23 namespace seqan3::detail
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)
45 { matrix.resize(column_index_type{
size_t{}}, row_index_type{
size_t{}}, initial_score) };
48 class policy_alignment_matrix
52 using score_type =
typename traits_t::score_type;
54 using matrix_index_type =
typename traits_t::matrix_index_type;
57 int32_t lower_diagonal{};
59 int32_t upper_diagonal{};
61 bool last_column_is_free{};
63 bool last_row_is_free{};
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;
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)
98 lower_diagonal = band.lower_diagonal;
99 upper_diagonal = band.upper_diagonal;
101 bool invalid_band = upper_diagonal < lower_diagonal;
102 std::string error_cause = (invalid_band) ?
" The upper diagonal is smaller than the lower diagonal." :
"";
104 if constexpr (traits_t::is_global)
106 auto method_global_config = get<seqan3::align_cfg::method_global>(config);
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;
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;
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.";
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};
147 auto acquire_matrices(
size_t const sequence1_size,
148 size_t const sequence2_size,
149 score_type initial_score = score_type{})
const
154 if constexpr (traits_t::is_banded)
155 check_valid_band_configuration(sequence1_size, sequence2_size);
157 static thread_local alignment_matrix_t alignment_matrix{};
158 static thread_local coordinate_matrix<matrix_index_type> index_matrix{};
161 size_t const column_count = sequence1_size + 1;
162 size_t row_count = sequence2_size + 1;
164 index_matrix.resize(column_index_type{column_count}, row_index_type{row_count});
166 if constexpr (traits_t::is_banded)
168 assert(upper_diagonal - lower_diagonal + 1 > 0);
170 row_count = std::min<int64_t>(upper_diagonal - lower_diagonal + 2, row_count);
173 alignment_matrix.resize(column_index_type{column_count}, row_index_type{row_count}, initial_score);
175 return std::tie(alignment_matrix, index_matrix);
186 void check_valid_band_configuration(
size_t const sequence1_size,
size_t const sequence2_size)
const
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;
191 bool invalid_band =
false;
194 if constexpr (traits_t::is_global)
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.";
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};