pax_global_header00006660000000000000000000000064144313726120014515gustar00rootroot0000000000000052 comment=3e31aa1d9039a2689241aebd18c45933b2d0f5e3 biosoup-0.11.0/000077500000000000000000000000001443137261200132545ustar00rootroot00000000000000biosoup-0.11.0/.github/000077500000000000000000000000001443137261200146145ustar00rootroot00000000000000biosoup-0.11.0/.github/workflows/000077500000000000000000000000001443137261200166515ustar00rootroot00000000000000biosoup-0.11.0/.github/workflows/biosoup.yml000066400000000000000000000031251443137261200210550ustar00rootroot00000000000000name: biosoup CI on: push: pull_request: branches: - master env: BUILD_TYPE: Release jobs: test: strategy: matrix: compiler: - g++-7 - g++ - clang++-6.0 - clang++ runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - if: ${{ contains(matrix.compiler, '-') }} name: Get compiler version id: get-compiler-version run: | version=$(echo ${{ matrix.compiler }} | cut -d- -f2) echo "version=$version" >> $GITHUB_OUTPUT - if: ${{ startsWith(matrix.compiler, 'g++-') }} name: Setup GCC uses: egor-tensin/setup-gcc@v1 with: version: "${{ steps.get-compiler-version.outputs.version }}" platform: x64 - if: ${{ startsWith(matrix.compiler, 'clang++-') }} name: Setup Clang uses: egor-tensin/setup-clang@v1 with: version: "${{ steps.get-compiler-version.outputs.version }}" platform: x64 - name: Configure CMake run: | cmake -B ${{ github.workspace }}/build_cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} cmake --build ${{ github.workspace }}/build_cmake env: CXX: ${{ matrix.compiler }} - name: Configure Meson uses: BSFishy/meson-build@v1.0.3 with: action: build directory: build_meson meson-version: 0.60.0 - name: Test working-directory: ${{ github.workspace }} run: | build_cmake/bin/biosoup_test build_meson/test/biosoup_test biosoup-0.11.0/.gitignore000066400000000000000000000001031443137261200152360ustar00rootroot00000000000000# Compiled Object files build /subprojects/* !/subprojects/*.wrap biosoup-0.11.0/.gitmodules000066400000000000000000000000011443137261200154200ustar00rootroot00000000000000 biosoup-0.11.0/CMakeLists.txt000066400000000000000000000054121443137261200160160ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.11) project(biosoup VERSION 0.11.0 LANGUAGES CXX DESCRIPTION "Biosoup is a c++ collection of header only data structures used for storage and logging in bioinformatics tools.") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) set(biosoup_main_project ON) endif () option(biosoup_install "Generate install target" ${biosoup_main_project}) option(biosoup_build_tests "Build unit tests" ${biosoup_main_project}) if (biosoup_build_tests) find_package(GTest 1.10.0 QUIET) if (NOT GTest_FOUND) include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest GIT_TAG release-1.10.0) FetchContent_GetProperties(googletest) if (NOT googletest_POPULATED) FetchContent_Populate(googletest) add_subdirectory( ${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) add_library(GTest::Main ALIAS gtest_main) endif () endif () endif () add_library(biosoup INTERFACE) add_library(${PROJECT_NAME}::biosoup ALIAS biosoup) target_include_directories(biosoup INTERFACE $ $) if (biosoup_install) include(GNUInstallDirs) include(CMakePackageConfigHelpers) configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake COMPATIBILITY SameMinorVersion) install( TARGETS biosoup EXPORT ${PROJECT_NAME}Targets) install( DIRECTORY include/biosoup DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install( EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME}:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) endif () if (biosoup_build_tests) add_executable(biosoup_test test/nucleic_acid_test.cpp test/overlap_test.cpp test/progress_bar_test.cpp test/sequence_test.cpp test/timer_test.cpp) target_link_libraries(biosoup_test biosoup GTest::Main) endif () biosoup-0.11.0/Config.cmake.in000066400000000000000000000001211443137261200160620ustar00rootroot00000000000000@PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") biosoup-0.11.0/LICENSE000066400000000000000000000020551443137261200142630ustar00rootroot00000000000000MIT License Copyright (c) 2020 Robert Vaser Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. biosoup-0.11.0/README.md000066400000000000000000000016321443137261200145350ustar00rootroot00000000000000# Biosoup ![Build status for gcc/clang](https://github.com/rvaser/biosoup/actions/workflows/biosoup.yml/badge.svg) Biosoup is a c++ collection of header only data structures used for storage and logging in bioinformatics tools. ## Build ### Dependencies - gcc 4.8+ | clang 3.5+ #### Hidden - (biosoup_test) google/googletest 1.10.0 ### CMake (3.11+) ```bash git clone https://github.com/rvaser/biosoup && cd biosoup cmake -B build -DCMAKE_BUILD_TYPE=Release make -C build ``` #### Options - `biosoup_install`: generate install target - `biosoup_build_tests`: build unit tests ### Meson (0.60.0+) ```bash git clone https://github.com/rvaser/biosoup && cd biosoup meson setup build ninja -C build ``` #### Options - `tests`: build unit tests ## Acknowledgement This work has been supported in part by the Croatian Science Foundation under the project Single genome and metagenome assembly (IP-2018-01-5886). biosoup-0.11.0/include/000077500000000000000000000000001443137261200146775ustar00rootroot00000000000000biosoup-0.11.0/include/biosoup/000077500000000000000000000000001443137261200163575ustar00rootroot00000000000000biosoup-0.11.0/include/biosoup/nucleic_acid.hpp000066400000000000000000000113631443137261200214760ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #ifndef BIOSOUP_NUCLEIC_ACID_HPP_ #define BIOSOUP_NUCLEIC_ACID_HPP_ #include #include #include #include #include #include #include namespace biosoup { constexpr static std::uint8_t kNucleotideCoder[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1 , 1, 0, 255, 255, 2, 3, 255, 255, 2, 255, 1, 0, 255, 255, 255, 0, 1, 3, 3, 2, 0, 255, 3, 255, 255, 255, 255, 255, 255, 255, 0, 1, 1, 0, 255, 255, 2, 3, 255, 255, 2, 255, 1, 0, 255, 255, 255, 0, 1, 3, 3, 2, 0, 255, 3, 255, 255, 255, 255, 255, 255 }; constexpr static char kNucleotideDecoder[] = { 'A', 'C', 'G', 'T' }; class NucleicAcid { public: NucleicAcid() = default; NucleicAcid( const std::string& name, const std::string& data) : NucleicAcid( name.c_str(), name.size(), data.c_str(), data.size()) {} NucleicAcid( const char* name, std::uint32_t name_len, const char* data, std::uint32_t data_len) : id(num_objects++), name(name, name_len), deflated_data(), block_quality(), inflated_len(data_len), is_reverse_complement(0) { deflated_data.reserve(data_len / 32. + .999); std::uint64_t block = 0; for (std::uint32_t i = 0; i < data_len; ++i) { std::uint64_t c = kNucleotideCoder[static_cast(data[i])]; if (c == 255ULL) { throw std::invalid_argument( "[biosoup::NucleicAcid::NucleicAcid] error: not a nucleotide"); } block |= c << ((i << 1) & 63); if (((i + 1) & 31) == 0 || i == data_len - 1) { deflated_data.emplace_back(block); block = 0; } } } NucleicAcid( const std::string& name, const std::string& data, const std::string& quality) : NucleicAcid( name.c_str(), name.size(), data.c_str(), data.size(), quality.c_str(), quality.size()) {} NucleicAcid( const char* name, std::uint32_t name_len, const char* data, std::uint32_t data_len, const char* quality, std::uint32_t quality_len) : NucleicAcid( name, name_len, data, data_len) { block_quality.reserve(quality_len / 64. + .999); for (std::uint32_t i = 0; i < quality_len; i += 64) { std::uint32_t j = std::min(i + 64, quality_len); auto block = std::accumulate( quality + i, quality + j, 0, [] (const std::uint32_t& sum, const char& q) -> std::uint32_t { return sum + (q - '!'); }); block_quality.emplace_back(block / (j - i)); } } NucleicAcid(const NucleicAcid&) = default; NucleicAcid& operator=(const NucleicAcid&) = default; NucleicAcid(NucleicAcid&&) = default; NucleicAcid& operator=(NucleicAcid&&) = default; ~NucleicAcid() = default; std::uint64_t Code(std::uint32_t i) const { std::uint64_t x = 0; if (is_reverse_complement) { i = inflated_len - i - 1; x = 3; } return ((deflated_data[i >> 5] >> ((i << 1) & 63)) & 3) ^ x; } std::uint8_t Score(std::uint32_t i) const { if (is_reverse_complement) { i = inflated_len - i - 1; } return block_quality[i >> 6]; } std::string InflateData(std::uint32_t i = 0, std::uint32_t len = -1) const { if (i >= inflated_len) { return std::string{}; } len = std::min(len, inflated_len - i); std::string dst{}; dst.reserve(len); for (; len; ++i, --len) { dst += kNucleotideDecoder[Code(i)]; } return dst; } std::string InflateQuality(std::uint32_t i = 0, std::uint32_t len = -1) const { // NOLINT if (block_quality.empty() || i >= inflated_len) { return std::string{}; } len = std::min(len, inflated_len - i); std::string dst{}; dst.reserve(len); for (; len; ++i, --len) { dst += Score(i) + '!'; } return dst; } void ReverseAndComplement() { // Watson-Crick base pairing is_reverse_complement ^= 1; } static std::atomic num_objects; std::uint32_t id; // (optional) initialize num_objects to 0 std::string name; std::vector deflated_data; std::vector block_quality; // (optional) Phred quality scores std::uint32_t inflated_len; bool is_reverse_complement; }; } // namespace biosoup #endif // BIOSOUP_NUCLEIC_ACID_HPP_ biosoup-0.11.0/include/biosoup/overlap.hpp000066400000000000000000000042051443137261200205410ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #ifndef BIOSOUP_OVERLAP_HPP_ #define BIOSOUP_OVERLAP_HPP_ #include #include namespace biosoup { struct Overlap { public: Overlap() = default; Overlap( std::uint32_t lhs_id, std::uint32_t lhs_begin, std::uint32_t lhs_end, std::uint32_t rhs_id, std::uint32_t rhs_begin, std::uint32_t rhs_end, std::uint32_t score, bool strand = true) : lhs_id(lhs_id), lhs_begin(lhs_begin), lhs_end(lhs_end), rhs_id(rhs_id), rhs_begin(rhs_begin), rhs_end(rhs_end), score(score), strand(strand), alignment() {} Overlap( std::uint32_t lhs_id, std::uint32_t lhs_begin, std::uint32_t lhs_end, std::uint32_t rhs_id, std::uint32_t rhs_begin, std::uint32_t rhs_end, std::uint32_t score, const std::string& alignment, bool strand = true) : Overlap( lhs_id, lhs_begin, lhs_end, rhs_id, rhs_begin, rhs_end, score, alignment.c_str(), alignment.size(), strand) {} Overlap( std::uint32_t lhs_id, std::uint32_t lhs_begin, std::uint32_t lhs_end, std::uint32_t rhs_id, std::uint32_t rhs_begin, std::uint32_t rhs_end, std::uint32_t score, const char* alignment, std::uint32_t alignment_len, bool strand = true) : lhs_id(lhs_id), lhs_begin(lhs_begin), lhs_end(lhs_end), rhs_id(rhs_id), rhs_begin(rhs_begin), rhs_end(rhs_end), score(score), strand(strand), alignment(alignment, alignment_len) {} Overlap(const Overlap&) = default; Overlap& operator=(const Overlap&) = default; Overlap(Overlap&&) = default; Overlap& operator=(Overlap&&) = default; ~Overlap() = default; std::uint32_t lhs_id; std::uint32_t lhs_begin; std::uint32_t lhs_end; std::uint32_t rhs_id; std::uint32_t rhs_begin; std::uint32_t rhs_end; std::uint32_t score; // based on k-mer matches or alignment score bool strand; // (optional) Watson-Crick strand std::string alignment; // (optional) cigar string }; } // namespace biosoup #endif // BIOSOUP_OVERLAP_HPP_ biosoup-0.11.0/include/biosoup/progress_bar.hpp000066400000000000000000000034131443137261200215610ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #ifndef BIOSOUP_PROGRESS_BAR_HPP_ #define BIOSOUP_PROGRESS_BAR_HPP_ #include #include #include #include namespace biosoup { class ProgressBar { public: // num_ticks element of [1, num_events] ProgressBar(std::uint32_t num_events, std::uint32_t num_ticks) : bar_(std::max(std::min(num_ticks, num_events), 1U), ' '), bar_ptr_(0), num_events_(num_events), event_counter_(0), events_per_tick_(num_events / static_cast(bar_.size())) {} ProgressBar(const ProgressBar&) = default; ProgressBar& operator=(const ProgressBar&) = default; ProgressBar(ProgressBar&&) = default; ProgressBar& operator=(ProgressBar&&) = default; ~ProgressBar() = default; std::uint32_t event_counter() const { return event_counter_; } std::uint32_t num_events() const { return num_events_; } bool operator++() { // true if a tick is added ++event_counter_; if (event_counter_ > num_events_) { return false; } else if (event_counter_ == num_events_) { while (bar_ptr_ < bar_.size()) { bar_[bar_ptr_++] = '='; } return true; } else if (event_counter_ >= (bar_ptr_ + 1) * events_per_tick_) { bar_[bar_ptr_++] = '='; if (bar_ptr_ < bar_.size()) { bar_[bar_ptr_] = '>'; } return true; } return false; } // to decrease amount of output, use when ++ returns true friend std::ostream& operator<<(std::ostream& os, const ProgressBar& pb) { return os << pb.bar_; } private: std::string bar_; std::uint32_t bar_ptr_; std::uint32_t num_events_; std::uint32_t event_counter_; double events_per_tick_; }; } // namespace biosoup #endif // BIOSOUP_PROGRESS_BAR_HPP_ biosoup-0.11.0/include/biosoup/sequence.hpp000066400000000000000000000047631443137261200207120ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #ifndef BIOSOUP_SEQUENCE_HPP_ #define BIOSOUP_SEQUENCE_HPP_ #include #include #include #include #include namespace biosoup { struct Sequence { public: Sequence() = default; Sequence(const std::string& name, const std::string& data) : Sequence(name.c_str(), name.size(), data.c_str(), data.size()) {} Sequence( const char* name, std::uint32_t name_len, const char* data, std::uint32_t data_len) : id(num_objects++), name(name, name_len), data(data, data_len), quality() {} Sequence( const std::string& name, const std::string& data, const std::string& quality) : Sequence( name.c_str(), name.size(), data.c_str(), data.size(), quality.c_str(), quality.size()) {} Sequence( const char* name, std::uint32_t name_len, const char* data, std::uint32_t data_len, const char* quality, std::uint32_t quality_len) : id(num_objects++), name(name, name_len), data(data, data_len), quality(quality, quality_len) {} Sequence(const Sequence&) = default; Sequence& operator=(const Sequence&) = default; Sequence(Sequence&&) = default; Sequence& operator=(Sequence&&) = default; ~Sequence() = default; void ReverseAndComplement() { // (optional) Watson-Crick base pairing for (auto& it : data) { switch (static_cast(std::toupper(static_cast(it)))) { case 'A': it = 'T'; break; case 'C': it = 'G'; break; case 'G': it = 'C'; break; case 'T': case 'U': it = 'A'; break; case 'R': it = 'Y'; break; // A || G case 'Y': it = 'R'; break; // C || T (U) case 'K': it = 'M'; break; // G || T (U) case 'M': it = 'K'; break; // A || C case 'S': break; // C || G case 'W': break; // A || T (U) case 'B': it = 'V'; break; // !A case 'D': it = 'H'; break; // !C case 'H': it = 'D'; break; // !G case 'V': it = 'B'; break; // !T (!U) default: break; // N || - } } std::reverse(data.begin(), data.end()); std::reverse(quality.begin(), quality.end()); } static std::atomic num_objects; std::uint32_t id; // (optional) initialize num_objects to 0 std::string name; std::string data; std::string quality; // (optional) Phred quality scores }; } // namespace biosoup #endif // BIOSOUP_SEQUENCE_HPP_ biosoup-0.11.0/include/biosoup/timer.hpp000066400000000000000000000025421443137261200202130ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #ifndef BIOSOUP_TIMER_HPP_ #define BIOSOUP_TIMER_HPP_ #include // NOLINT #include namespace biosoup { class Timer { public: Timer() : checkpoint_(), elapsed_time_(0) {} Timer(const Timer&) = default; Timer& operator=(const Timer&) = default; Timer(Timer&&) = default; Timer& operator=(Timer&&) = default; ~Timer() = default; double elapsed_time(void) const { return elapsed_time_; } void Start() { checkpoint_ = std::chrono::steady_clock::now(); } double Stop() { if (checkpoint_.time_since_epoch().count()) { // Start() was called auto duration = std::chrono::duration_cast>( std::chrono::steady_clock::now() - checkpoint_).count(); checkpoint_ = {}; elapsed_time_ += duration; return duration; } return 0; } double Lap() const { if (checkpoint_.time_since_epoch().count()) { // Start() was called return std::chrono::duration_cast>( std::chrono::steady_clock::now() - checkpoint_).count(); } return 0; } void Reset() { checkpoint_ = {}; elapsed_time_ = 0; } private: std::chrono::time_point checkpoint_; double elapsed_time_; }; } // namespace biosoup #endif // BIOSOUP_TIMER_HPP_ biosoup-0.11.0/include/meson.build000066400000000000000000000005261443137261200170440ustar00rootroot00000000000000########### # Headers # ########### biosoup_include_directories = include_directories(['.']) if meson.is_subproject() subdir_done() endif install_headers( files([ 'biosoup/nucleic_acid.hpp', 'biosoup/overlap.hpp', 'biosoup/progress_bar.hpp', 'biosoup/sequence.hpp', 'biosoup/timer.hpp', ]), subdir : 'biosoup') biosoup-0.11.0/meson.build000066400000000000000000000017051443137261200154210ustar00rootroot00000000000000project( 'biosoup', ['cpp'], version : '0.11.0', default_options : [ 'buildtype=release', 'warning_level=3', 'cpp_std=c++11', 'b_ndebug=if-release'], license : 'MIT', meson_version : '>=0.60.0' ) ########### # Headers # ########### subdir('include') ######### # Tests # ######### if (not meson.is_subproject()) and get_option('tests') biosoup_gtest_dep = dependency('gtest', version : '>= 1.10.0', main : true, fallback : ['gtest', 'gtest_main_dep']) subdir('test') endif ################### # Dependency info # ################### if (not meson.is_subproject()) import('pkgconfig').generate( name : 'biosoup', version : meson.project_version(), filebase : 'biosoup', description : 'C++ collection of header only bioinformatics data structures used for storage and logging.') endif biosoup_dep = declare_dependency( include_directories : biosoup_include_directories, version : meson.project_version() ) biosoup-0.11.0/meson_options.txt000066400000000000000000000002171443137261200167110ustar00rootroot00000000000000######### # Tests # ######### option('tests', type : 'boolean', value : true, description : 'Enable dependencies required for testing') biosoup-0.11.0/subprojects/000077500000000000000000000000001443137261200156175ustar00rootroot00000000000000biosoup-0.11.0/subprojects/gtest.wrap000066400000000000000000000010041443137261200176330ustar00rootroot00000000000000[wrap-file] directory = googletest-release-1.10.0 source_url = https://github.com/google/googletest/archive/release-1.10.0.zip source_filename = gtest-1.10.0.zip source_hash = 94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91 patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.10.0-1/get_patch patch_filename = gtest-1.10.0-1-wrap.zip patch_hash = 04ff14e8880e4e465f6260221e9dfd56fea6bc7cce4c4aff0dc528e4a2c8f514 wrapdb_version = 1.10.0-1 [provide] gtest = gtest_dep gtest_main = gtest_main_dep biosoup-0.11.0/test/000077500000000000000000000000001443137261200142335ustar00rootroot00000000000000biosoup-0.11.0/test/meson.build000066400000000000000000000006771443137261200164070ustar00rootroot00000000000000########### # Sources # ########### biosoup_test_sources = files([ 'nucleic_acid_test.cpp', 'overlap_test.cpp', 'progress_bar_test.cpp', 'sequence_test.cpp', 'timer_test.cpp', ]) biosoup_test = executable( 'biosoup_test', biosoup_test_sources, dependencies : biosoup_gtest_dep, include_directories : biosoup_include_directories, install : false) ######### # Tests # ######### test('biosoup gtest unit tests', biosoup_test) biosoup-0.11.0/test/nucleic_acid_test.cpp000066400000000000000000000054311443137261200204030ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #include "biosoup/nucleic_acid.hpp" #include #include "gtest/gtest.h" std::atomic biosoup::NucleicAcid::num_objects{0}; namespace biosoup { namespace test { TEST(BiosoupNucleicAcidTest, NucleotideError) { try { NucleicAcid s{"test", "EFIJLOPQUXZ"}; } catch (std::invalid_argument& exception) { EXPECT_STREQ( exception.what(), "[biosoup::NucleicAcid::NucleicAcid] error: not a nucleotide"); } } TEST(BiosoupNucleicAcidTest, Inflate) { NucleicAcid s{"test", "AaAaCcCcGgGgTtTt------ACGTRYKMSWBDHVN-nvhdbwsmkyrtgca------tTtTgGgGcCcCaAaA"}; // NOLINT EXPECT_EQ(s.deflated_data.size(), s.deflated_data.capacity()); EXPECT_EQ(0, s.Code(16)); EXPECT_EQ(1, s.Code(23)); EXPECT_EQ(2, s.Code(35)); EXPECT_EQ(3, s.Code(59)); EXPECT_EQ("AAAACCCCGGGGTTTTAAAAAAACGTATGCCACATGAAAGTACACCGTATGCAAAAAAATTTTGGGGCCCCAAAA", s.InflateData()); // NOLINT EXPECT_EQ("TATGCCACATGAAAGTACACCGTAT", s.InflateData(25, 25)); EXPECT_EQ("TGAAAGT", s.InflateData(34, 7)); EXPECT_EQ("", s.InflateData(75, 42)); EXPECT_EQ("C", s.InflateData(29, 1)); EXPECT_EQ("G", s.InflateData(64, 1)); EXPECT_EQ("CCAAAA", s.InflateData(69)); } TEST(BiosoupNucleicAcidTest, Quality) { NucleicAcid s{ "test", "ACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTAC", // NOLINT "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}; // NOLINT EXPECT_EQ(s.block_quality.size(), s.block_quality.capacity()); EXPECT_EQ(31, s.Score(42)); EXPECT_EQ(78, s.Score(84)); EXPECT_EQ("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@oooooooooooooooooooooooooooooo", s.InflateQuality()); // NOLINT EXPECT_EQ("@@@@@@@@@@@@@@@@", s.InflateQuality(0, 16)); EXPECT_EQ("@@oo", s.InflateQuality(62, 4)); EXPECT_EQ("@", s.InflateQuality(63, 1)); EXPECT_EQ("o", s.InflateQuality(64, 1)); EXPECT_EQ("o", s.InflateQuality(93)); EXPECT_EQ("ooo", s.InflateQuality(91, 20)); EXPECT_EQ("", s.InflateQuality(95)); } TEST(BiosoupNucleicAcidTest, ReverseAndComplement) { NucleicAcid s{ "test", "ACGTACTGAGCTAGTCATCGATGCCAGTCATGCGATCGTACTAGCTGAGACTGATCGCATGCTAGTACGTCA", // NOLINT "0123456789012345678901234567890123456789012345678901234567890123ZZZZZZZZ"}; // NOLINT NucleicAcid c{s}; c.ReverseAndComplement(); EXPECT_EQ("TGACGTACTAGCATGCGATCAGTCTCAGCTAGTACGATCGCATGACTGGCATCGATGACTAGCTCAGTACGT", c.InflateData()); // NOLINT EXPECT_EQ("ZZZZZZZZ4444444444444444444444444444444444444444444444444444444444444444", c.InflateQuality()); // NOLINT c.ReverseAndComplement(); EXPECT_EQ(c.InflateData(), s.InflateData()); EXPECT_EQ(c.InflateQuality(), s.InflateQuality()); } } // namespace test } // namespace biosoup biosoup-0.11.0/test/overlap_test.cpp000066400000000000000000000004011443137261200174410ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #include "biosoup/overlap.hpp" #include "gtest/gtest.h" namespace biosoup { namespace test { TEST(BiosoupOverlapTest, Compile) { Overlap o{0, 10, 20, 1, 0, 10, 10, 0}; } } // namespace test } // namespace biosoup biosoup-0.11.0/test/progress_bar_test.cpp000066400000000000000000000076231443137261200204760ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #include "biosoup/progress_bar.hpp" #include "gtest/gtest.h" namespace biosoup { namespace test { TEST(BiosoupProgressBarTest, Operator) { ProgressBar pb{8, 8}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("==> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("===> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("====> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=====> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("======> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=======>", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("========", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("========", ::testing::PrintToString(pb)); pb = {8, 9}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); pb = {8, 7}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("==> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("===> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("====> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=====> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("======>", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=======", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=======", ::testing::PrintToString(pb)); pb = {8, 4}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=> ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("==> ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("==> ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("===>", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("===>", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("====", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("====", ::testing::PrintToString(pb)); pb = {8, 2}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=>", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=>", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=>", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=>", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("==", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("==", ::testing::PrintToString(pb)); pb = {8, 1}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ(" ", ::testing::PrintToString(pb)); EXPECT_TRUE(++pb); EXPECT_EQ("=", ::testing::PrintToString(pb)); EXPECT_FALSE(++pb); EXPECT_EQ("=", ::testing::PrintToString(pb)); pb = {8, 0}; EXPECT_EQ(" ", ::testing::PrintToString(pb)); } } // namespace test } // namespace biosoup biosoup-0.11.0/test/sequence_test.cpp000066400000000000000000000007531443137261200176130ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #include "biosoup/sequence.hpp" #include "gtest/gtest.h" std::atomic biosoup::Sequence::num_objects{0}; namespace biosoup { namespace test { TEST(BiosoupSequenceTest, ReverseAndComplement) { Sequence s{"Test", "ACGTURYKMSWBDHVN", "0123456789:;<=>?"}; s.ReverseAndComplement(); EXPECT_EQ(0, s.id); EXPECT_EQ("NBDHVWSKMRYAACGT", s.data); EXPECT_EQ("?>=<;:9876543210", s.quality); } } // namespace test } // namespace biosoup biosoup-0.11.0/test/timer_test.cpp000066400000000000000000000041611443137261200171200ustar00rootroot00000000000000// Copyright (c) 2020 Robert Vaser #include "biosoup/timer.hpp" #include // NOLINT #include "gtest/gtest.h" namespace biosoup { namespace test { bool ExpectWithinInclusive(double lower, double upper, double value) { return lower <= value && value <= upper; } TEST(BiosoupTimerTest, Start) { Timer t{}; t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.Stop())); t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); t.Start(); EXPECT_TRUE(ExpectWithinInclusive(0, 0.001, t.Stop())); } TEST(BiosoupTimerTest, Stop) { Timer t{}; EXPECT_TRUE(ExpectWithinInclusive(0, 0.001, t.Stop())); EXPECT_EQ(0, t.elapsed_time()); t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); t.Stop(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.elapsed_time())); EXPECT_TRUE(ExpectWithinInclusive(0, 0.001, t.Stop())); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.elapsed_time())); t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.Stop())); EXPECT_TRUE(ExpectWithinInclusive(0.512, 0.768, t.elapsed_time())); } TEST(BiosoupTimerTest, Lap) { Timer t{}; t.Start(); EXPECT_TRUE(ExpectWithinInclusive(0, 0.001, t.Lap())); std::this_thread::sleep_for(std::chrono::milliseconds(256)); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.Lap())); EXPECT_EQ(0, t.elapsed_time()); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.Stop())); EXPECT_TRUE(ExpectWithinInclusive(0, 0.001, t.Lap())); } TEST(BiosoupTimerTest, Reset) { Timer t{}; t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); t.Reset(); t.Stop(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); t.Start(); std::this_thread::sleep_for(std::chrono::milliseconds(256)); t.Stop(); EXPECT_TRUE(ExpectWithinInclusive(0.256, 0.384, t.elapsed_time())); t.Reset(); EXPECT_EQ(0, t.elapsed_time()); } } // namespace test } // namespace biosoup