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