56 template <Matrix matrix_t,
typename first_sequence_t = std::nullopt_t,
typename second_sequence_t = std::nullopt_t>
61 static constexpr
bool has_first_sequence = !std::is_same_v<std::decay_t<first_sequence_t>,
std::nullopt_t>;
63 static constexpr
bool has_second_sequence = !std::is_same_v<std::decay_t<second_sequence_t>,
std::nullopt_t>;
67 static constexpr
bool is_traceback_matrix = std::is_same_v<std::decay_t<entry_t>, trace_directions>;
70 static constexpr
bool is_optional_score = is_type_specialisation_of_v<entry_t, std::optional>;
80 debug_matrix() =
default;
81 debug_matrix(debug_matrix
const &) =
default;
82 debug_matrix(debug_matrix &&) =
default;
83 debug_matrix & operator=(debug_matrix
const &) =
default;
84 debug_matrix & operator=(debug_matrix &&) =
default;
85 ~debug_matrix() =
default;
90 debug_matrix(matrix_t matrix)
99 debug_matrix(matrix_t matrix, first_sequence_t first_sequence, second_sequence_t second_sequence)
100 : _matrix{std::forward<matrix_t>(matrix)},
101 _first_sequence{std::forward<first_sequence_t>(first_sequence)},
102 _second_sequence{std::forward<second_sequence_t>(second_sequence)}
104 if constexpr(has_first_sequence)
106 assert(_matrix.cols() <= _first_sequence.size() + 1u);
109 if constexpr(has_second_sequence)
111 assert(_matrix.rows() <= _second_sequence.size() + 1u);
117 size_t rows() const noexcept
120 return _rows.value_or(_matrix.rows());
122 return _cols.value_or(_matrix.cols());
126 size_t cols() const noexcept
129 return _cols.value_or(_matrix.cols());
131 return _rows.value_or(_matrix.rows());
135 first_sequence_t
const & first_sequence() const noexcept
138 return _first_sequence;
140 return _second_sequence;
144 second_sequence_t
const & second_sequence() const noexcept
147 return _second_sequence;
149 return _first_sequence;
153 entry_type at(
size_t const row,
size_t const col)
const noexcept
155 assert(row < rows() && col < cols());
157 size_t const _row = !_transpose ? row : col;
158 size_t const _col = !_transpose ? col : row;
160 if (!_masking_matrix.has_value() || _masking_matrix.value().at(_row, _col))
162 entry_t
const & entry = _matrix.at(_row, _col);
164 if (!is_traceback_matrix || !_transpose)
167 if constexpr(is_traceback_matrix)
170 if ((entry & trace_directions::left) == trace_directions::left)
171 reverse |= trace_directions::up;
172 if ((entry & trace_directions::up) == trace_directions::up)
173 reverse |= trace_directions::left;
174 if ((entry & trace_directions::diagonal) == trace_directions::diagonal)
175 reverse |= trace_directions::diagonal;
180 if constexpr(is_traceback_matrix)
181 return trace_directions::none;
192 debug_matrix & mask_matrix(row_wise_matrix<bool> masking_matrix) noexcept
194 _masking_matrix = masking_matrix;
204 return mask_matrix(row_wise_matrix<bool>{masking_vector, rows(), cols()});
212 debug_matrix & sub_matrix(
size_t const new_rows,
size_t const new_cols) noexcept
214 assert(new_rows <= _matrix.rows());
215 assert(new_cols <= _matrix.cols());
224 debug_matrix & transpose_matrix() noexcept
226 _transpose = !_transpose;
245 template <
typename ostream_t>
246 void print(ostream_t & cout,
fmtflags2 const flags)
const noexcept
249 size_t const column_width = this->column_width.has_value() ?
250 this->column_width.value() : auto_column_width(flags);
252 auto char_first_sequence = [&]([[maybe_unused]]
size_t const i) ->
std::string 254 if constexpr(!has_first_sequence)
257 return as_string(first_sequence()[i], flags);
260 auto char_second_sequence = [&]([[maybe_unused]]
size_t const i) ->
std::string 262 if constexpr(!has_second_sequence)
265 return as_string(second_sequence()[i], flags);
271 size_t const length_bytes = symbol.size();
272 size_t const length = unicode_str_length(symbol);
273 size_t const offset = length_bytes - length;
281 auto print_first_cell = [&](
std::string const & symbol)
283 cout << symbol << symbols.col_sep;
287 auto print_first_row = [&]
289 print_first_cell(
" ");
290 print_cell(symbols.epsilon);
292 for (
size_t col = 0; col < cols() - 1; ++col)
293 print_cell(char_first_sequence(col));
299 auto print_divider = [&]
301 cout <<
" " << symbols.row_col_sep;
302 for (
size_t col = 0; col < cols(); ++col)
304 for (
size_t i = 0; i < column_width; ++i)
305 cout << symbols.row_sep;
307 cout << symbols.row_col_sep;
313 for (
size_t row = 0; row < rows(); ++row)
315 if (symbols.row_sep[0] !=
'\0')
320 print_first_cell(symbols.epsilon);
322 print_first_cell(char_second_sequence(row - 1));
324 for (
size_t col = 0; col < cols(); ++col)
325 print_cell(entry_at(row, col, flags));
332 size_t auto_column_width(
fmtflags2 const flags)
const noexcept
334 size_t col_width = 1;
335 for (
size_t row = 0; row < rows(); ++row)
336 for (
size_t col = 0; col < cols(); ++col)
337 col_width =
std::max(col_width, unicode_str_length(entry_at(row, col, flags)));
348 entry_type
const & entry = at(row, col);
349 if (!is_traceback_matrix && entry == matrix_inf<entry_type>)
352 return as_string(entry, flags);
356 template <
typename entry_type>
360 debug_stream_type stream{strstream};
361 stream << flags << entry;
362 return strstream.
str();
367 static size_t unicode_str_length(
std::string const & str) noexcept
370 for (
auto it = str.cbegin(); it < str.cend(); ++it, ++length)
373 if ((v & 0b11100000) == 0b11000000)
375 else if ((v & 0b11110000) == 0b11100000)
377 else if ((v & 0b11111000) == 0b11110000)
387 char const * epsilon{};
389 char const * col_sep{};
391 char const * row_sep{};
393 char const * row_col_sep{};
399 static constexpr format_type csv{
" ",
";",
"",
"",
""};
401 static constexpr format_type unicode{
"ε",
"║",
"═",
"╬",
"∞"};
411 first_sequence_t _first_sequence;
413 second_sequence_t _second_sequence;
428 template <Matrix matrix_t>
430 debug_matrix(matrix_t &&)
431 -> debug_matrix<matrix_t>;
435 template <Matrix matrix_t,
typename first_sequence_t,
typename second_sequence_t>
436 debug_matrix(matrix_t &&, first_sequence_t &&, second_sequence_t &&)
437 -> debug_matrix<matrix_t, first_sequence_t, second_sequence_t>;
454 template <detail::Matrix alignment_matrix_t>
457 detail::debug_matrix debug{std::forward<alignment_matrix_t>(matrix)};
460 debug.print(sstream, s.
flags2());
Provides seqan3::detail::row_wise_matrix.
debug_stream_type & operator<<(debug_stream_type &s, alignment_matrix_t &&matrix)
An alignment matrix can be printed to the seqan3::debug_stream.
Definition: debug_matrix.hpp:455
Enables use of non-ASCII UTF8 characters in formatted output.
Definition: debug_stream.hpp:40
constexpr auto reverse
A range adaptor that presents the underlying range in reverse order.
Definition: ranges:721
SeqAn specific customisations in the standard namespace.
The main SeqAn3 namespace.
fmtflags2 flags2() const
Retrieve the format flags from the stream.
Definition: debug_stream.hpp:203
Provides the declaration of seqan3::detail::trace_directions.
fmtflags2
Flags that change the behaviour of the seqan3::debug_stream.
Definition: debug_stream.hpp:37
Definition: aligned_sequence_concept.hpp:35
A "pretty printer" for most SeqAn data structures and related types.
Definition: debug_stream.hpp:78
Provides seqan3::detail::Matrix.
Provides seqan3::debug_stream and related types.