SeqAn3
alignment_trace_algorithms.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
42 #include <deque>
43 #include <vector>
44 
49 
50 namespace seqan3::detail
51 {
52 
60  template <typename trace_matrix_t>
62  requires matrix_concept<remove_cvref_t<trace_matrix_t>> &&
65 inline alignment_coordinate alignment_begin_coordinate(trace_matrix_t && matrix,
66  alignment_coordinate const end_coordinate)
67 {
68  constexpr auto D = trace_directions::diagonal;
69  constexpr auto L = trace_directions::left;
70  constexpr auto U = trace_directions::up;
71  size_t row = end_coordinate.seq2_pos + 1;
72  size_t col = end_coordinate.seq1_pos + 1;
73 
74  assert(row < matrix.rows());
75  assert(col < matrix.cols());
76 
77  while (true)
78  {
79  trace_directions dir = matrix.at(row, col);
80  if ((dir & L) == L)
81  {
82  col = std::max<size_t>(col, 1) - 1;
83  }
84  else if ((dir & U) == U)
85  {
86  row = std::max<size_t>(row, 1) - 1;
87  }
88  else if ((dir & D) == D)
89  {
90  row = std::max<size_t>(row, 1) - 1;
91  col = std::max<size_t>(col, 1) - 1;
92  }
93  else
94  {
95 #ifndef NDEBUG
96  if (!(row == 0 || col == 0))
97  throw std::logic_error{"Unknown seqan3::trace_direction in an inner cell of the trace matrix."};
98 #endif
99  break;
100  }
101  }
102 
103  return {std::max<size_t>(col, 1) - 1, std::max<size_t>(row, 1) - 1};
104 }
105 
121 template <
122  typename database_t,
123  typename query_t,
124  typename trace_matrix_t,
125  typename gapped_database_alphabet_t = gapped<value_type_t<database_t>>,
126  typename gapped_query_alphabet_t = gapped<value_type_t<query_t>>>
128  requires matrix_concept<remove_cvref_t<trace_matrix_t>> &&
129  std::Same<typename remove_cvref_t<trace_matrix_t>::entry_type, trace_directions>
131 inline std::pair<std::vector<gapped_database_alphabet_t>, std::vector<gapped_query_alphabet_t>>
132 alignment_trace(database_t && database,
133  query_t && query,
134  trace_matrix_t && matrix,
135  alignment_coordinate const end_coordinate)
136 {
137  constexpr auto N = trace_directions::none;
138  constexpr auto D = trace_directions::diagonal;
139  constexpr auto L = trace_directions::left;
140  constexpr auto U = trace_directions::up;
141  size_t col = end_coordinate.seq1_pos + 1;
142  size_t row = end_coordinate.seq2_pos + 1;
143 
144  assert(row <= query.size());
145  assert(col <= database.size());
146  assert(row < matrix.rows());
147  assert(col < matrix.cols());
148 
149  std::deque<gapped_database_alphabet_t> gapped_database{};
150  std::deque<gapped_query_alphabet_t> gapped_query{};
151 
152  if (matrix.at(0, 0) != N)
153  throw std::logic_error{"End trace must be NONE"};
154 
155  while (true)
156  {
157  trace_directions dir = matrix.at(row, col);
158  if ((dir & L) == L)
159  {
160  col = std::max<size_t>(col, 1) - 1;
161  gapped_database.push_front(database[col]);
162  gapped_query.push_front(gap::GAP);
163  }
164  else if ((dir & U) == U)
165  {
166  row = std::max<size_t>(row, 1) - 1;
167  gapped_database.push_front(gap::GAP);
168  gapped_query.push_front(query[row]);
169  }
170  else if ((dir & D) == D)
171  {
172  row = std::max<size_t>(row, 1) - 1;
173  col = std::max<size_t>(col, 1) - 1;
174  gapped_database.push_front(database[col]);
175  gapped_query.push_front(query[row]);
176  }
177  else
178  {
179 #ifndef NDEBUG
180  if (!(row == 0 || col == 0))
181  throw std::logic_error{"Unknown seqan3::trace_direction in an inner cell of the trace matrix."};
182 #endif
183  break;
184  }
185  }
186 
187  return
188  {
189  {std::begin(gapped_database), std::end(gapped_database)},
190  {std::begin(gapped_query), std::end(gapped_query)}
191  };
192 }
193 
194 } // namespace seqan3::detail
Contains seqan3::gapped.
Contains the declaration of seqan3::detail::alignment_trace_matrix.
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
Definition: aligned_sequence_concept.hpp:288
Provides seqan3::detail::alignment_coordinate.
Provides various metafunctions used by the range module.