SeqAn3 3.2.0
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
23namespace seqan3::detail
24{
25
40template <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 })
46class policy_alignment_matrix
47{
48protected:
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.
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)