69 template <
typename stream_type,
70 typename seq_legal_alph_type,
71 typename ref_seqs_type,
72 typename ref_ids_type,
73 typename stream_pos_type,
77 typename ref_seq_type,
79 typename ref_offset_type,
86 typename tag_dict_type,
87 typename e_value_type,
88 typename bit_score_type>
91 ref_seqs_type & ref_seqs,
93 stream_pos_type & position_buffer,
98 ref_seq_type & SEQAN3_DOXYGEN_ONLY(ref_seq),
100 ref_offset_type & ref_offset,
102 cigar_type & cigar_vector,
106 tag_dict_type & tag_dict,
107 e_value_type & SEQAN3_DOXYGEN_ONLY(e_value),
108 bit_score_type & SEQAN3_DOXYGEN_ONLY(bit_score));
110 template <
typename stream_type,
111 typename header_type,
114 typename ref_seq_type,
115 typename ref_id_type,
120 typename tag_dict_type>
123 [[maybe_unused]] header_type && header,
124 [[maybe_unused]] seq_type && seq,
125 [[maybe_unused]] qual_type && qual,
126 [[maybe_unused]] id_type &&
id,
127 [[maybe_unused]] int32_t
const offset,
128 [[maybe_unused]] ref_seq_type && SEQAN3_DOXYGEN_ONLY(ref_seq),
129 [[maybe_unused]] ref_id_type && ref_id,
131 [[maybe_unused]] align_type && align,
132 [[maybe_unused]] cigar_type && cigar_vector,
133 [[maybe_unused]]
sam_flag const flag,
134 [[maybe_unused]] uint8_t
const mapq,
135 [[maybe_unused]] mate_type && mate,
136 [[maybe_unused]] tag_dict_type && tag_dict,
137 [[maybe_unused]]
double SEQAN3_DOXYGEN_ONLY(e_value),
138 [[maybe_unused]]
double SEQAN3_DOXYGEN_ONLY(bit_score));
174 ret[
static_cast<index_t
>(
'I')] = 1;
175 ret[
static_cast<index_t
>(
'D')] = 2;
176 ret[
static_cast<index_t
>(
'N')] = 3;
177 ret[
static_cast<index_t
>(
'S')] = 4;
178 ret[
static_cast<index_t
>(
'H')] = 5;
179 ret[
static_cast<index_t
>(
'P')] = 6;
180 ret[
static_cast<index_t
>(
'=')] = 7;
181 ret[
static_cast<index_t
>(
'X')] = 8;
189 static uint16_t
reg2bin(int32_t beg, int32_t end)
noexcept
192 if (beg >> 14 == end >> 14)
193 return ((1 << 15) - 1) / 7 + (beg >> 14);
194 if (beg >> 17 == end >> 17)
195 return ((1 << 12) - 1) / 7 + (beg >> 17);
196 if (beg >> 20 == end >> 20)
197 return ((1 << 9) - 1) / 7 + (beg >> 20);
198 if (beg >> 23 == end >> 23)
199 return ((1 << 6) - 1) / 7 + (beg >> 23);
200 if (beg >> 26 == end >> 26)
201 return ((1 << 3) - 1) / 7 + (beg >> 26);
211 template <
typename stream_view_type, std::
integral number_type>
222 template <
typename stream_view_type>
228 template <
typename stream_view_type,
typename value_type>
230 stream_view_type && stream_view,
231 value_type
const & SEQAN3_DOXYGEN_ONLY(value));
233 template <
typename stream_view_type>
236 template <
typename cigar_input_type>
243template <
typename stream_type,
244 typename seq_legal_alph_type,
245 typename ref_seqs_type,
246 typename ref_ids_type,
247 typename stream_pos_type,
250 typename offset_type,
251 typename ref_seq_type,
252 typename ref_id_type,
253 typename ref_offset_type,
260 typename tag_dict_type,
261 typename e_value_type,
262 typename bit_score_type>
266 ref_seqs_type & ref_seqs,
268 stream_pos_type & position_buffer,
272 offset_type & offset,
273 ref_seq_type & SEQAN3_DOXYGEN_ONLY(ref_seq),
274 ref_id_type & ref_id,
275 ref_offset_type & ref_offset,
277 cigar_type & cigar_vector,
281 tag_dict_type & tag_dict,
282 e_value_type & SEQAN3_DOXYGEN_ONLY(e_value),
283 bit_score_type & SEQAN3_DOXYGEN_ONLY(bit_score))
285 static_assert(detail::decays_to_ignore_v<ref_offset_type>
286 || detail::is_type_specialisation_of_v<ref_offset_type, std::optional>,
287 "The ref_offset must be a specialisation of std::optional.");
289 static_assert(detail::decays_to_ignore_v<mapq_type> || std::same_as<mapq_type, uint8_t>,
290 "The type of field::mapq must be uint8_t.");
292 static_assert(detail::decays_to_ignore_v<flag_type> || std::same_as<flag_type, sam_flag>,
293 "The type of field::flag must be seqan3::sam_flag.");
298 [[maybe_unused]] int32_t offset_tmp{};
299 [[maybe_unused]] int32_t soft_clipping_end{};
301 [[maybe_unused]] int32_t ref_length{0}, seq_length{0};
323 for (int32_t ref_idx = 0; ref_idx < n_ref; ++ref_idx)
335 if constexpr (detail::decays_to_ignore_v<ref_seqs_type>)
340 auto & reference_ids = header.
ref_ids();
346 header.
ref_dict.emplace(reference_ids.back(), reference_ids.size() - 1);
357 +
"' found in BAM file header (header.ref_ids():",
361 else if (id_it->second != ref_idx)
367 " does not correspond to the position ",
369 " in the header (header.ref_ids():",
373 else if (std::get<0>(header.
ref_id_info[id_it->second]) != l_ref)
375 throw format_error{
"Provided reference has unequal length as specified in the header."};
387 position_buffer = stream.tellg();
391 if (core.
refID >=
static_cast<int32_t
>(header.
ref_ids().size()) || core.
refID < -1)
395 "' is not in range of ",
396 "header.ref_ids(), which has size ",
400 else if (core.
refID > -1)
411 if constexpr (!detail::decays_to_ignore_v<mate_type>)
425 if constexpr (!detail::decays_to_ignore_v<id_type>)
433 if constexpr (!detail::decays_to_ignore_v<align_type> || !detail::decays_to_ignore_v<cigar_type>)
458 if constexpr (detail::decays_to_ignore_v<seq_type>)
460 auto skip_sequence_bytes = [&]()
467 if constexpr (!detail::decays_to_ignore_v<align_type>)
470 "If you want to read ALIGNMENT but not SEQ, the alignment"
471 " object must store a sequence container at the second (query) position.");
473 if (!tmp_cigar_vector.empty())
475 assert(core.
l_seq == (seq_length + offset_tmp + soft_clipping_end));
476 using alph_t = std::ranges::range_value_t<decltype(get<1>(align))>;
477 constexpr auto from_dna16 = detail::convert_through_char_representation<dna16sam, alph_t>;
479 get<1>(align).reserve(seq_length);
482 std::ranges::advance(tmp_iter, offset_tmp / 2);
486 get<1>(align).push_back(from_dna16[
to_rank(get<1>(*tmp_iter))]);
491 for (
size_t i = (seq_length / 2); i > 0; --i)
493 get<1>(align).push_back(from_dna16[
to_rank(get<0>(*tmp_iter))]);
494 get<1>(align).push_back(from_dna16[
to_rank(get<1>(*tmp_iter))]);
500 get<1>(align).push_back(from_dna16[
to_rank(get<0>(*tmp_iter))]);
505 std::ranges::advance(tmp_iter, (soft_clipping_end + !(seq_length & 1)) / 2);
509 skip_sequence_bytes();
515 skip_sequence_bytes();
520 using alph_t = std::ranges::range_value_t<
decltype(
seq)>;
521 constexpr auto from_dna16 = detail::convert_through_char_representation<dna16sam, alph_t>;
523 for (
auto [d1, d2] : seq_stream)
537 if constexpr (!detail::decays_to_ignore_v<align_type>)
539 assign_unaligned(get<1>(align),
541 |
views::slice(
static_cast<std::ranges::range_difference_t<seq_type>
>(offset_tmp),
542 std::ranges::distance(
seq) - soft_clipping_end));
553 return static_cast<char>(chr + 33);
555 if constexpr (!detail::decays_to_ignore_v<qual_type>)
564 assert(remaining_bytes >= 0);
567 while (tags_view.size() > 0)
569 if constexpr (!detail::decays_to_ignore_v<tag_dict_type>)
577 if constexpr (!detail::decays_to_ignore_v<align_type> || !detail::decays_to_ignore_v<cigar_type>)
582 if (core.
l_seq != 0 && offset_tmp == core.
l_seq)
584 if constexpr (detail::decays_to_ignore_v<tag_dict_type> | detail::decays_to_ignore_v<seq_type>)
591 "N' suggests that the cigar string exceeded 65535 elements and was therefore ",
592 "stored in the optional field CG. You need to read in the field::tags and "
593 "field::seq in order to access this information.")};
597 auto it = tag_dict.
find(
"CG"_tag);
599 if (it == tag_dict.end())
601 "The cigar string '",
605 "N' suggests that the cigar string exceeded 65535 elements and was therefore ",
606 "stored in the optional field CG but this tag is not present in the given ",
611 offset_tmp = soft_clipping_end = 0;
615 if constexpr (!detail::decays_to_ignore_v<align_type>)
620 |
views::slice(
static_cast<std::ranges::range_difference_t<seq_type>
>(offset_tmp),
621 std::ranges::distance(
seq) - soft_clipping_end));
628 if constexpr (!detail::decays_to_ignore_v<align_type>)
631 if constexpr (!detail::decays_to_ignore_v<cigar_type>)
632 std::swap(cigar_vector, tmp_cigar_vector);
636template <
typename stream_type,
637 typename header_type,
640 typename ref_seq_type,
641 typename ref_id_type,
646 typename tag_dict_type>
649 [[maybe_unused]] header_type && header,
650 [[maybe_unused]] seq_type && seq,
651 [[maybe_unused]] qual_type && qual,
652 [[maybe_unused]] id_type &&
id,
653 [[maybe_unused]] int32_t
const offset,
654 [[maybe_unused]] ref_seq_type && SEQAN3_DOXYGEN_ONLY(ref_seq),
655 [[maybe_unused]] ref_id_type && ref_id,
657 [[maybe_unused]] align_type && align,
658 [[maybe_unused]] cigar_type && cigar_vector,
659 [[maybe_unused]]
sam_flag const flag,
660 [[maybe_unused]] uint8_t
const mapq,
661 [[maybe_unused]] mate_type && mate,
662 [[maybe_unused]] tag_dict_type && tag_dict,
663 [[maybe_unused]]
double SEQAN3_DOXYGEN_ONLY(e_value),
664 [[maybe_unused]]
double SEQAN3_DOXYGEN_ONLY(bit_score))
670 "The seq object must be a std::ranges::forward_range over "
671 "letters that model seqan3::alphabet.");
674 "The id object must be a std::ranges::forward_range over "
675 "letters that model seqan3::alphabet.");
678 "The ref_seq object must be a std::ranges::forward_range "
679 "over letters that model seqan3::alphabet.");
681 if constexpr (!detail::decays_to_ignore_v<ref_id_type>)
683 static_assert((std::ranges::forward_range<ref_id_type> || std::integral<std::remove_reference_t<ref_id_type>>
684 || detail::is_type_specialisation_of_v<std::remove_cvref_t<ref_id_type>,
std::optional>),
685 "The ref_id object must be a std::ranges::forward_range "
686 "over letters that model seqan3::alphabet or an integral or a std::optional<integral>.");
690 "The align object must be a std::pair of two ranges whose "
691 "value_type is comparable to seqan3::gap");
693 static_assert((std::tuple_size_v<std::remove_cvref_t<align_type>> == 2
694 && std::equality_comparable_with<gap, std::ranges::range_reference_t<decltype(std::get<0>(align))>>
695 && std::equality_comparable_with<
gap, std::ranges::range_reference_t<
decltype(std::get<1>(align))>>),
696 "The align object must be a std::pair of two ranges whose "
697 "value_type is comparable to seqan3::gap");
700 "The qual object must be a std::ranges::forward_range "
701 "over letters that model seqan3::alphabet.");
704 "The mate object must be a std::tuple of size 3 with "
705 "1) a std::ranges::forward_range with a value_type modelling seqan3::alphabet, "
706 "2) a std::integral or std::optional<std::integral>, and "
707 "3) a std::integral.");
710 ((std::ranges::forward_range<decltype(std::get<0>(
mate))>
712 || detail::is_type_specialisation_of_v<
714 std::optional>)&&(std::integral<std::remove_cvref_t<decltype(std::get<1>(
mate))>>
715 || detail::is_type_specialisation_of_v<
717 std::optional>)&&std::integral<std::remove_cvref_t<decltype(std::get<2>(
mate))>>),
718 "The mate object must be a std::tuple of size 3 with "
719 "1) a std::ranges::forward_range with a value_type modelling seqan3::alphabet, "
720 "2) a std::integral or std::optional<std::integral>, and "
721 "3) a std::integral.");
724 "The tag_dict object must be of type seqan3::sam_tag_dictionary.");
726 if constexpr (detail::decays_to_ignore_v<header_type>)
728 throw format_error{
"BAM can only be written with a header but you did not provide enough information! "
729 "You can either construct the output file with ref_ids and ref_seqs information and "
730 "the header will be created for you, or you can access the `header` member directly."};
751 int32_t l_text{
static_cast<int32_t
>(os.
str().size())};
756 int32_t n_ref{
static_cast<int32_t
>(header.
ref_ids().size())};
759 for (int32_t ridx = 0; ridx < n_ref; ++ridx)
761 int32_t l_name{
static_cast<int32_t
>(header.
ref_ids()[ridx].size()) + 1};
776 int32_t ref_length{};
780 if (!std::ranges::empty(cigar_vector))
782 int32_t dummy_seq_length{};
783 for (
auto & [
count, operation] : cigar_vector)
786 else if (!std::ranges::empty(get<0>(align)) && !std::ranges::empty(get<1>(align)))
788 ref_length = std::ranges::distance(get<1>(align));
794 int32_t off_end{
static_cast<int32_t
>(std::ranges::distance(
seq)) -
offset};
796 for (
auto chr : get<1>(align))
800 off_end -= ref_length;
804 if (cigar_vector.size() >= (1 << 16))
807 cigar_vector.resize(2);
808 cigar_vector[0] =
cigar{
static_cast<uint32_t
>(std::ranges::distance(
seq)),
'S'_cigar_operation};
809 cigar_vector[1] =
cigar{
static_cast<uint32_t
>(std::ranges::distance(get<1>(align))),
'N'_cigar_operation};
819 uint8_t read_name_size = std::min<uint8_t>(std::ranges::distance(
id), 254) + 1;
820 read_name_size +=
static_cast<uint8_t
>(read_name_size == 1);
828 static_cast<uint16_t
>(cigar_vector.size()),
830 static_cast<int32_t
>(std::ranges::distance(
seq)),
832 get<1>(
mate).value_or(-1),
835 auto check_and_assign_id_to = [&header]([[maybe_unused]]
auto & id_source, [[maybe_unused]]
auto & id_target)
839 if constexpr (!detail::decays_to_ignore_v<id_t>)
841 if constexpr (std::integral<id_t>)
843 id_target = id_source;
845 else if constexpr (detail::is_type_specialisation_of_v<id_t, std::optional>)
847 id_target = id_source.value_or(-1);
851 if (!std::ranges::empty(id_source))
855 if constexpr (std::ranges::contiguous_range<
decltype(id_source)>
856 && std::ranges::sized_range<
decltype(id_source)>
857 && std::ranges::borrowed_range<
decltype(id_source)>)
868 "The ref_id type is not convertible to the reference id information stored in the "
869 "reference dictionary of the header object.");
871 id_it = header.
ref_dict.find(id_source);
879 "not be found in BAM header ref_dict: ",
884 id_target = id_it->second;
891 check_and_assign_id_to(
ref_id, core.refID);
894 check_and_assign_id_to(get<0>(
mate), core.next_refID);
897 core.block_size =
sizeof(core) - 4 + core.l_read_name + core.n_cigar_op * 4
899 (core.l_seq + 1) / 2 +
901 tag_dict_binary_str.
size();
905 if (std::ranges::empty(
id))
912 for (
auto [cigar_count, op] : cigar_vector)
914 cigar_count = cigar_count << 4;
920 using alph_t = std::ranges::range_value_t<seq_type>;
921 constexpr auto to_dna16 = detail::convert_through_char_representation<alph_t, dna16sam>;
924 for (int32_t sidx = 0; sidx < ((core.l_seq & 1) ? core.l_seq - 1 : core.l_seq); ++sidx, ++sit)
929 stream_it =
static_cast<char>(compressed_chr);
933 stream_it =
static_cast<char>(
to_rank(to_dna16[
to_rank(*sit)]) << 4);
936 if (std::ranges::empty(
qual))
943 if (std::ranges::distance(
qual) != core.l_seq)
946 ". Got quality with size ",
947 std::ranges::distance(
qual),
954 return static_cast<char>(
to_rank(chr));
960 stream << tag_dict_binary_str;
965template <
typename stream_view_type,
typename value_type>
967 stream_view_type && stream_view,
968 value_type
const & SEQAN3_DOXYGEN_ONLY(value))
978 if constexpr (std::integral<value_type>)
982 else if constexpr (std::same_as<value_type, float>)
988 constexpr bool always_false = std::is_same_v<value_type, void>;
989 static_assert(always_false,
"format_bam::read_sam_dict_vector: unsupported value_type");
994 variant = std::move(tmp_vector);
1014template <
typename stream_view_type>
1024 uint16_t tag =
static_cast<uint16_t
>(*it) << 8;
1027 tag +=
static_cast<uint16_t
>(*it);
1046 target[tag] =
static_cast<int32_t
>(tmp);
1053 target[tag] =
static_cast<int32_t
>(tmp);
1060 target[tag] =
static_cast<int32_t
>(tmp);
1067 target[tag] =
static_cast<int32_t
>(tmp);
1074 target[tag] = std::move(tmp);
1081 target[tag] =
static_cast<int32_t
>(tmp);
1094 while (!is_char<'\0'>(*it))
1107 while (!is_char<'\0'>(*it))
1114 throw format_error{
"Hexadecimal tag has an uneven number of digits!"};
1122 target[tag] = byte_array;
1127 char array_value_type_id = *it;
1130 switch (array_value_type_id)
1155 "must be one of [cCsSiIf] but '",
1156 array_value_type_id,
1163 "SAM tag must be one of [A,i,Z,H,B,f] but '",
1183template <
typename cigar_input_type>
1187 char operation{
'\0'};
1189 int32_t ref_length{}, seq_length{};
1190 uint32_t operation_and_count{};
1191 constexpr char const * cigar_mapping =
"MIDNSHP=X*******";
1192 constexpr uint32_t cigar_mask = 0x0f;
1194 if (n_cigar_op == 0)
1195 return std::tuple{operations, ref_length, seq_length};
1199 while (n_cigar_op > 0)
1202 sizeof(operation_and_count),
1203 reinterpret_cast<char *
>(&operation_and_count));
1204 operation = cigar_mapping[operation_and_count & cigar_mask];
1205 count = operation_and_count >> 4;
1212 return std::tuple{operations, ref_length, seq_length};
1222 auto stream_variant_fn = [&result](
auto && arg)
1227 if constexpr (std::same_as<T, int32_t>)
1230 size_t const absolute_arg = std::abs(arg);
1232 bool const negative = arg < 0;
1233 n = n * n + 2 * negative;
1239 result[result.size() - 1] =
'C';
1240 result.append(
reinterpret_cast<char const *
>(&arg), 1);
1245 result[result.size() - 1] =
'S';
1246 result.append(
reinterpret_cast<char const *
>(&arg), 2);
1251 result[result.size() - 1] =
'c';
1252 int8_t tmp =
static_cast<int8_t
>(arg);
1253 result.append(
reinterpret_cast<char const *
>(&tmp), 1);
1258 result[result.size() - 1] =
's';
1259 int16_t tmp =
static_cast<int16_t
>(arg);
1260 result.append(
reinterpret_cast<char const *
>(&tmp), 2);
1265 result.append(
reinterpret_cast<char const *
>(&arg), 4);
1270 else if constexpr (std::same_as<T, std::string>)
1272 result.append(
reinterpret_cast<char const *
>(arg.data()), arg.size() + 1 );
1274 else if constexpr (!std::ranges::range<T>)
1276 result.append(
reinterpret_cast<char const *
>(&arg),
sizeof(arg));
1280 int32_t sz{
static_cast<int32_t
>(arg.size())};
1281 result.append(
reinterpret_cast<char *
>(&sz), 4);
1282 result.append(
reinterpret_cast<char const *
>(arg.data()),
1283 arg.size() *
sizeof(std::ranges::range_value_t<T>));
1287 for (
auto & [tag, variant] : tag_dict)
1289 result.push_back(
static_cast<char>(tag / 256));
1290 result.push_back(
static_cast<char>(tag % 256));
constexpr derived_type & assign_char(char_type const chr) noexcept
Assign from a character, implicitly converts invalid characters.
Definition: alphabet_base.hpp:163
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:187
The seqan3::cigar semialphabet pairs a counter with a seqan3::cigar::operation letter.
Definition: alphabet/cigar/cigar.hpp:60
Functionally the same as std::ostreambuf_iterator, but offers writing a range more efficiently.
Definition: fast_ostreambuf_iterator.hpp:40
A 16 letter DNA alphabet, containing all IUPAC symbols minus the gap and plus an equality sign ('=')....
Definition: dna16sam.hpp:48
The actual implementation of seqan3::cigar::operation for documentation purposes only....
Definition: cigar_operation.hpp:48
The alphabet of a gap character '-'.
Definition: gap.hpp:39
The SAM tag dictionary class that stores all optional SAM fields.
Definition: sam_tag_dictionary.hpp:343
Provides seqan3::dna16sam.
T emplace_back(T... args)
Provides seqan3::detail::fast_ostreambuf_iterator.
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: alphabet/concept.hpp:155
constexpr void consume(rng_t &&rng)
Iterate over a range (consumes single-pass input ranges).
Definition: core/range/detail/misc.hpp:28
constexpr auto all
Returns a view that includes all elements of the range argument.
Definition: all_view.hpp:204
sam_flag
An enum flag that describes the properties of an aligned read (given as a SAM record).
Definition: sam_flag.hpp:76
std::vector< cigar > get_cigar_vector(alignment_type &&alignment, uint32_t const query_start_pos=0, uint32_t const query_end_pos=0, bool const extended_cigar=false)
Creates a cigar string (SAM format) given a seqan3::detail::pairwise_alignment represented by two seq...
Definition: io/sam_file/detail/cigar.hpp:215
constexpr std::tuple< std::vector< cigar >, int32_t, int32_t > parse_cigar(cigar_input_type &&cigar_input)
Parses a cigar string into a vector of operation-count pairs (e.g. (M, 3)).
Definition: io/sam_file/detail/cigar.hpp:148
std::string get_cigar_string(std::vector< cigar > const &cigar_vector)
Transforms a vector of cigar elements into a string representation.
Definition: io/sam_file/detail/cigar.hpp:276
constexpr char sam_tag_type_char_extra[12]
Each types SAM tag type extra char id. Index corresponds to the seqan3::detail::sam_tag_variant types...
Definition: sam_tag_dictionary.hpp:45
void update_alignment_lengths(int32_t &ref_length, int32_t &seq_length, char const cigar_operation, uint32_t const cigar_count)
Updates the sequence lengths by cigar_count depending on the cigar operation op.
Definition: io/sam_file/detail/cigar.hpp:105
constexpr char sam_tag_type_char[12]
Each SAM tag type char identifier. Index corresponds to the seqan3::detail::sam_tag_variant types.
Definition: sam_tag_dictionary.hpp:42
constexpr auto take_exactly_or_throw
A view adaptor that returns the first size elements from the underlying range and also exposes size i...
Definition: take_exactly_view.hpp:590
constexpr auto istreambuf
A view factory that returns a view over the stream buffer of an input stream.
Definition: istreambuf_view.hpp:107
@ flag
The alignment flag (bit information), uint16_t value.
@ ref_offset
Sequence (seqan3::field::ref_seq) relative start position (0-based), unsigned value.
@ mapq
The mapping quality of the seqan3::field::seq alignment, usually a Phred-scaled score.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
@ mate
The mate pair information given as a std::tuple of reference name, offset and template length.
@ ref_id
The identifier of the (reference) sequence that seqan3::field::seq was aligned to.
@ seq
The "sequence", usually a range of nucleotides or amino acids.
@ qual
The qualities, usually in Phred score notation.
decltype(detail::transform< trait_t >(list_t{})) transform
Apply a transformation trait to every type in the list and return a seqan3::type_list of the results.
Definition: type_list/traits.hpp:470
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: type_pack/traits.hpp:164
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:178
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:91
The generic alphabet concept that covers most data types used in ranges.
Checks whether from can be implicityly converted to to.
A more refined container concept than seqan3::container.
Whether a type behaves like a tuple.
Auxiliary functions for the alignment IO.
Provides seqan3::detail::istreambuf.
std::string to_string(value_type &&... values)
Streams all parameters via the seqan3::debug_stream and returns a concatenated string.
Definition: to_string.hpp:29
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides seqan3::debug_stream and related types.
Provides helper data structures for the seqan3::sam_file_output.
Provides the seqan3::sam_tag_dictionary class and auxiliaries.
Provides seqan3::views::slice.
The options type defines various option members that influence the behavior of all or some formats.
Definition: sam_file/output_options.hpp:26
Provides seqan3::views::take_exactly and seqan3::views::take_exactly_or_throw.