pax_global_header00006660000000000000000000000064140067555640014526gustar00rootroot0000000000000052 comment=38181f09854ff42cbd9632200a2ec9fb37a4b7b6 biosoup-0.10.0/000077500000000000000000000000001400675556400132645ustar00rootroot00000000000000biosoup-0.10.0/.gitignore000066400000000000000000000000361400675556400152530ustar00rootroot00000000000000# Compiled Object files build biosoup-0.10.0/.gitmodules000066400000000000000000000000011400675556400154300ustar00rootroot00000000000000 biosoup-0.10.0/.travis.yml000066400000000000000000000016011400675556400153730ustar00rootroot00000000000000language: cpp matrix: include: - name: "GCC 4.8 (Linux)" # GCC 4.8.5 & CMake 3.12.4 os: linux dist: xenial addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.8 env: - SET_COMPILER="export CC=gcc-4.8 && export CXX=g++-4.8" - name: "Clang 3.5 (Linux)" # Clang 3.5.2 & CMake 3.12.4 os: linux dist: xenial addons: apt: packages: - clang-3.5 env: - SET_COMPILER="export CC=clang-3.5 && export CXX=clang++-3.5" - name: "Clang Xcode 9.4 (OSX)" # Clang 9.4.1 & CMake 3.15.5 os: osx osx_image: xcode9.4 before_install: - eval "${SET_COMPILER}" install: - mkdir build && cd build - cmake -DCMAKE_BUILD_TYPE=Release .. && make script: - ./bin/biosoup_test notifications: email: on_failure: always biosoup-0.10.0/CMakeLists.txt000066400000000000000000000054121400675556400160260ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.11) project(biosoup VERSION 0.10.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.10.0/Config.cmake.in000066400000000000000000000001211400675556400160720ustar00rootroot00000000000000@PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") biosoup-0.10.0/LICENSE000066400000000000000000000020551400675556400142730ustar00rootroot00000000000000MIT 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.10.0/README.md000066400000000000000000000026301400675556400145440ustar00rootroot00000000000000# Biosoup [![Build status for gcc/clang](https://travis-ci.com/rvaser/biosoup.svg?branch=master)](https://travis-ci.com/rvaser/biosoup) Biosoup is a c++ collection of header only data structures used for storage and logging in bioinformatics tools. ## Usage To build biosoup run the following commands: ```bash git clone https://github.com/rvaser/biosoup && cd biosoup && mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. && make ``` which will create install targets and unit tests. Running `make install` will create a package on your system that can be searched and linked with: ```cmake find_package(biosoup) target_link_libraries( biosoup::biosoup) ``` On the other hand, you can include biosoup as a submodule and add it to your project with the following: ```cmake if (NOT TARGET biosoup) add_subdirectory(/biosoup EXCLUDE_FROM_ALL) endif () target_link_libraries( biosoup::biosoup) ``` If you are not using CMake, include the appropriate header file directly to your project. #### Build options - `biosoup_install`: generate install target - `biosoup_build_tests`: build unit tests #### Dependencies - gcc 4.8+ | clang 3.5+ - (optional) cmake 3.11+ ###### Hidden - (biosoup_test) googletest 1.10.0 ## 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.10.0/include/000077500000000000000000000000001400675556400147075ustar00rootroot00000000000000biosoup-0.10.0/include/biosoup/000077500000000000000000000000001400675556400163675ustar00rootroot00000000000000biosoup-0.10.0/include/biosoup/nucleic_acid.hpp000066400000000000000000000113631400675556400215060ustar00rootroot00000000000000// 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.10.0/include/biosoup/overlap.hpp000066400000000000000000000042051400675556400205510ustar00rootroot00000000000000// 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.10.0/include/biosoup/progress_bar.hpp000066400000000000000000000034131400675556400215710ustar00rootroot00000000000000// 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.10.0/include/biosoup/sequence.hpp000066400000000000000000000047631400675556400207220ustar00rootroot00000000000000// 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.10.0/include/biosoup/timer.hpp000066400000000000000000000025421400675556400202230ustar00rootroot00000000000000// 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.10.0/test/000077500000000000000000000000001400675556400142435ustar00rootroot00000000000000biosoup-0.10.0/test/nucleic_acid_test.cpp000066400000000000000000000054311400675556400204130ustar00rootroot00000000000000// 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.10.0/test/overlap_test.cpp000066400000000000000000000004011400675556400174510ustar00rootroot00000000000000// 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.10.0/test/progress_bar_test.cpp000066400000000000000000000076231400675556400205060ustar00rootroot00000000000000// 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.10.0/test/sequence_test.cpp000066400000000000000000000007531400675556400176230ustar00rootroot00000000000000// 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.10.0/test/timer_test.cpp000066400000000000000000000041611400675556400171300ustar00rootroot00000000000000// 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