SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
alignment_trace_algorithms.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 <deque>
16 #include <vector>
17 
25 
26 namespace seqan3::detail
27 {
28 
36  template <typename trace_matrix_t>
38  requires matrix<remove_cvref_t<trace_matrix_t>> &&
41 inline alignment_coordinate alignment_front_coordinate(trace_matrix_t && matrix,
42  alignment_coordinate const back_coordinate)
43 {
44  constexpr auto D = trace_directions::diagonal;
45  constexpr auto L = trace_directions::left;
46  constexpr auto U = trace_directions::up;
47 
48  matrix_coordinate coordinate{row_index_type{back_coordinate.second}, column_index_type{back_coordinate.first}};
49 
50  assert(coordinate.row < matrix.rows());
51  assert(coordinate.col < matrix.cols());
52 
53  while (true)
54  {
55  trace_directions dir = matrix.at(coordinate);
56  if ((dir & L) == L)
57  {
58  coordinate.col = std::max<size_t>(coordinate.col, 1) - 1;
59  }
60  else if ((dir & U) == U)
61  {
62  coordinate.row = std::max<size_t>(coordinate.row, 1) - 1;
63  }
64  else if ((dir & D) == D)
65  {
66  coordinate.row = std::max<size_t>(coordinate.row, 1) - 1;
67  coordinate.col = std::max<size_t>(coordinate.col, 1) - 1;
68  }
69  else
70  {
71 #ifndef NDEBUG
72  if (!(coordinate.row == 0 || coordinate.col == 0))
73  throw std::logic_error{"Unknown seqan3::trace_direction in an inner cell of the trace matrix."};
74 #endif
75  break;
76  }
77  }
78 
79  return {column_index_type{coordinate.col}, row_index_type{coordinate.row}};
80 }
81 
95 template <
96  tuple_like alignment_t,
97  typename database_t,
98  typename query_t,
99  typename trace_matrix_t>
101  requires matrix<remove_cvref_t<trace_matrix_t>> &&
103  detail::all_satisfy_aligned_seq<detail::tuple_type_list_t<alignment_t>>
105 inline alignment_t alignment_trace(database_t && database,
106  query_t && query,
107  trace_matrix_t && matrix,
108  alignment_coordinate const back_coordinate,
109  alignment_coordinate const front_coordinate)
110 {
111  constexpr auto N = trace_directions::none;
112  constexpr auto D = trace_directions::diagonal;
113  constexpr auto L = trace_directions::left;
114  constexpr auto U = trace_directions::up;
115 
116  matrix_coordinate coordinate{row_index_type{back_coordinate.second}, column_index_type{back_coordinate.first}};
117 
118  assert(coordinate.row <= query.size());
119  assert(coordinate.col <= database.size());
120  assert(coordinate.row < matrix.rows());
121  assert(coordinate.col < matrix.cols());
122 
123  alignment_t aligned_seq{};
124  assign_unaligned(std::get<0>(aligned_seq), views::slice(database, front_coordinate.first, coordinate.col));
125  assign_unaligned(std::get<1>(aligned_seq), views::slice(query, front_coordinate.second, coordinate.row));
126  auto end_aligned_db = std::ranges::cend(std::get<0>(aligned_seq));
127  auto end_aligned_qy = std::ranges::cend(std::get<1>(aligned_seq));
128 
129  if (matrix.at({row_index_type{0u}, column_index_type{0u}}) != N)
130  throw std::logic_error{"End trace must be NONE"};
131 
132  while (true)
133  {
134  trace_directions dir = matrix.at(coordinate);
135  if ((dir & L) == L)
136  {
137  coordinate.col = std::max<size_t>(coordinate.col, 1) - 1;
138  --end_aligned_db;
139  end_aligned_qy = insert_gap(std::get<1>(aligned_seq), end_aligned_qy);
140  }
141  else if ((dir & U) == U)
142  {
143  coordinate.row = std::max<size_t>(coordinate.row, 1) - 1;
144  end_aligned_db = insert_gap(std::get<0>(aligned_seq), end_aligned_db);
145  --end_aligned_qy;
146  }
147  else if ((dir & D) == D)
148  {
149  coordinate.row = std::max<size_t>(coordinate.row, 1) - 1;
150  coordinate.col = std::max<size_t>(coordinate.col, 1) - 1;
151  --end_aligned_db;
152  --end_aligned_qy;
153  }
154  else
155  {
156 #ifndef NDEBUG
157  if (!(coordinate.row == 0 || coordinate.col == 0))
158  throw std::logic_error{"Unknown seqan3::trace_direction in an inner cell of the trace matrix."};
159 #endif
160  break;
161  }
162  }
163 
164  return aligned_seq;
165 }
166 
167 } // namespace seqan3::detail
matrix_concept.hpp
Provides seqan3::detail::matrix.
seqan3::insert_gap
aligned_seq_t::iterator insert_gap(aligned_seq_t &aligned_seq, typename aligned_seq_t::const_iterator pos_it)
An implementation of seqan3::aligned_sequence::insert_gap for sequence containers.
Definition: aligned_sequence_concept.hpp:248
vector
trace_directions.hpp
Provides the declaration of seqan3::detail::trace_directions.
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
slice.hpp
Provides seqan3::views::slice.
gapped.hpp
Provides seqan3::gapped.
range.hpp
Provides various transformation traits used by the range module.
deque
std::logic_error
tuple_like
Whether a type behaves like a tuple.
aligned_sequence_concept.hpp
Includes the aligned_sequence and the related insert_gap and erase_gap functions to enable stl contai...
seqan3::alignment_coordinate::second
size_t second
The begin/end position of the alignment in the second sequence.
Definition: alignment_coordinate.hpp:379
seqan3::views::slice
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:141
alignment_coordinate.hpp
Provides seqan3::detail::alignment_coordinate.
seqan3::assign_unaligned
void assign_unaligned(aligned_seq_t &aligned_seq, unaligned_sequence_type &&unaligned_seq)
An implementation of seqan3::aligned_sequence::assign_unaligned_sequence for sequence containers.
Definition: aligned_sequence_concept.hpp:375