48 #include <range/v3/algorithm/equal.hpp> 49 #include <range/v3/view/zip.hpp> 59 #include <seqan3/io/detail/record.hpp> 267 template <detail::fields_concept selected_field_
ids_ = fields<field::SEQ, field::ID, field::QUAL>,
268 detail::type_list_of_sequence_file_output_formats_concept val
id_formats_ =
269 type_list<sequence_file_format_fasta, sequence_file_format_fastq>,
270 ostream_concept<
char> stream_type_ = std::ofstream>
289 static_assert([] () constexpr
291 for (
field f : selected_field_ids::as_array)
292 if (!field_ids::contains(f))
296 "You selected a field that is not valid for sequence files, please refer to the documentation " 297 "of sequence_file_output::field_ids for the accepted values.");
299 static_assert([] () constexpr
305 "You may not select field::SEQ_QUAL and either of field::SEQ and field::QUAL at the same time.");
311 using value_type = void;
312 using reference = void;
313 using const_reference = void;
314 using size_type = void;
318 using iterator = detail::out_file_iterator<sequence_file_output>;
354 stream.open(_file_name, std::ios_base::out | std::ios::binary);
355 if (!stream.is_open())
359 detail::set_format(format, _file_name);
368 template <sequence_file_output_format_concept file_format>
370 file_format
const & SEQAN3_DOXYGEN_ONLY(format_tag),
372 stream{std::move(_stream)}, format{file_format{}}
374 static_assert(meta::in<valid_formats, file_format>::value,
375 "You selected a format that is not in the valid_formats of this file.");
472 template <
typename record_t>
475 requires { requires detail::is_type_specialisation_of_v<remove_cvref_t<record_t>,
record>; }
477 write_record(detail::get_or_ignore<field::SEQ>(r),
478 detail::get_or_ignore<field::ID>(r),
479 detail::get_or_ignore<field::QUAL>(r),
480 detail::get_or_ignore<field::SEQ_QUAL>(r));
519 template <
typename tuple_t>
524 write_record(detail::get_or_ignore<selected_field_ids::index_of(
field::SEQ)>(t),
525 detail::get_or_ignore<selected_field_ids::index_of(
field::ID)>(t),
526 detail::get_or_ignore<selected_field_ids::index_of(
field::QUAL)>(t),
527 detail::get_or_ignore<selected_field_ids::index_of(
field::SEQ_QUAL)>(t));
567 template <
typename arg_t,
typename ... arg_types>
605 template <std::ranges::InputRange rng_t>
609 for (
auto &&
record : range)
659 template <std::ranges::InputRange rng_t>
668 template <std::ranges::InputRange rng_t>
718 template <
typename typelist,
typename field_
ids>
721 write_columns(detail::range_wrap_ignore(detail::get_or_ignore<field::SEQ>(r)),
722 detail::range_wrap_ignore(detail::get_or_ignore<field::ID>(r)),
723 detail::range_wrap_ignore(detail::get_or_ignore<field::QUAL>(r)),
724 detail::range_wrap_ignore(detail::get_or_ignore<field::SEQ_QUAL>(r)));
764 template <
typename ... arg_types>
769 detail::range_wrap_ignore(detail::get_or_ignore<selected_field_ids::index_of(
field::SEQ)>(t)),
770 detail::range_wrap_ignore(detail::get_or_ignore<selected_field_ids::index_of(
field::ID)>(t)),
771 detail::range_wrap_ignore(detail::get_or_ignore<selected_field_ids::index_of(
field::QUAL)>(t)),
772 detail::range_wrap_ignore(detail::get_or_ignore<selected_field_ids::index_of(
field::SEQ_QUAL)>(t)));
791 std::string file_name;
797 using format_type = detail::transfer_template_args_onto_t<valid_formats, std::variant>;
802 template <
typename seq_t,
typename id_t,
typename qual_t,
typename seq_qual_t>
803 void write_record(seq_t && seq, id_t &&
id, qual_t && qual, seq_qual_t && seq_qual)
805 static_assert(detail::decays_to_ignore_v<seq_qual_t> ||
806 (detail::decays_to_ignore_v<seq_t> && detail::decays_to_ignore_v<qual_t>),
807 "You may not select field::SEQ_QUAL and either of field::SEQ and field::QUAL at the same time.");
809 assert(!format.valueless_by_exception());
810 std::visit([&] (
auto & f)
812 if constexpr (!detail::decays_to_ignore_v<seq_qual_t>)
816 seq_qual | view::convert<typename seq_qual_t::sequence_alphabet_type>,
818 seq_qual | view::convert<typename seq_qual_t::quality_alphabet_type>);
836 void write_columns(seqs_t && seqs,
839 seq_quals_t && seq_quals)
845 "At least one of the columns must not be set to std::ignore.");
850 "You may not select field::SEQ_QUAL and either of field::SEQ and field::QUAL at the same time.");
852 assert(!format.valueless_by_exception());
853 std::visit([&] (
auto & f)
857 auto zipped = ranges::view::zip(seq_quals, ids);
859 for (
auto && v : zipped)
868 auto zipped = ranges::view::zip(seqs, ids, quals);
870 for (
auto && v : zipped)
871 f.write(stream, options, std::get<0>(v), std::get<1>(v), std::get<2>(v));
884 template <ostream_concept<
char> stream_type,
885 sequence_file_output_format_concept file_format,
886 detail::fields_concept selected_field_
ids>
890 std::remove_reference_t<stream_type>>;
auto const convert
A view that converts each element in the input range (implicitly or via static_cast).
Definition: convert.hpp:89
std::ranges::default_sentinel sentinel
The type returned by end().
Definition: output.hpp:322
void push_back(record_t &&r) requires tuple_like_concept< record_t > &&requires
Write a seqan3::record to the file.
Definition: output.hpp:473
The "sequence", usually a range of nucleotides or amino acids.
A class for writing sequence files, e.g. FASTA, FASTQ ...
Definition: output.hpp:271
Provides exceptions used in the I/O module.
sequence_file_output & operator=(std::tuple< arg_types... > const &t)
Write columns (wrapped in a std::tuple) to the file.
Definition: output.hpp:765
The class template that file records are based on; behaves like an std::tuple.
Definition: record.hpp:208
Provides seqan3::type_list and auxiliary metafunctions.
sequence_file_output & operator=(record< typelist, field_ids > const &r)
Write columns (wrapped in a seqan3::record) to the file.
Definition: output.hpp:719
Whether a type behaves like a tuple.
sequence_file_output & operator=(rng_t &&range) requires tuple_like_concept< reference_t< rng_t >>
Write a range of records (or tuples) to the file.
Definition: output.hpp:606
detail::out_file_iterator< sequence_file_output > iterator
The iterator type of this view (an output iterator).
Definition: output.hpp:318
Provides seqan3::view::convert.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
The qualities, usually in phred-score notation.
Thrown if there is an unspecified filesystem or stream error while opening, e.g. permission problem...
Definition: exception.hpp:62
A class template that holds a choice of seqan3::field.
Definition: record.hpp:136
friend sequence_file_output & operator|(rng_t &&range, sequence_file_output &f) requires tuple_like_concept< reference_t< rng_t >>
Write a range of records (or tuples) to the file.
Definition: output.hpp:660
stream_type_ stream_type
The type of the underlying stream.
Definition: output.hpp:283
Sequence and qualities combined in one range.
Provides seqan3::sequence_file_output_options.
void const_iterator
The const iterator type is void, because files are not const-iterable.
Definition: output.hpp:320
Provides seqan3::tuple_like_concept.
Provides the seqan3::record template and the seqan3::field enum.
valid_formats_ valid_formats
A seqan3::type_list with the possible formats.
Definition: output.hpp:281
The identifier, usually a string.
sequence_file_output()=delete
Default constructor is explicitly deleted, you need to give a stream or file name.
void emplace_back(arg_t &&arg, arg_types &&... args)
Write a record to the file by passing individual fields.
Definition: output.hpp:568
Adaptations of concepts from the Ranges TS.
~sequence_file_output()=default
Destructor is defaulted.
void push_back(tuple_t &&t) requires tuple_like_concept< tuple_t >
Write a record in form of a std::tuple to the file.
Definition: output.hpp:520
std::ptrdiff_t difference_type
A signed integer type, usually std::ptrdiff_t.
Definition: output.hpp:316
sequence_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:369
iterator begin() noexcept
Returns an iterator to current position in the file.
Definition: output.hpp:417
sequence_file_output & operator=(sequence_file_output const &)=delete
Copy assignment is explicitly deleted, because you can't have multiple access to the same file...
This header includes C++17 filesystem support and imports it into namespace seqan3::filesystem (indep...
Provides various metafunctions on generic types.
Provides the seqan3::detail::out_file_iterator class template.
selected_field_ids_ selected_field_ids
A seqan3::fields list with the fields selected for the record.
Definition: output.hpp:279
sequence_file_output(filesystem::path const &_file_name, selected_field_ids const &fields_tag=selected_field_ids{})
Construct from filename.
Definition: output.hpp:350
meta::list< types... > type_list
Type that contains multiple types, an alias for meta::list.
Definition: type_list.hpp:54
The options type defines various option members that influence the behaviour of all or some formats...
Definition: output_options.hpp:48
sentinel end() noexcept
Returns a sentinel for comparison with iterator.
Definition: output.hpp:436
sequence_file_output_options options
The options are public and its members can be set directly.
Definition: output.hpp:778
field
An enumerator for the fields used in file formats.Some of the fields are shared between formats...
Definition: record.hpp:63
::ranges::default_sentinel default_sentinel
Alias for ranges::default_sentinel. Empty sentinel type for use with iterator types that know the bou...
Definition: ranges:215
friend sequence_file_output operator|(rng_t &&range, sequence_file_output &&f) requires tuple_like_concept< reference_t< rng_t >>
Definition: output.hpp:669