SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
debug_stream_alignment.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 <iomanip>
16 #include <tuple>
17 
18 #include <range/v3/algorithm/for_each.hpp>
19 
26 
27 namespace seqan3::detail
28 {
29 
37 template <typename char_t, tuple_like alignment_t, size_t ...idx>
38 void stream_alignment(debug_stream_type<char_t> & stream, alignment_t const & align, std::index_sequence<idx...> const & )
39 {
40  using std::get;
41  size_t const alignment_size = get<0>(align).size();
42 
43  // split alignment into blocks of length 50 and loop over parts
44  for (size_t begin_pos = 0; begin_pos < alignment_size; begin_pos += 50)
45  {
46  size_t const end_pos = std::min(begin_pos + 50, alignment_size);
47 
48  // write header line
49  if (begin_pos != 0)
50  stream << '\n';
51 
52  stream << std::setw(7) << begin_pos << ' ';
53  for (size_t pos = begin_pos + 1; pos <= end_pos; ++pos)
54  {
55  if (pos % 10 == 0)
56  stream << ':';
57  else if (pos % 5 == 0)
58  stream << '.';
59  else
60  stream << ' ';
61  }
62 
63  // write first sequence
64  stream << '\n' << std::setw(8) << "";
65  std::ranges::for_each(get<0>(align) | views::slice(begin_pos, end_pos) | views::to_char,
66  [&stream] (char ch) { stream << ch; });
67 
68  auto stream_f = [&] (auto const & previous_seq, auto const & aligned_seq)
69  {
70  // write alignment bars
71  stream << '\n' << std::setw(8) << "";
72  std::ranges::for_each(views::zip(previous_seq, aligned_seq) | views::slice(begin_pos, end_pos),
73  [&stream] (auto && ch) { stream << (get<0>(ch) == get<1>(ch) ? '|' : ' '); });
74 
75  // write next sequence
76  stream << '\n' << std::setw(8) << "";
77  std::ranges::for_each(aligned_seq | views::slice(begin_pos, end_pos) | views::to_char,
78  [&stream] (char ch) { stream << ch; });
79  };
80  (stream_f(get<idx>(align), get<idx + 1>(align)), ...);
81  stream << '\n';
82  }
83 }
84 } // namespace seqan3::detail
85 
86 namespace seqan3
87 {
98 template <typename char_t, typename alignment_t>
100  requires (detail::debug_streamable_tuple<alignment_t> &&
101  detail::all_model_aligned_seq<detail::tuple_type_list_t<std::remove_cvref_t<alignment_t>>>)
103 inline debug_stream_type<char_t> & operator<<(debug_stream_type<char_t> & stream, alignment_t && alignment)
104 {
105  constexpr size_t sequence_count = std::tuple_size_v<std::remove_cvref_t<alignment_t>>;
106 
107  static_assert(sequence_count >= 2, "An alignment requires at least two sequences.");
108 
109  detail::stream_alignment(stream, alignment, std::make_index_sequence<sequence_count - 1>{});
110  return stream;
111 }
112 
113 } // namespace seqan
zip.hpp
Provides seqan3::views::zip.
tuple.hpp
Provides seqan3::tuple_like.
std::index_sequence
tuple
seqan3::views::get
auto const get
A view calling std::get on each element in a range.
Definition: get.hpp:65
seqan3::debug_stream_type
A "pretty printer" for most SeqAn data structures and related types.
Definition: debug_stream_type.hpp:71
slice.hpp
Provides seqan3::views::slice.
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
tuple_like
Whether a type behaves like a tuple.
std::min
T min(T... args)
aligned_sequence_concept.hpp
Includes the aligned_sequence and the related insert_gap and erase_gap functions to enable stl contai...
debug_stream_tuple.hpp
Provides seqan3::debug_stream and related types.
to_char.hpp
Provides seqan3::views::to_char.
iomanip
seqan3::views::to_char
auto const to_char
A view that calls seqan3::to_char() on each element in the input range.
Definition: to_char.hpp:65
seqan3::views::slice
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:141
std::remove_cvref_t
std::setw
T setw(T... args)