Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push, pull_request]

jobs:
check-build:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
container:
image: traviswheelerlab/ultra-build
volumes:
Expand All @@ -14,17 +14,17 @@ jobs:
- run: cmake . && make

check-examples:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
container:
image: traviswheelerlab/ultra-build
volumes:
- ${{ github.workspace }}:/code
steps:
- uses: actions/checkout@v3
- run: cmake . && make examples

check-format:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
container:
image: traviswheelerlab/ultra-build
volumes:
Expand Down
63 changes: 44 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ project(
HOMEPAGE_URL https://github.com/TravisWheelerLab/ULTRA
)

# By default we do NOT build the standalone ULTRA library
option(BUILD_ULTRA_LIB "Also build ULTRA as a standalone library" OFF)

# Default to Release if no build type is set
if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
message(STATUS "Setting CMAKE_BUILD_TYPE=Release")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()

if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
# Add a debug flag when not in Release
if (NOT CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(-DDEBUG_PRAGMA=1)
endif()

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(
LIB_CPP_FILES
)
set(
HPP_FILES

# Header files (for installation / PUBLIC_HEADER)
set(HPP_FILES
src/FASTAReader.hpp
src/FileReader.hpp
src/SequenceWindow.hpp
Expand All @@ -39,10 +39,10 @@ set(
src/RepeatSplitter.hpp
src/cli.hpp
src/mask.hpp
)
set(
CPP_FILES
)

# All source files
set(CPP_FILES
src/FASTAReader.cpp
src/FileReader.cpp
src/SequenceWindow.cpp
Expand All @@ -63,21 +63,46 @@ set(

find_package(Threads REQUIRED)

add_executable(
ultra
# LIB_SOURCES = everything except main.cpp
set(LIB_SOURCES ${CPP_FILES})
list(REMOVE_ITEM LIB_SOURCES src/main.cpp)

${LIB_CPP_FILES}
${CPP_FILES}
)
target_link_libraries(ultra PRIVATE Threads::Threads)
# 1) Build static library only if requested
if (BUILD_ULTRA_LIB)
add_library(ultra_core STATIC ${LIB_SOURCES})
target_include_directories(ultra_core
PUBLIC ${CMAKE_SOURCE_DIR}/src
)
target_link_libraries(ultra_core
PUBLIC Threads::Threads
)

install(
TARGETS ultra_core
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include
)
endif()

# 2) Build the CLI executable
if (BUILD_ULTRA_LIB)
# Link only main.cpp against ultra_core
add_executable(ultra src/main.cpp)
target_link_libraries(ultra PRIVATE ultra_core)
else()
# Monolithic: compile everything into the exe
add_executable(ultra ${CPP_FILES})
target_link_libraries(ultra PRIVATE Threads::Threads)
endif()

target_include_directories(ultra SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/lib)
target_include_directories(ultra PRIVATE ${CMAKE_SOURCE_DIR}/src)

install(TARGETS ultra RUNTIME)
install(TARGETS ultra RUNTIME DESTINATION bin)

# Optional examples target
add_custom_target(
examples
COMMAND examples/run-all.sh
COMMAND /usr/bin/env sh examples/run-all.sh
VERBATIM
)
add_dependencies(examples ultra)
33 changes: 33 additions & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# examples/Makefile — build the ULTRA example program

# C++ compiler and flags
CXX := g++
CXXFLAGS := -std=c++11 -Wall -I../src

# Path to the ULTRA static library
ULTRA_LIB := ../build/libultra_core.a

# Libraries to link against
LDLIBS := $(ULTRA_LIB) -pthread

# Your example source & target
SRC := library_example.cpp
OBJ := $(SRC:.cpp=.o)
TARGET := library_example

# Default target: build the example executable
all: $(TARGET)

# Link step
$(TARGET): $(OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDLIBS)

# Compile step
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@

# Clean up build artifacts
clean:
rm -f $(OBJ) $(TARGET)

.PHONY: all clean
70 changes: 70 additions & 0 deletions examples/library_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// Created by Daniel Olson on 5/5/25.
//
#include <cstdio>
#include <ultra.hpp>
#include <cli.hpp>

int main() {
printf("Note that the Makefile is currently linking against ULTRA/build/libultra_core.a\n");
printf(" and is using ULTRA/src/ as the source of ULTRA header files.\n");
printf("The location of the ULTRA lib and header files will need to be adjusted in real use-cases.\n\n\n");

printf("Starting test of library.\n");


// These are the settings we will use with ULTRA
Settings *settings = new Settings();
settings->run_without_reader = true; // This must be set to true when using as lib
settings->window_size = 1000000; // window size should be equal to the largest sequence you will analyze
settings->overlap = 0; // overlap should be turned off


// We can also pass in an argument string to settings like so:
int argc;
char **argv;
std::string arg_string = "-p 25 -i 3 -d 3";
string_to_args(arg_string, argc, argv);

settings->prepare_settings(); // This should be called before running settings->parse_input()
if (!settings->parse_input(argc, (const char**)argv)) {
exit(0);
}

// Finally, we call settings->assign_settings()
settings->assign_settings();

// We create a reusable ULTRA object
auto ultra = new Ultra(settings);
// We can find repeats in a C++ string using "FindRepeatsInString(std::string)"

printf("Finding repeats in string ``aaaaaaaaaaaaaaaaaaaaaaaaaa''\n");
auto repeats = ultra->FindRepeatsInString("aaaaaaaaaaaaaaaaaaaaaaaaaa");

printf("Start Length Pattern\n");
for (int i= 0; i < repeats->size(); ++i) {
auto r = repeats->at(i);
printf("%lu %lu %i %s\n", r->windowStart, r->repeatLength, r->repeatPeriod, r->GetConsensus().c_str());
delete r; // We are in charge of the memory management of the repeats returned by FindRepeatsInString
}

delete repeats; // We are also in charge of the memory for the repeat array itself
printf("---------\n");


printf("Finding repeats in string ``aggtaaggtaaggtaaggtaaggtaagcggtataacatacagatctgactactactactactactactactactac''\n");
repeats = ultra->FindRepeatsInString("aggtaaggtaaggtaaggtaaggtaagcggtataacatacagatctgactactactactactactactactactac");
printf("Start Length Pattern\n");
for (int i= 0; i < repeats->size(); ++i) {
auto r = repeats->at(i);
printf("%lu %lu %i %s\n", r->windowStart, r->repeatLength, r->repeatPeriod, r->GetConsensus().c_str());
delete r;
}

delete repeats;
printf("---------\n");

printf("All positions reported are 0 indexed.\n");

return 0;
}
1 change: 1 addition & 0 deletions examples/run-all.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ run_one() {

run_one examples/example_1.fa
run_one examples/example_2.fa
run_one examples/example_3.fa
6 changes: 0 additions & 6 deletions lib/README.md

This file was deleted.

8 changes: 6 additions & 2 deletions src/BEDFileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
#include "ultra.hpp"
#include <algorithm>
#include <iostream>
void BEDFileWriter::InitializeWriter(Ultra *ultra, FILE *out_file) { owner = ultra; out=out_file; }
void BEDFileWriter::InitializeWriter(Ultra *ultra, FILE *out_file) {
owner = ultra;
out = out_file;
}

void BEDFileWriter::WriteRepeat(RepeatRegion *repeat) {

Expand Down Expand Up @@ -35,7 +38,8 @@ void BEDFileWriter::WriteRepeat(RepeatRegion *repeat) {
// We need to decide what to do with the overall sequence

std::string rep_con = std::to_string(repeat->repeatPeriod);
if (owner->settings->max_consensus_period >= repeat->repeatPeriod && !repeat->string_consensus.empty())
if (owner->settings->max_consensus_period >= repeat->repeatPeriod &&
!repeat->string_consensus.empty())
rep_con = repeat->string_consensus;

fprintf(out, "\t%s\n", rep_con.c_str());
Expand Down
File renamed without changes.
2 changes: 0 additions & 2 deletions src/FASTAReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ bool FASTAReader::ReadWindow(SequenceWindow *window) {
window->PrepareWindow(sequenceName, sequenceID, symbolsReadInSeq,
overlapLength);


if (overlapLength > 0)
window->CopyOverlap(overlapBuffer);

Expand Down Expand Up @@ -188,7 +187,6 @@ bool FASTAReader::ReadWindow(SequenceWindow *window) {

window->readID = readID++;


return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/FASTAReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ class FASTAReader {
double C_pctg;
double G_pctg;

symbol *overlapBuffer; // = NULL;
unsigned long overlapLength = 0; // = 0;
symbol *overlapBuffer; // = NULL;
unsigned long overlapLength = 0; // = 0;

std::string sequenceName = ""; // = "";
std::string sequenceName = ""; // = "";
unsigned long sequenceID = 0; // = 0;
unsigned long readID = 0; // = 0; // read id's may not be contiguous
unsigned long symbolsReadInSeq = 0; // = 0;

bool doneReadingFile; // = false;
bool doneReadingFile; // = false;
bool isReading;

bool CopyOverlapBufferFromWindow(SequenceWindow *window,
Expand Down
1 change: 0 additions & 1 deletion src/FileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ FileReader::~FileReader() {
delete fastaReader;
fastaReader = nullptr;
}

}

SequenceWindow *FileReader::GetReadyWindow() {
Expand Down
1 change: 0 additions & 1 deletion src/FileReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class FileReader {
unsigned long maxSeqLength;
unsigned long maxOverlapLength;


bool multithread = true;
file_type format = UNKNOWN;

Expand Down
8 changes: 4 additions & 4 deletions src/JSONFileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ void JSONFileWriter::WriteRepeat(RepeatRegion *repeat) {

++this->repeatsOutput;

fprintf(out, "{\"SequenceName\": \"%s\"",
repeat->sequenceName.c_str());
fprintf(out, "{\"SequenceName\": \"%s\"", repeat->sequenceName.c_str());

this->OutputJSONKeyValue("Start", std::to_string(repeat->sequenceStart));
this->OutputJSONKeyValue("Length", std::to_string(repeat->repeatLength));
Expand All @@ -91,9 +90,10 @@ void JSONFileWriter::WriteRepeat(RepeatRegion *repeat) {
this->OutputJSONKeyValue("PVal", std::to_string(pval));
}


if (owner->settings->show_counts) {
auto copies = (repeat->repeatLength - repeat->insertions + repeat->deletions) / repeat->repeatPeriod;
auto copies =
(repeat->repeatLength - repeat->insertions + repeat->deletions) /
repeat->repeatPeriod;
this->OutputJSONKeyValue("Copies", std::to_string(copies));
this->OutputJSONKeyValue("Substitutions",
std::to_string(repeat->mismatches));
Expand Down
1 change: 0 additions & 1 deletion src/RepeatSplitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,6 @@ void ValidateSplits(std::vector<std::string> *consensi,
join_threshold)) {
consensi->at(i) = consensi->at(i - 1);
splits->at(i - 1) = -1;

}
}
}
5 changes: 3 additions & 2 deletions src/SequenceWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ void SequenceWindow::PrepareWindow(std::string seqName, unsigned long sid,
}
}

long long SequenceWindow::ReadLine(std::string line, long long place, unsigned long long &total_seq_length) {
long long SequenceWindow::ReadLine(std::string line, long long place,
unsigned long long &total_seq_length) {
// printf ("(mem: %llx overlap:%llx newseq: %llx, length: %llu, place %llu)
// Reading line: %s\n", (unsigned long)seqMem, (unsigned long)overlapSeq,
// (unsigned long)newSeq, length, place, line.c_str());
Expand Down Expand Up @@ -156,7 +157,7 @@ bool CompareSequenceWindows::operator()(SequenceWindow *lhs,
}

void ShuffleSequenceWindow(SequenceWindow *window) {
std::random_device rd; // a seed source for the random number engine
std::random_device rd; // a seed source for the random number engine
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned long long> dist;
for (unsigned long long i = 0; i < window->length; ++i) {
Expand Down
3 changes: 2 additions & 1 deletion src/SequenceWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class SequenceWindow {

// ReadLine() returns how much of line was read
// and will returns -1 if the line is a new sequence
long long ReadLine(std::string line, long long place, unsigned long long &total_seq_length);
long long ReadLine(std::string line, long long place,
unsigned long long &total_seq_length);
void CopyOverlap(symbol *b);
void CalculateSymbolFrequencies();

Expand Down
Loading