SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
policy_alignment_matrix.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <tuple>
16 
22 
23 namespace seqan3::detail
24 {
25 
40 template <typename traits_t, typename alignment_matrix_t>
41  requires (is_type_specialisation_of_v<traits_t, alignment_configuration_traits> &&
42  requires (alignment_matrix_t & matrix, typename traits_t::score_type const initial_score)
43  {
44  { matrix.resize(column_index_type{size_t{}}, row_index_type{size_t{}}, initial_score) };
45  })
46 class policy_alignment_matrix
47 {
48 protected:
50  using score_type = typename traits_t::score_type;
52  using matrix_index_type = typename traits_t::matrix_index_type;
53 
55  int32_t lower_diagonal{};
57  int32_t upper_diagonal{};
59  bool last_column_is_free{};
61  bool last_row_is_free{};
62 
66  policy_alignment_matrix() = default;
67  policy_alignment_matrix(policy_alignment_matrix const &) = default;
68  policy_alignment_matrix(policy_alignment_matrix &&) = default;
69  policy_alignment_matrix & operator=(policy_alignment_matrix const &) = default;
70  policy_alignment_matrix & operator=(policy_alignment_matrix &&) = default;
71  ~policy_alignment_matrix() = default;
72 
86  template <typename alignment_configuration_t>
87  requires (is_type_specialisation_of_v<alignment_configuration_t, configuration>)
88  policy_alignment_matrix(alignment_configuration_t const & config)
89  {
90  using seqan3::get;
91 
92  auto band = config.get_or(seqan3::align_cfg::band_fixed_size{});
93 
94  lower_diagonal = band.lower_diagonal;
95  upper_diagonal = band.upper_diagonal;
96 
97  bool invalid_band = upper_diagonal < lower_diagonal;
98  std::string error_cause = (invalid_band) ? " The upper diagonal is smaller than the lower diagonal." : "";
99 
100  if constexpr (traits_t::is_global)
101  {
102  auto method_global_config = get<seqan3::align_cfg::method_global>(config);
103 
104  bool first_row_is_free = method_global_config.free_end_gaps_sequence1_leading;
105  bool first_column_is_free = method_global_config.free_end_gaps_sequence2_leading;
106 
107  last_row_is_free = method_global_config.free_end_gaps_sequence1_trailing;
108  last_column_is_free = method_global_config.free_end_gaps_sequence2_trailing;
109  // band starts in first column without free gaps or band starts in first row without free gaps.
110  invalid_band |= (upper_diagonal < 0 && !first_column_is_free) || (lower_diagonal > 0 && !first_row_is_free);
111  error_cause += " The band starts in a region without free gaps.";
112  }
113 
114  if (invalid_band)
115  throw invalid_alignment_configuration{"The selected band [" + std::to_string(lower_diagonal) + ":"
116  + std::to_string(upper_diagonal)
117  + "] cannot be used with the current "
118  "alignment configuration:"
119  + error_cause};
120  }
122 
145  auto acquire_matrices(size_t const sequence1_size,
146  size_t const sequence2_size,
147  score_type initial_score = score_type{}) const
148  {
149  assert(sequence1_size < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()));
150  assert(sequence2_size < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()));
151 
152  if constexpr (traits_t::is_banded)
153  check_valid_band_configuration(sequence1_size, sequence2_size);
154 
155  static thread_local alignment_matrix_t alignment_matrix{};
156  static thread_local coordinate_matrix<matrix_index_type> index_matrix{};
157 
158  // Increase dimension by one for the initialisation of the matrix.
159  size_t const column_count = sequence1_size + 1;
160  size_t row_count = sequence2_size + 1;
161 
162  index_matrix.resize(column_index_type{column_count}, row_index_type{row_count});
163 
164  if constexpr (traits_t::is_banded)
165  {
166  assert(upper_diagonal - lower_diagonal + 1 > 0); // Band size is a positive integer.
167  // Allocate one more cell to compute the last cell of the band with standard recursion function.
168  row_count = std::min<int64_t>(upper_diagonal - lower_diagonal + 2, row_count);
169  }
170 
171  alignment_matrix.resize(column_index_type{column_count}, row_index_type{row_count}, initial_score);
172 
173  return std::tie(alignment_matrix, index_matrix);
174  }
175 
184  void check_valid_band_configuration(size_t const sequence1_size, size_t const sequence2_size) const
185  {
186  bool const upper_diagonal_ends_before_last_cell = (upper_diagonal + sequence2_size) < sequence1_size;
187  bool const lower_diagonal_ends_behind_last_cell = (-lower_diagonal + sequence1_size) < sequence2_size;
188 
189  bool invalid_band = false;
190  std::string error_cause{};
191 
192  if constexpr (traits_t::is_global)
193  {
194  // band ends in last column without free gaps or band ends in last row without free gaps.
195  invalid_band |= (lower_diagonal_ends_behind_last_cell && !last_column_is_free)
196  || (upper_diagonal_ends_before_last_cell && !last_row_is_free);
197  error_cause = "The band ends in a region without free gaps.";
198  }
199 
200  if (invalid_band)
201  throw invalid_alignment_configuration{"The selected band [" + std::to_string(lower_diagonal) + ":"
202  + std::to_string(upper_diagonal)
203  + "] cannot be used with the current "
204  "alignment configuration: "
205  + error_cause};
206  }
207 };
208 } // namespace seqan3::detail
Includes customized exception types for the alignment module .
Provides helper type traits for the configuration and execution of the alignment algorithm.
Configuration element for setting a fixed size band.
Definition: align_config_band.hpp:63
Provides seqan3::configuration and utility functions.
Provides seqan3::detail::coordinate_matrix.
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:415
Provides type traits for working with templates.
T tie(T... args)
T to_string(T... args)