21 #include <seqan3/alignment/pairwise/policy/all.hpp> 37 template <
typename value_t>
38 SEQAN3_CONCEPT AlignPairwiseValue =
40 std::tuple_size_v<value_t> == 2 &&
48 template <
typename value_t>
49 SEQAN3_CONCEPT AlignPairwiseSingleInput =
50 AlignPairwiseValue<value_t> &&
68 template <
typename range_t>
69 SEQAN3_CONCEPT AlignPairwiseRangeInputConcept =
71 AlignPairwiseValue<value_type_t<range_t>> &&
84 template <
typename range_type,
85 typename alignment_config_type>
86 struct alignment_contract
95 using first_seq_t = std::tuple_element_t<0, value_type_t<std::ranges::iterator_t<unref_range_type>>>;
97 using second_seq_t = std::tuple_element_t<1, value_type_t<std::ranges::iterator_t<unref_range_type>>>;
102 constexpr
static bool expects_tuple_like_value_type()
104 return TupleLike<alignment_config_type> &&
105 std::tuple_size_v<value_type_t<std::ranges::iterator_t<unref_range_type>>> == 2;
109 constexpr
static bool expects_valid_scoring_scheme()
111 if constexpr (alignment_config_type::template exists<align_cfg::scoring>())
114 decltype(get<align_cfg::scoring>(std::declval<alignment_config_type>()).value)
116 return static_cast<bool>(ScoringScheme<scoring_type,
117 value_type_t<first_seq_t>,
118 value_type_t<second_seq_t>>);
127 constexpr
static bool expects_alignment_configuration()
129 return alignment_config_type::template exists<align_cfg::mode>();
137 struct alignment_configurator
145 template <
typename config_type,
typename score_allocator_t,
typename trace_allocator_t>
146 struct select_matrix_policy
151 template <
typename config_t>
152 static constexpr
auto select() noexcept
155 if constexpr (std::is_same_v<typename trace_allocator_t::value_type, ignore_t>)
157 if constexpr (config_t::template exists<align_cfg::band>())
158 return deferred_crtp_base<banded_score_dp_matrix_policy, score_allocator_t>{};
160 return deferred_crtp_base<unbanded_score_dp_matrix_policy, score_allocator_t>{};
164 if constexpr (config_t::template exists<align_cfg::band>())
166 return deferred_crtp_base<banded_score_trace_dp_matrix_policy,
168 trace_allocator_t>{};
172 return deferred_crtp_base<unbanded_score_trace_dp_matrix_policy,
174 trace_allocator_t>{};
181 using type = decltype(select<config_type>());
188 template <
typename config_type,
typename ... trait_types>
189 struct select_gap_policy
194 template <
typename config_t>
195 static constexpr
auto select() noexcept
197 if constexpr (config_t::template exists<align_cfg::band>())
198 return deferred_crtp_base<affine_gap_banded_policy, trait_types...>{};
200 return deferred_crtp_base<affine_gap_policy, trait_types...>{};
205 using type = decltype(select<config_type>());
212 template <
typename config_type,
typename ... trait_types>
213 struct select_gap_init_policy
218 template <
typename config_t>
219 static constexpr
auto select() noexcept
221 if constexpr (config_t::template exists<align_cfg::band>())
222 return deferred_crtp_base<affine_gap_banded_init_policy, trait_types...>{};
224 return deferred_crtp_base<affine_gap_init_policy, trait_types...>{};
229 using type = decltype(select<config_type>());
252 template <AlignPairwiseRangeInputConcept sequences_t,
typename config_t>
254 requires is_type_specialisation_of_v<config_t, configuration>
256 static constexpr
auto configure(config_t
const & cfg)
259 if constexpr (!config_t::template exists<align_cfg::result>())
265 return configure<sequences_t>(cfg | align_cfg::result{with_score});
273 using first_seq_t = std::tuple_element_t<0, value_type_t<sequences_t>>;
274 using second_seq_t = std::tuple_element_t<1, value_type_t<sequences_t>>;
276 using wrapped_first_t = all_view<first_seq_t &>;
277 using wrapped_second_t = all_view<second_seq_t &>;
280 using result_t = alignment_result<typename align_result_selector<std::remove_reference_t<wrapped_first_t>,
292 using alignment_contract_t = alignment_contract<sequences_t, config_t>;
294 static_assert(alignment_contract_t::expects_alignment_configuration(),
295 "Alignment configuration error: " 296 "The alignment can only be configured with alignment configurations.");
298 static_assert(alignment_contract_t::expects_tuple_like_value_type(),
299 "Alignment configuration error: " 300 "The value type of the sequence ranges must model the seqan3::TupleLike " 301 "and must contain exactly 2 elements.");
303 static_assert(alignment_contract_t::expects_valid_scoring_scheme(),
304 "Alignment configuration error: " 305 "Either the scoring scheme was not configured or the given scoring scheme cannot be invoked with " 306 "the value types of the passed sequences.");
313 auto const & gaps = cfg.template value_or<align_cfg::gap>(gap_scheme{gap_score{-1}});
314 auto const & scoring_scheme = get<align_cfg::scoring>(cfg).value;
315 auto align_ends_cfg = cfg.template value_or<align_cfg::aligned_ends>(free_ends_none);
317 if constexpr (config_t::template exists<align_cfg::mode<detail::global_alignment_type>>())
320 if (gaps.get_gap_open_score() == 0 &&
321 !(align_ends_cfg[2] || align_ends_cfg[3]) &&
322 align_ends_cfg[0] == align_ends_cfg[1])
326 if constexpr (is_type_specialisation_of_v<
remove_cvref_t<decltype(scoring_scheme)>,
327 nucleotide_scoring_scheme>)
329 if ((scoring_scheme.score(
'A'_dna15,
'A'_dna15) == 0) &&
330 (scoring_scheme.score(
'A'_dna15,
'C'_dna15)) == -1)
331 return configure_edit_distance<function_wrapper_t>(cfg);
341 if (config_t::template exists<align_cfg::max_error>())
342 throw invalid_alignment_configuration{
"The align_cfg::max_error configuration is only allowed for " 343 "the specific edit distance computation."};
345 return configure_free_ends_initialisation<function_wrapper_t>(cfg);
356 template <
typename function_wrapper_t,
typename config_t>
357 static constexpr function_wrapper_t configure_edit_distance(config_t
const & cfg)
363 if constexpr (config_t::template exists<align_cfg::band>())
364 throw invalid_alignment_configuration{
"Banded alignments are yet not supported."};
371 auto align_ends_cfg = cfg.template value_or<align_cfg::aligned_ends>(free_ends_none);
372 using align_ends_cfg_t = remove_cvref_t<decltype(align_ends_cfg)>;
374 auto configure_edit_traits = [&] (
auto is_semi_global)
376 struct edit_traits_type
378 using is_semi_global_type [[maybe_unused]] = remove_cvref_t<decltype(is_semi_global)>;
381 edit_distance_algorithm<remove_cvref_t<config_t>, edit_traits_type> algorithm{cfg};
382 return function_wrapper_t{std::move(algorithm)};
386 auto has_free_ends_trailing = [&] (
auto first) constexpr
388 if constexpr (!decltype(first)::value)
392 else if constexpr (align_ends_cfg_t::template is_static<1>())
394 #if defined(__GNUC__) && __GNUC__ >= 9 395 constexpr
bool free_ends_trailing = align_ends_cfg_t::template get_static<1>();
397 #else // ^^^ workaround / no workaround vvv 399 #endif // defined(__GNUC__) && __GNUC__ >= 9 403 if (align_ends_cfg[1])
412 if constexpr (align_ends_cfg_t::template is_static<0>())
413 return has_free_ends_trailing(
std::integral_constant<
bool, align_ends_cfg_t::template get_static<0>()>{});
416 if (align_ends_cfg[0])
434 template <
typename function_wrapper_t,
typename config_t>
435 static constexpr function_wrapper_t configure_free_ends_initialisation(config_t
const & cfg);
449 template <
typename function_wrapper_t,
typename ...policies_t,
typename config_t>
450 static constexpr function_wrapper_t configure_free_ends_optimum_search(config_t
const & cfg);
455 template <
typename config_t>
456 struct configure_trace_type
461 config_t::template exists<align_cfg::result<with_front_coordinate_type>>(),
471 template <
typename function_wrapper_t,
typename config_t>
472 constexpr function_wrapper_t alignment_configurator::configure_free_ends_initialisation(config_t
const & cfg)
478 using score_type = int32_t;
479 using trace_type =
typename configure_trace_type<config_t>::type;
486 using dp_matrix_t =
typename select_matrix_policy<config_t,
495 using affine_t =
typename select_gap_policy<config_t, cell_type, local_t>::type;
502 auto align_ends_cfg = cfg.template value_or<align_cfg::aligned_ends>(free_ends_none);
503 using align_ends_cfg_t = decltype(align_ends_cfg);
507 auto configure_leading_both = [&] (
auto first_seq,
auto second_seq) constexpr
510 struct policy_trait_type
512 using free_first_leading_t [[maybe_unused]] = decltype(first_seq);
513 using free_second_leading_t [[maybe_unused]] = decltype(second_seq);
517 using init_t =
typename select_gap_init_policy<config_t, policy_trait_type>::type;
518 return configure_free_ends_optimum_search<function_wrapper_t, affine_t, dp_matrix_t, init_t>(cfg);
521 if constexpr (local_t::value)
529 auto configure_leading_second = [&] (
auto first) constexpr
532 if constexpr (align_ends_cfg_t::template is_static<2>())
535 return configure_leading_both(first, second_t{});
539 if (align_ends_cfg[2])
549 if constexpr (align_ends_cfg_t::template is_static<0>())
552 return configure_leading_second(first_t{});
556 if (align_ends_cfg[0])
568 template <
typename function_wrapper_t,
typename ...policies_t,
typename config_t>
569 constexpr function_wrapper_t alignment_configurator::configure_free_ends_optimum_search(config_t
const & cfg)
572 auto align_ends_cfg = cfg.template value_or<align_cfg::aligned_ends>(free_ends_none);
573 using align_ends_cfg_t = decltype(align_ends_cfg);
579 auto configure_trailing_both = [&] (
auto first_seq,
auto second_seq) constexpr
581 struct policy_trait_type
583 using find_in_every_cell_type [[maybe_unused]] = local_t;
584 using find_in_last_row_type [[maybe_unused]] = decltype(first_seq);
585 using find_in_last_column_type [[maybe_unused]] = decltype(second_seq);
588 using find_optimum_t = deferred_crtp_base<find_optimum_policy, policy_trait_type>;
589 return function_wrapper_t{alignment_algorithm<config_t, policies_t..., find_optimum_t>{cfg}};
592 if constexpr (local_t::value)
600 auto configure_trailing_second = [&] (
auto first) constexpr
603 if constexpr (align_ends_cfg_t::template is_static<3>())
606 return configure_trailing_both(first, second_t{});
610 if (align_ends_cfg[3])
620 if constexpr (align_ends_cfg_t::template is_static<1>())
623 return configure_trailing_second(first_t{});
627 if (align_ends_cfg[1])
Provides seqan3::detail::alignment_algorithm.
Specifies the requirements of a Range type that is either a std::ranges::View or an lvalue-reference...
Meta-header for the alignment configuration module .
Provides seqan3::type_list and auxiliary type traits.
std::remove_cv_t< std::remove_reference_t< t > > remove_cvref_t
Return the input type with const, volatile and references removed (type trait).
Definition: basic.hpp:35
SeqAn specific customisations in the standard namespace.
Provides seqan3::detail::deferred_crtp_base.
Provides seqan3::type_list and auxiliary type traits.
Provides seqan3::TupleLike.
Provides seqan3::alignment_result.
Provides seqan3::view::all.
Definition: aligned_sequence_concept.hpp:35
Provides seqan3::detail::align_result_selector.
Provides various transformation traits used by the range module.
Specifies requirements of a Range type for which begin returns a type that models std::ForwardIterato...
Provides seqan3::detail::edit_distance_algorithm.