SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
output.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <cassert>
16 #include <seqan3/std/filesystem>
17 #include <fstream>
18 #include <seqan3/std/ranges>
19 #include <string>
20 #include <string_view>
21 #include <variant>
22 #include <vector>
23 
26 #include <seqan3/io/detail/record.hpp>
28 #include <seqan3/io/exception.hpp>
29 #include <seqan3/io/record.hpp>
39 
40 namespace seqan3
41 {
42 
43 #ifdef SEQAN3_DEPRECATED_310
45 template <typename tuple_t>
46 static constexpr bool fourth_tuple_element_is_sequence = false;
47 
48 template <typename tuple_t>
50 static constexpr bool fourth_tuple_element_is_sequence<tuple_t>
51  = seqan3::sequence<std::remove_cvref_t<std::tuple_element_t<3, tuple_t>>>;
53 #endif // SEQAN3_DEPRECATED_310
54 
55 // ----------------------------------------------------------------------------
56 // sam_file_output
57 // ----------------------------------------------------------------------------
58 
156 template <detail::fields_specialisation selected_field_ids_ =
157  fields<field::seq,
158  field::id,
163  field::cigar,
164  field::mapq,
165  field::qual,
166  field::flag,
167  field::mate,
168  field::tags,
170  detail::type_list_of_sam_file_output_formats valid_formats_ = type_list<format_sam, format_bam>,
171  typename ref_ids_type = ref_info_not_given>
173 {
174 public:
180  using selected_field_ids = selected_field_ids_;
182  using valid_formats = valid_formats_;
183 #ifdef SEQAN3_DEPRECATED_310
186  using ref_ids_type_t = ref_ids_type;
188 #endif // SEQAN3_DEPRECATED_310
190  using stream_char_type = char;
192 
195  field::id,
200  field::cigar,
201  field::mapq,
202  field::flag,
203  field::qual,
204  field::mate,
205  field::tags,
207 
208 #ifdef SEQAN3_DEPRECATED_310
210  static constexpr bool is_default_selected_field_ids = selected_field_ids::size == field_ids::size;
211 
213  "You selected the deprecated seqan3::field::ref_seq. It will not be available in the record.");
215  "You selected the deprecated seqan3::field::evalue. It will not be available in the record.");
217  "You selected the deprecated seqan3::field::bit_score. It will not be available in the record.");
218 #endif // SEQAN3_DEPRECATED_310
219 
220  static_assert([] () constexpr
221  {
222  for (field f : selected_field_ids::as_array)
223  if (!field_ids::contains(f))
224  return false;
225  return true;
226  }(),
227  "You selected a field that is not valid for alignment files, "
228  "please refer to the documentation of "
229  "seqan3::sam_file_output::field_ids for the accepted values.");
230 
237  using value_type = void;
239  using reference = void;
241  using const_reference = void;
243  using size_type = void;
247  using iterator = detail::out_file_iterator<sam_file_output>;
249  using const_iterator = void;
251  using sentinel = std::default_sentinel_t;
253 
258  sam_file_output() = delete;
260  sam_file_output(sam_file_output const &) = delete;
268  ~sam_file_output() = default;
269 
296  selected_field_ids const & SEQAN3_DOXYGEN_ONLY(fields_tag) = selected_field_ids{}) :
297  primary_stream{new std::ofstream{}, stream_deleter_default}
298  {
299  primary_stream->rdbuf()->pubsetbuf(stream_buffer.data(), stream_buffer.size());
300  static_cast<std::basic_ofstream<char> *>(primary_stream.get())->open(filename,
301  std::ios_base::out | std::ios::binary);
302 
303  // open stream
304  if (!primary_stream->good())
305  throw file_open_error{"Could not open file " + filename.string() + " for writing."};
306 
307  // possibly add intermediate compression stream
308  secondary_stream = detail::make_secondary_ostream(*primary_stream, filename);
309 
310  // initialise format handler or throw if format is not found
311  detail::set_format(format, filename);
312  }
313 
330  template <output_stream stream_type, sam_file_output_format file_format>
332  requires std::same_as<typename std::remove_reference_t<stream_type>::char_type, stream_char_type>
334  sam_file_output(stream_type & stream,
335  file_format const & SEQAN3_DOXYGEN_ONLY(format_tag),
336  selected_field_ids const & SEQAN3_DOXYGEN_ONLY(fields_tag) = selected_field_ids{}) :
337  primary_stream{&stream, stream_deleter_noop},
338  secondary_stream{&stream, stream_deleter_noop},
339  format{detail::sam_file_output_format_exposer<file_format>{}}
340  {
341  static_assert(list_traits::contains<file_format, valid_formats>,
342  "You selected a format that is not in the valid_formats of this file.");
343  }
344 
346  template <output_stream stream_type, sam_file_output_format file_format>
348  requires std::same_as<typename std::remove_reference_t<stream_type>::char_type, stream_char_type>
350  sam_file_output(stream_type && stream,
351  file_format const & SEQAN3_DOXYGEN_ONLY(format_tag),
352  selected_field_ids const & SEQAN3_DOXYGEN_ONLY(fields_tag) = selected_field_ids{}) :
353  primary_stream{new stream_type{std::move(stream)}, stream_deleter_default},
354  secondary_stream{&*primary_stream, stream_deleter_noop},
355  format{detail::sam_file_output_format_exposer<file_format>{}}
356  {
357  static_assert(list_traits::contains<file_format, valid_formats>,
358  "You selected a format that is not in the valid_formats of this file.");
359  }
360 
391  template <typename ref_ids_type_, std::ranges::forward_range ref_lengths_type>
393  requires std::same_as<std::remove_reference_t<ref_ids_type_>, ref_ids_type>
396  ref_ids_type_ && ref_ids,
397  ref_lengths_type && ref_lengths,
398  selected_field_ids const & SEQAN3_DOXYGEN_ONLY(fields_tag) = selected_field_ids{}) :
400 
401  {
402  initialise_header_information(ref_ids, ref_lengths);
403  }
404 
426  template <output_stream stream_type,
427  sam_file_output_format file_format,
428  typename ref_ids_type_, // generic type to capture lvalue references
429  std::ranges::forward_range ref_lengths_type>
431  requires std::same_as<std::remove_reference_t<ref_ids_type_>, ref_ids_type>
433  sam_file_output(stream_type && stream,
434  ref_ids_type_ && ref_ids,
435  ref_lengths_type && ref_lengths,
436  file_format const & SEQAN3_DOXYGEN_ONLY(format_tag),
437  selected_field_ids const & SEQAN3_DOXYGEN_ONLY(fields_tag) = selected_field_ids{}) :
438  sam_file_output{std::forward<stream_type>(stream), file_format{}, selected_field_ids{}}
439  {
440  initialise_header_information(ref_ids, ref_lengths);
441  }
443 
465  iterator begin() noexcept
466  {
467  return {*this};
468  }
469 
484  sentinel end() noexcept
485  {
486  return {};
487  }
488 
507  template <typename record_t>
508  void push_back(record_t && r)
510  requires detail::record_like<record_t>
512  {
513  using default_align_t = std::pair<std::span<gapped<char>>, std::span<gapped<char>>>;
514  using default_mate_t = std::tuple<std::string_view, std::optional<int32_t>, int32_t>;
515 
516  write_record(detail::get_or<field::header_ptr>(r, nullptr),
517  detail::get_or<field::seq>(r, std::string_view{}),
518  detail::get_or<field::qual>(r, std::string_view{}),
519  detail::get_or<field::id>(r, std::string_view{}),
520  detail::get_or<field::offset>(r, 0u),
521  detail::get_or<field::ref_seq>(r, std::string_view{}),
522  detail::get_or<field::ref_id>(r, std::ignore),
523  detail::get_or<field::ref_offset>(r, std::optional<int32_t>{}),
524  detail::get_or<field::alignment>(r, default_align_t{}),
525  detail::get_or<field::cigar>(r, std::vector<cigar>{}),
526  detail::get_or<field::flag>(r, sam_flag::none),
527  detail::get_or<field::mapq>(r, 0u),
528  detail::get_or<field::mate>(r, default_mate_t{}),
529  detail::get_or<field::tags>(r, sam_tag_dictionary{}),
530  detail::get_or<field::evalue>(r, 0u),
531  detail::get_or<field::bit_score>(r, 0u));
532  }
533 
555 #ifdef SEQAN3_DEPRECATED_310
556  template <typename tuple_t>
557  void push_back(tuple_t && t)
559  // new syntax enforces via static_assert that field::ref_seq, field::evalue, and field::bit_score isn't set
560  requires tuple_like<tuple_t> && (!detail::record_like<tuple_t>) && (!is_default_selected_field_ids)
562  {
563  push_back_tuple(std::forward<tuple_t>(t));
564  }
565 
566  // The new syntax enforces via static_assert (see above) that field::ref_seq, field::evalue, and field::bit_score
567  // isn't set. That makes sure that someone who explicitly requested for these fields will get a deprecation warning.
568  // That leaves the case where the user did not provide any fields and just used the default ones.
569  // This causes a problem, because it is complicated to decide whether the new syntax or the old syntax is used.
570  // position | old fields | new fields
571  // -------- | ------------------ | -------------
572  // 0 | field::seq | field::seq
573  // 1 | field::id | field::id
574  // 2 | field::offset | field::offset
575  // 3 | field::ref_seq | field::ref_id
576  // 4 | field::ref_id | field::ref_offset
577  // 5 | field::ref_offset | field::alignment
578  // 6 | field::alignment | field::cigar
579  // 7 | field::cigar | field::mapq
580  // 8 | field::mapq | field::flag
581  // 9 | field::flag | field::qual
582  // 10 | field::qual | field::mate
583  // 11 | field::mate | field::tags
584  // 12 | field::tags | field::header_ptr
585  // 13 | field::evalue | -
586  // 14 | field::bit_score | -
587  // 15 | field::header_ptr | -
588  //
589  // That means we have the following three cases:
590  // * sizeof...(arg_types) + 1 <= 3 are identical.
591  // * sizeof...(arg_types) + 1 > 3
592  // * 4. arg is not a seqan3::sequence => that field is a field::ref_id (new syntax)
593  // * 4. arg is a seqan3::sequence => that field is a field::ref_seq (old syntax)
594 
596  // selected_field_ids::size can only be <= 13 or == 16 (static asserts above ensure that)
597  // sizeof...(arg_types) + 1 <= 3 are identical. (old and new syntax)
598  template <typename tuple_t>
599  void push_back(tuple_t && t)
600  requires tuple_like<tuple_t> && (!detail::record_like<tuple_t>) && (is_default_selected_field_ids)
601  && (std::tuple_size_v<std::remove_cvref_t<tuple_t>> <= 3)
602  {
603  push_back_tuple(std::forward<tuple_t>(t));
604  }
606 
608  // * sizeof...(arg_types) + 1 > 3
609  // * 4. arg is not a seqan3::sequence => that field is a field::ref_id (new syntax)
610  template <typename tuple_t>
611  void push_back(tuple_t && t)
612  requires tuple_like<tuple_t> && (!detail::record_like<tuple_t>) && (is_default_selected_field_ids)
613  && (std::tuple_size_v<std::remove_cvref_t<tuple_t>> > 3)
614  && (!fourth_tuple_element_is_sequence<std::remove_cvref_t<tuple_t>>)
615  {
616  push_back_tuple(std::forward<tuple_t>(t));
617  }
619 
621  // * sizeof...(arg_types) + 1 > 3
622  // * 4. arg is a seqan3::sequence => that field is a field::ref_seq (old syntax)
623  template <typename tuple_t>
624  SEQAN3_DEPRECATED_310 void push_back(tuple_t && t)
625  requires tuple_like<tuple_t> && (!detail::record_like<tuple_t>) && (is_default_selected_field_ids)
626  && (std::tuple_size_v<std::remove_cvref_t<tuple_t>> > 3)
627  && (fourth_tuple_element_is_sequence<std::remove_cvref_t<tuple_t>>)
628  {
629  using default_align_t = std::pair<std::span<gapped<char>>, std::span<gapped<char>>>;
630  using default_mate_t = std::tuple<std::string_view, std::optional<int32_t>, int32_t>;
631 
632  // pad it to 16 elements (we know the order of the default field ids)
634  detail::get_or<0>(t, std::string_view{}), // field::seq
635  detail::get_or<1>(t, std::string_view{}), // field::id
636  detail::get_or<2>(t, 0u), // field::offset
637  // detail::get_or<3>(t, std::string_view{}), // field::ref_seq not used
638  detail::get_or<4>(t, std::ignore), // field::ref_id
639  detail::get_or<5>(t, std::optional<int32_t>{}), // field::ref_offset
640  detail::get_or<6>(t, default_align_t{}), // field::alignment
641  detail::get_or<7>(t, std::vector<cigar>{}), // field::cigar
642  detail::get_or<8>(t, 0u), // field::mapq
643  detail::get_or<9>(t, sam_flag::none), // field::flag
644  detail::get_or<10>(t, std::string_view{}), // field::qual
645  detail::get_or<11>(t, default_mate_t{}), // field::mate
646  detail::get_or<12>(t, sam_tag_dictionary{}), // field::tags
647  // detail::get_or<13>(t, 0u), // field::evalue not used
648  // detail::get_or<14>(t, 0u), // field::bit_score not used
649  detail::get_or<15>(t, nullptr) // field::header_ptr
650  ));
651  }
653 
656  template <typename tuple_t>
657  void push_back_tuple(tuple_t && t)
658 #else // ^^^ before SeqAn 3.1.0 / after SeqAn 3.1.0 vvv
659  template <typename tuple_t>
660  void push_back(tuple_t && t)
662  requires tuple_like<tuple_t> && (!detail::record_like<tuple_t>)
664 #endif // SEQAN3_DEPRECATED_310
665  {
666  using default_align_t = std::pair<std::span<gapped<char>>, std::span<gapped<char>>>;
667  using default_mate_t = std::tuple<std::string_view, std::optional<int32_t>, int32_t>;
668 
669  // index_of might return npos, but this will be handled well by get_or_ignore (and just return ignore)
670  write_record(detail::get_or<selected_field_ids::index_of(field::header_ptr)>(t, nullptr),
671  detail::get_or<selected_field_ids::index_of(field::seq)>(t, std::string_view{}),
672  detail::get_or<selected_field_ids::index_of(field::qual)>(t, std::string_view{}),
673  detail::get_or<selected_field_ids::index_of(field::id)>(t, std::string_view{}),
674  detail::get_or<selected_field_ids::index_of(field::offset)>(t, 0u),
675  detail::get_or<selected_field_ids::index_of(field::ref_seq)>(t, std::string_view{}),
676  detail::get_or<selected_field_ids::index_of(field::ref_id)>(t, std::ignore),
677  detail::get_or<selected_field_ids::index_of(field::ref_offset)>(t, std::optional<int32_t>{}),
678  detail::get_or<selected_field_ids::index_of(field::alignment)>(t, default_align_t{}),
679  detail::get_or<selected_field_ids::index_of(field::cigar)>(t, std::vector<cigar>{}),
680  detail::get_or<selected_field_ids::index_of(field::flag)>(t, sam_flag::none),
681  detail::get_or<selected_field_ids::index_of(field::mapq)>(t, 0u),
682  detail::get_or<selected_field_ids::index_of(field::mate)>(t, default_mate_t{}),
683  detail::get_or<selected_field_ids::index_of(field::tags)>(t, sam_tag_dictionary{}),
684  detail::get_or<selected_field_ids::index_of(field::evalue)>(t, 0u),
685  detail::get_or<selected_field_ids::index_of(field::bit_score)>(t, 0u));
686  }
687 
711  template <typename arg_t, typename ...arg_types>
713  requires (sizeof...(arg_types) + 1 <= selected_field_ids::size)
715  void emplace_back(arg_t && arg, arg_types && ... args)
716 #ifdef SEQAN3_DEPRECATED_310
717  // selected_field_ids::size can only be <= 13 or == 16 (static asserts above ensure that)
719 #endif // SEQAN3_DEPRECATED_310
720  {
721  push_back(std::tie(arg, args...));
722  }
723 
724 #ifdef SEQAN3_DEPRECATED_310
726  // sizeof...(arg_types) + 1 <= 3 are identical. (old and new syntax)
727  template <typename arg_t, typename ...arg_types>
728  requires (sizeof...(arg_types) + 1 <= 3)
729  void emplace_back(arg_t && arg, arg_types && ... args)
731  {
732  push_back(std::tie(arg, args...));
733  }
735 
737  // * sizeof...(arg_types) + 1 > 3
738  // * 4. arg is not a seqan3::sequence => that field is a field::ref_id (new syntax)
739  template <typename seq_t, typename id_t, typename offset_t, typename ref_id_t, typename ...arg_types>
741  void emplace_back(seq_t && seq, id_t && id, offset_t && offset, ref_id_t && ref_id, arg_types && ... args)
743  {
744  push_back(std::tie(seq, id, offset, ref_id, args...));
745  }
747 
749  // * sizeof...(arg_types) + 1 > 3
750  // * 4. arg is a seqan3::sequence => that field is a field::ref_seq (old syntax)
751  template <typename seq_t, typename id_t, typename offset_t, typename ref_seq_t, typename ...arg_types>
753  void emplace_back SEQAN3_DEPRECATED_310(seq_t && seq,
754  id_t && id,
755  offset_t && offset,
756  [[maybe_unused]] ref_seq_t && ref_seq,
757  arg_types && ... args)
759  {
760 #pragma GCC diagnostic push
761 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
762  // use deprecated call
763  push_back(std::tie(seq, id, offset, ref_seq, args...));
764 #pragma GCC diagnostic pop
765  }
767 #endif // SEQAN3_DEPRECATED_310
768 
790  template <typename rng_t>
791  sam_file_output & operator=(rng_t && range)
793  requires std::ranges::input_range<rng_t> && tuple_like<std::ranges::range_reference_t<rng_t>>
795  {
796  for (auto && record : range)
797  push_back(std::forward<decltype(record)>(record));
798  return *this;
799  }
800 
829  template <typename rng_t>
830  friend sam_file_output & operator|(rng_t && range, sam_file_output & f)
832  requires std::ranges::input_range<rng_t> && tuple_like<std::ranges::range_reference_t<rng_t>>
834  {
835  f = range;
836  return f;
837  }
838 
840  template <typename rng_t>
841  friend sam_file_output operator|(rng_t && range, sam_file_output && f)
843  requires std::ranges::input_range<rng_t> && tuple_like<std::ranges::range_reference_t<rng_t>>
845  {
846  f = range;
847  return std::move(f);
848  }
850 
853 
858  {
859  return *secondary_stream;
860  }
862 
873  auto & header()
874  {
875  if constexpr (std::same_as<ref_ids_type, ref_info_not_given>)
876  throw std::logic_error{"Please construct your file with reference id and length information in order "
877  "to properly initialise the header before accessing it."};
878 
879  return *header_ptr;
880  }
881 
882 protected:
885  std::vector<char> stream_buffer{std::vector<char>(1'000'000)};
886 
894  static void stream_deleter_noop(std::basic_ostream<stream_char_type> *) {}
896  static void stream_deleter_default(std::basic_ostream<stream_char_type> * ptr) { delete ptr; }
897 
899  stream_ptr_t primary_stream{nullptr, stream_deleter_noop};
901  stream_ptr_t secondary_stream{nullptr, stream_deleter_noop};
902 
904  using format_type = typename detail::variant_from_tags<valid_formats,
905  detail::sam_file_output_format_exposer>::type;
906 
908  format_type format;
910 
912  using header_type = sam_file_header<std::conditional_t<std::same_as<ref_ids_type, ref_info_not_given>,
914  ref_ids_type>>;
915 
917  std::unique_ptr<header_type> header_ptr;
918 
920  template <typename ref_ids_type_, typename ref_lengths_type>
921  void initialise_header_information(ref_ids_type_ && ref_ids, ref_lengths_type && ref_lengths)
922  {
923  assert(std::ranges::size(ref_ids) == std::ranges::size(ref_lengths));
924 
925  header_ptr = std::make_unique<sam_file_header<ref_ids_type>>(std::forward<ref_ids_type_>(ref_ids));
926 
927  for (int32_t idx = 0; idx < std::ranges::distance(ref_ids); ++idx)
928  {
929  header_ptr->ref_id_info.emplace_back(ref_lengths[idx], "");
930 
931  if constexpr (std::ranges::contiguous_range<std::ranges::range_reference_t<ref_ids_type_>> &&
932  std::ranges::sized_range<std::ranges::range_reference_t<ref_ids_type_>> &&
933  std::ranges::borrowed_range<std::ranges::range_reference_t<ref_ids_type_>>)
934  {
935  auto && id = header_ptr->ref_ids()[idx];
936  header_ptr->ref_dict[std::span{std::ranges::data(id), std::ranges::size(id)}] = idx;
937  }
938  else
939  {
940  header_ptr->ref_dict[header_ptr->ref_ids()[idx]] = idx;
941  }
942  }
943  }
944 
946  template <typename record_header_ptr_t, typename ...pack_type>
947  void write_record(record_header_ptr_t && record_header_ptr, pack_type && ...remainder)
948  {
949  static_assert((sizeof...(pack_type) == 15), "Wrong parameter list passed to write_record.");
950 
951  assert(!format.valueless_by_exception());
952 
953  std::visit([&] (auto & f)
954  {
955  // use header from record if explicitly given, e.g. file_output = file_input
956  if constexpr (!std::same_as<record_header_ptr_t, std::nullptr_t>)
957  {
958  f.write_alignment_record(*secondary_stream,
959  options,
960  *record_header_ptr,
961  std::forward<pack_type>(remainder)...);
962  }
963  else if constexpr (std::same_as<ref_ids_type, ref_info_not_given>)
964  {
965  f.write_alignment_record(*secondary_stream,
966  options,
967  std::ignore,
968  std::forward<pack_type>(remainder)...);
969  }
970  else
971  {
972  f.write_alignment_record(*secondary_stream,
973  options,
974  *header_ptr,
975  std::forward<pack_type>(remainder)...);
976  }
977  }, format);
978  }
979 
981  friend iterator;
982 };
983 
992 template <detail::fields_specialisation selected_field_ids>
995 
999 template <output_stream stream_type,
1000  sam_file_output_format file_format,
1001  detail::fields_specialisation selected_field_ids>
1002 sam_file_output(stream_type &&, file_format const &, selected_field_ids const &)
1004 
1008 template <output_stream stream_type,
1009  sam_file_output_format file_format,
1010  detail::fields_specialisation selected_field_ids>
1011 sam_file_output(stream_type &, file_format const &, selected_field_ids const &)
1013 
1017 template <output_stream stream_type,
1018  sam_file_output_format file_format>
1019 sam_file_output(stream_type &&, file_format const &)
1021 
1025 template <output_stream stream_type,
1026  sam_file_output_format file_format>
1027 sam_file_output(stream_type &, file_format const &)
1029 
1031 template <detail::fields_specialisation selected_field_ids,
1032  std::ranges::forward_range ref_ids_type,
1033  std::ranges::forward_range ref_lengths_type>
1034 sam_file_output(std::filesystem::path const &, ref_ids_type &&, ref_lengths_type &&, selected_field_ids const &)
1038 
1040 template <std::ranges::forward_range ref_ids_type,
1041  std::ranges::forward_range ref_lengths_type>
1042 sam_file_output(std::filesystem::path const &, ref_ids_type &&, ref_lengths_type &&)
1046 
1048 template <output_stream stream_type,
1049  std::ranges::forward_range ref_ids_type,
1050  std::ranges::forward_range ref_lengths_type,
1051  sam_file_output_format file_format,
1052  detail::fields_specialisation selected_field_ids>
1053 sam_file_output(stream_type &&, ref_ids_type &&, ref_lengths_type &&, file_format const &, selected_field_ids const &)
1055 
1057 template <output_stream stream_type,
1058  std::ranges::forward_range ref_ids_type,
1059  std::ranges::forward_range ref_lengths_type,
1060  sam_file_output_format file_format,
1061  detail::fields_specialisation selected_field_ids>
1062 sam_file_output(stream_type &, ref_ids_type &&, ref_lengths_type &&, file_format const &, selected_field_ids const &)
1064 
1066 template <output_stream stream_type,
1067  std::ranges::forward_range ref_ids_type,
1068  std::ranges::forward_range ref_lengths_type,
1069  sam_file_output_format file_format>
1070 sam_file_output(stream_type &&, ref_ids_type &&, ref_lengths_type &&, file_format const &)
1074 
1076 template <output_stream stream_type,
1077  std::ranges::forward_range ref_ids_type,
1078  std::ranges::forward_range ref_lengths_type,
1079  sam_file_output_format file_format>
1080 sam_file_output(stream_type &, ref_ids_type &&, ref_lengths_type &&, file_format const &)
1085 
1086 } // namespace seqan3
A class for writing alignment files, e.g. SAM, BAL, BLAST, ...
Definition: output.hpp:173
void const_reference
The const reference type (void).
Definition: output.hpp:241
sam_file_output(stream_type &&stream, ref_ids_type_ &&ref_ids, ref_lengths_type &&ref_lengths, file_format const &format_tag, selected_field_ids const &fields_tag=selected_field_ids{})
Construct from an existing stream and with specified format.
Definition: output.hpp:433
sam_file_output(stream_type &, ref_ids_type &&, ref_lengths_type &&, file_format const &, selected_field_ids const &) -> sam_file_output< selected_field_ids, type_list< file_format >, std::remove_reference_t< ref_ids_type >>
Deduces selected_field_ids, the valid format, and the ref_ids_type from input.
void size_type
The size type (void).
Definition: output.hpp:243
sam_file_output(stream_type &&stream, file_format const &format_tag, selected_field_ids const &fields_tag=selected_field_ids{})
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: output.hpp:350
sam_file_output(sam_file_output const &)=delete
Copy construction is explicitly deleted, because you can't have multiple access to the same file.
friend sam_file_output & operator|(rng_t &&range, sam_file_output &f)
Write a range of records (or tuples) to the file.
Definition: output.hpp:830
sam_file_output()=delete
Default constructor is explicitly deleted, you need to give a stream or file name.
detail::out_file_iterator< sam_file_output > iterator
The iterator type of this view (an output iterator).
Definition: output.hpp:247
sam_file_output & operator=(rng_t &&range)
Write a range of records (or tuples) to the file.
Definition: output.hpp:791
sam_file_output & operator=(sam_file_output const &)=delete
Copy assignment is explicitly deleted, because you can't have multiple access to the same file.
sam_file_output(std::filesystem::path const &, ref_ids_type &&, ref_lengths_type &&) -> sam_file_output< typename sam_file_output<>::selected_field_ids, typename sam_file_output<>::valid_formats, std::remove_reference_t< ref_ids_type >>
Deduces ref_ids_type from input. Valid formats, and selected_field_ids are set to the default.
auto & header()
Access the file's header.
Definition: output.hpp:873
std::default_sentinel_t sentinel
The type returned by end().
Definition: output.hpp:251
char stream_char_type
Character type of the stream(s).
Definition: output.hpp:190
sam_file_output(stream_type &stream, file_format const &format_tag, selected_field_ids const &fields_tag=selected_field_ids{})
Construct from an existing stream and with specified format.
Definition: output.hpp:334
iterator begin() noexcept
Returns an iterator to current position in the file.
Definition: output.hpp:465
sam_file_output(std::filesystem::path const &, ref_ids_type &&, ref_lengths_type &&, selected_field_ids const &) -> sam_file_output< selected_field_ids, typename sam_file_output<>::valid_formats, std::remove_reference_t< ref_ids_type >>
Deduces selected_field_ids and ref_ids_type from input. valid_formats is set to the default.
sentinel end() noexcept
Returns a sentinel for comparison with iterator.
Definition: output.hpp:484
static constexpr bool is_default_selected_field_ids
brief Does selected_field_ids contain all fields like in the default case?
Definition: output.hpp:210
sam_file_output(std::filesystem::path, selected_field_ids const &) -> sam_file_output< selected_field_ids, typename sam_file_output<>::valid_formats, ref_info_not_given >
Deduces selected_field_ids from input and sets sam_file_output::ref_ids_type to seqan3::detail::ref_i...
void push_back(record_t &&r)
Write a seqan3::record to the file.
Definition: output.hpp:508
selected_field_ids_ selected_field_ids
A seqan3::fields list with the fields selected for the record.
Definition: output.hpp:180
sam_file_output & operator=(sam_file_output &&)=default
Move assignment is defaulted.
valid_formats_ valid_formats
A seqan3::type_list with the possible formats.
Definition: output.hpp:182
void reference
The reference type (void).
Definition: output.hpp:239
sam_file_output(stream_type &, ref_ids_type &&, ref_lengths_type &&, file_format const &) -> sam_file_output< typename sam_file_output<>::selected_field_ids, type_list< file_format >, std::remove_reference_t< ref_ids_type >>
Deduces the valid format, and the ref_ids_type from input. selected_field_ids set to the default.
sam_file_output(stream_type &&, file_format const &) -> sam_file_output< typename sam_file_output<>::selected_field_ids, type_list< file_format >, ref_info_not_given >
Deduces the valid format from input and sets sam_file_output::ref_ids_type to seqan3::detail::ref_inf...
sam_file_output(std::filesystem::path filename, selected_field_ids const &fields_tag=selected_field_ids{})
Construct from filename.
Definition: output.hpp:295
sam_file_output(stream_type &&, ref_ids_type &&, ref_lengths_type &&, file_format const &) -> sam_file_output< typename sam_file_output<>::selected_field_ids, type_list< file_format >, std::remove_reference_t< ref_ids_type >>
Deduces the valid format, and the ref_ids_type from input. selected_field_ids set to the default.
void push_back(tuple_t &&t)
Write a record in form of a std::tuple to the file.
Definition: output.hpp:557
void value_type
The value type (void).
Definition: output.hpp:237
~sam_file_output()=default
Destructor is defaulted.
sam_file_output_options options
The options are public and its members can be set directly.
Definition: output.hpp:852
sam_file_output(stream_type &&, ref_ids_type &&, ref_lengths_type &&, file_format const &, selected_field_ids const &) -> sam_file_output< selected_field_ids, type_list< file_format >, std::remove_reference_t< ref_ids_type >>
Deduces selected_field_ids, the valid format, and the ref_ids_type from input.
sam_file_output(sam_file_output &&)=default
Move construction is defaulted.
sam_file_output(stream_type &, file_format const &, selected_field_ids const &) -> sam_file_output< selected_field_ids, type_list< file_format >, ref_info_not_given >
Deduces selected_field_ids, and the valid format from input and sets sam_file_output::ref_ids_type to...
void emplace_back(arg_t &&arg, arg_types &&... args) requires(!is_default_selected_field_ids)
Write a record to the file by passing individual fields.
Definition: output.hpp:715
sam_file_output(stream_type &&, file_format const &, selected_field_ids const &) -> sam_file_output< selected_field_ids, type_list< file_format >, ref_info_not_given >
Deduces selected_field_ids, and the valid format from input and sets sam_file_output::ref_ids_type to...
sam_file_output(std::filesystem::path const &filename, ref_ids_type_ &&ref_ids, ref_lengths_type &&ref_lengths, selected_field_ids const &fields_tag=selected_field_ids{})
Construct from filename.
Definition: output.hpp:395
friend sam_file_output operator|(rng_t &&range, sam_file_output &&f)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: output.hpp:841
void const_iterator
The const iterator type is void, because files are not const-iterable.
Definition: output.hpp:249
sam_file_output(stream_type &, file_format const &) -> sam_file_output< typename sam_file_output<>::selected_field_ids, type_list< file_format >, ref_info_not_given >
Deduces the valid format from input and sets sam_file_output::ref_ids_type to seqan3::detail::ref_inf...
The SAM tag dictionary class that stores all optional SAM fields.
Definition: sam_tag_dictionary.hpp:332
T data(T... args)
This header includes C++17 filesystem support and imports it into namespace std::filesystem (independ...
T format(T... args)
T forward(T... args)
T get(T... args)
@ none
None of the flags below are set.
field
An enumerator for the fields used in file formats.
Definition: record.hpp:63
@ flag
The alignment flag (bit information), uint16_t value.
@ ref_offset
Sequence (seqan3::field::ref_seq) relative start position (0-based), unsigned value.
@ ref_seq
The (reference) "sequence" information, usually a range of nucleotides or amino acids.
@ alignment
The (pairwise) alignment stored in an object that models seqan3::detail::pairwise_alignment.
@ cigar
The cigar vector (std::vector<seqan3::cigar>) representing the alignment in SAM/BAM format.
@ mapq
The mapping quality of the seqan3::field::seq alignment, usually a Phred-scaled score.
@ bit_score
The bit score (statistical significance indicator), unsigned value.
@ 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.
@ header_ptr
A pointer to the seqan3::sam_file_header object storing header information.
@ ref_id
The identifier of the (reference) sequence that seqan3::field::seq was aligned to.
@ evalue
The e-value (length normalized bit score), double value.
@ id
The identifier, usually a string.
@ tags
The optional tags in the SAM format, stored in a dictionary.
@ seq
The "sequence", usually a range of nucleotides or amino acids.
@ qual
The qualities, usually in Phred score notation.
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:231
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
std::remove_cv_t< std::remove_reference_t< t > > remove_cvref_t
Return the input type with const, volatile and references removed (type trait).
Definition: basic.hpp:45
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
The generic concept for alignment file out formats.
The generic concept for a (biological) sequence.
Whether a type behaves like a tuple.
Provides exceptions used in the I/O module.
Stream concepts.
Provides various utility functions required only for output.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
Provides the seqan3::detail::out_file_iterator class template.
#define SEQAN3_DEPRECATED_310
Deprecation message for SeqAn 3.1.0 release.
Definition: platform.hpp:203
Adaptations of concepts from the Ranges TS.
Provides the seqan3::record template and the seqan3::field enum.
Provides seqan3::detail::record_like.
Provides the seqan3::format_bam.
Provides the seqan3::format_sam.
Provides the seqan3::sam_file_header class.
Provides seqan3::sam_file_output_format and auxiliary classes.
Provides seqan3::sam_file_output_options.
Provides helper data structures for the seqan3::sam_file_output.
T size(T... args)
A class template that holds a choice of seqan3::field.
Definition: record.hpp:172
The class template that file records are based on; behaves like an std::tuple.
Definition: record.hpp:235
Type tag which indicates that no reference information has been passed to the alignment file on const...
Definition: sam_flag.hpp:23
The options type defines various option members that influence the behavior of all or some formats.
Definition: output_options.hpp:23
Type that contains multiple types.
Definition: type_list.hpp:29
T tie(T... args)
T tuple_size_v
Provides seqan3::tuple_like.
Provides traits for seqan3::type_list.
T visit(T... args)