diff --git a/include/seqan3/io/sam_file/format_bam.hpp b/include/seqan3/io/sam_file/format_bam.hpp index 914c862ccf..f2c5ab37dd 100644 --- a/include/seqan3/io/sam_file/format_bam.hpp +++ b/include/seqan3/io/sam_file/format_bam.hpp @@ -158,78 +158,78 @@ class format_bam : private detail::format_sam_base }; //!\brief Converts a cigar op character to the rank according to the official BAM specifications. - static constexpr std::array char_to_sam_rank{[]() constexpr {std::array ret{}; - - using index_t = std::make_unsigned_t; - - // ret['M'] = 0; set anyway by initialization - ret[static_cast('I')] = 1; - ret[static_cast('D')] = 2; - ret[static_cast('N')] = 3; - ret[static_cast('S')] = 4; - ret[static_cast('H')] = 5; - ret[static_cast('P')] = 6; - ret[static_cast('=')] = 7; - ret[static_cast('X')] = 8; - - return ret; -}() -}; // namespace seqan3 - -//!\brief Computes the bin number for a given region [beg, end), copied from the official SAM specifications. -static uint16_t reg2bin(int32_t beg, int32_t end) noexcept -{ - --end; - if (beg >> 14 == end >> 14) - return ((1 << 15) - 1) / 7 + (beg >> 14); - if (beg >> 17 == end >> 17) - return ((1 << 12) - 1) / 7 + (beg >> 17); - if (beg >> 20 == end >> 20) - return ((1 << 9) - 1) / 7 + (beg >> 20); - if (beg >> 23 == end >> 23) - return ((1 << 6) - 1) / 7 + (beg >> 23); - if (beg >> 26 == end >> 26) - return ((1 << 3) - 1) / 7 + (beg >> 26); - return 0; -} + static constexpr std::array char_to_sam_rank{[]() constexpr + { + std::array ret{}; + + using index_t = std::make_unsigned_t; + + // ret['M'] = 0; set anyway by initialization + ret[static_cast('I')] = 1; + ret[static_cast('D')] = 2; + ret[static_cast('N')] = 3; + ret[static_cast('S')] = 4; + ret[static_cast('H')] = 5; + ret[static_cast('P')] = 6; + ret[static_cast('=')] = 7; + ret[static_cast('X')] = 8; + + return ret; + }()}; // namespace seqan3 + + //!\brief Computes the bin number for a given region [beg, end), copied from the official SAM specifications. + static uint16_t reg2bin(int32_t beg, int32_t end) noexcept + { + --end; + if (beg >> 14 == end >> 14) + return ((1 << 15) - 1) / 7 + (beg >> 14); + if (beg >> 17 == end >> 17) + return ((1 << 12) - 1) / 7 + (beg >> 17); + if (beg >> 20 == end >> 20) + return ((1 << 9) - 1) / 7 + (beg >> 20); + if (beg >> 23 == end >> 23) + return ((1 << 6) - 1) / 7 + (beg >> 23); + if (beg >> 26 == end >> 26) + return ((1 << 3) - 1) / 7 + (beg >> 26); + return 0; + } -/*!\brief Reads a arithmetic field from binary stream by directly reinterpreting the bits. + /*!\brief Reads a arithmetic field from binary stream by directly reinterpreting the bits. * \tparam stream_view_type The type of the stream as a view. * \tparam number_type The type of number to parse; must model std::integral. * \param[in, out] stream_view The stream view to read from. * \param[out] target An integral value to store the parsed value in. */ -template -void read_integral_byte_field(stream_view_type && stream_view, number_type & target) -{ - std::ranges::copy_n(std::ranges::begin(stream_view), sizeof(target), reinterpret_cast(&target)); -} + template + void read_integral_byte_field(stream_view_type && stream_view, number_type & target) + { + std::ranges::copy_n(std::ranges::begin(stream_view), sizeof(target), reinterpret_cast(&target)); + } -/*!\brief Reads a float field from binary stream by directly reinterpreting the bits. + /*!\brief Reads a float field from binary stream by directly reinterpreting the bits. * \tparam stream_view_type The type of the stream as a view. * \param[in, out] stream_view The stream view to read from. * \param[out] target An float value to store the parsed value in. */ -template -void read_float_byte_field(stream_view_type && stream_view, float & target) -{ - std::ranges::copy_n(std::ranges::begin(stream_view), sizeof(int32_t), reinterpret_cast(&target)); -} + template + void read_float_byte_field(stream_view_type && stream_view, float & target) + { + std::ranges::copy_n(std::ranges::begin(stream_view), sizeof(int32_t), reinterpret_cast(&target)); + } -template -void read_sam_dict_vector(seqan3::detail::sam_tag_variant & variant, - stream_view_type && stream_view, - value_type const & SEQAN3_DOXYGEN_ONLY(value)); + template + void read_sam_dict_vector(seqan3::detail::sam_tag_variant & variant, + stream_view_type && stream_view, + value_type const & SEQAN3_DOXYGEN_ONLY(value)); -template -void read_sam_dict_field(stream_view_type && stream_view, sam_tag_dictionary & target); + template + void read_sam_dict_field(stream_view_type && stream_view, sam_tag_dictionary & target); -template -auto parse_binary_cigar(cigar_input_type && cigar_input, uint16_t n_cigar_op) const; + template + auto parse_binary_cigar(cigar_input_type && cigar_input, uint16_t n_cigar_op) const; -static std::string get_tag_dict_str(sam_tag_dictionary const & tag_dict); -} -; + static std::string get_tag_dict_str(sam_tag_dictionary const & tag_dict); +}; //!\copydoc sam_file_input_format::read_alignment_record template ; static_assert( - []() constexpr { + []() constexpr + { for (field f : selected_field_ids::as_array) if (!field_ids::contains(f)) return false; diff --git a/include/seqan3/io/sam_file/output.hpp b/include/seqan3/io/sam_file/output.hpp index dc986e4e1b..ec3e702070 100644 --- a/include/seqan3/io/sam_file/output.hpp +++ b/include/seqan3/io/sam_file/output.hpp @@ -101,7 +101,8 @@ class sam_file_output field::header_ptr>; static_assert( - []() constexpr { + []() constexpr + { for (field f : selected_field_ids::as_array) if (!field_ids::contains(f)) return false; diff --git a/test/unit/io/sam_file/format_bam_test.cpp b/test/unit/io/sam_file/format_bam_test.cpp index bd3002b652..272f4a9dee 100644 --- a/test/unit/io/sam_file/format_bam_test.cpp +++ b/test/unit/io/sam_file/format_bam_test.cpp @@ -590,7 +590,6 @@ TEST_F(bam_format, too_long_cigar_string_write) } too_long_cigar.push_back({1, 'M'_cigar_operation}); - // Expected output. ATTENTION this could not be validated by samtools as it does not support too long cigar strings std::string expected = std::string /*the beginning*/ @@ -658,9 +657,7 @@ TEST_F(bam_format, issue2417) std::istringstream stream{input}; - seqan3::sam_file_input fin{stream, - seqan3::format_bam{}, - seqan3::fields{}}; + seqan3::sam_file_input fin{stream, seqan3::format_bam{}, seqan3::fields{}}; std::vector> const empty_sequence{};