SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
policy_affine_gap_recursion.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 
14 #pragma once
15 
16 #include <tuple>
17 
24 
25 namespace seqan3::detail
26 {
27 
43 template <typename alignment_configuration_t>
44 class policy_affine_gap_recursion
45 {
46 protected:
48  using traits_type = alignment_configuration_traits<alignment_configuration_t>;
50  using score_type = typename traits_type::score_type;
52  using affine_cell_type = affine_cell_proxy<std::tuple<score_type, score_type, score_type>>;
53 
55  score_type gap_extension_score{};
57  score_type gap_open_score{};
58 
60  bool first_row_is_free{};
62  bool first_column_is_free{};
63 
67  policy_affine_gap_recursion() = default;
68  policy_affine_gap_recursion(policy_affine_gap_recursion const &) = default;
69  policy_affine_gap_recursion(policy_affine_gap_recursion &&) = default;
70  policy_affine_gap_recursion & operator=(policy_affine_gap_recursion const &) = default;
71  policy_affine_gap_recursion & operator=(policy_affine_gap_recursion &&) = default;
72  ~policy_affine_gap_recursion() = default;
73 
83  explicit policy_affine_gap_recursion(alignment_configuration_t const & config)
84  {
85  // Get the gap scheme from the config or choose -1 and -10 as default.
86  auto const & selected_gap_scheme = config.get_or(align_cfg::gap_cost_affine{align_cfg::open_score{-10},
87  align_cfg::extension_score{-1}});
88 
89  if constexpr (simd::simd_concept<score_type>)
90  {
91  gap_extension_score = simd::fill<score_type>(selected_gap_scheme.extension_score);
92  gap_open_score = simd::fill<score_type>(selected_gap_scheme.open_score) + gap_extension_score;
93  }
94  else
95  {
96  gap_extension_score = static_cast<score_type>(selected_gap_scheme.extension_score);
97  gap_open_score = static_cast<score_type>(selected_gap_scheme.open_score) + gap_extension_score;
98  }
99 
100  auto method_global_config = config.get_or(align_cfg::method_global{});
101  first_row_is_free = method_global_config.free_end_gaps_sequence1_leading;
102  first_column_is_free = method_global_config.free_end_gaps_sequence2_leading;
103  }
105 
123  template <typename affine_cell_t>
125  requires is_type_specialisation_of_v<affine_cell_t, affine_cell_proxy>
127  affine_cell_type compute_inner_cell(score_type diagonal_score,
128  affine_cell_t previous_cell,
129  score_type const sequence_score) const noexcept
130  {
131  diagonal_score += sequence_score;
132  score_type horizontal_score = previous_cell.horizontal_score();
133  score_type vertical_score = previous_cell.vertical_score();
134 
135  diagonal_score = (diagonal_score < vertical_score) ? vertical_score : diagonal_score;
136  diagonal_score = (diagonal_score < horizontal_score) ? horizontal_score : diagonal_score;
137 
138  score_type tmp = diagonal_score + gap_open_score;
139  vertical_score += gap_extension_score;
140  horizontal_score += gap_extension_score;
141 
142  // store the vertical_score and horizontal_score value in the next path
143  vertical_score = (vertical_score < tmp) ? tmp : vertical_score;
144  horizontal_score = (horizontal_score < tmp) ? tmp : horizontal_score;
145 
146  return {diagonal_score, horizontal_score, vertical_score};
147  }
148 
159  affine_cell_type initialise_origin_cell() const noexcept
160  {
161  return {score_type{},
162  first_row_is_free ? score_type{} : gap_open_score,
163  first_column_is_free ? score_type{} : gap_open_score};
164  }
165 
180  template <typename affine_cell_t>
182  requires is_type_specialisation_of_v<affine_cell_t, affine_cell_proxy>
184  affine_cell_type initialise_first_column_cell(affine_cell_t previous_cell) const noexcept
185  {
186  score_type new_vertical = previous_cell.vertical_score() + gap_extension_score;
187  return {previous_cell.vertical_score(),
188  previous_cell.vertical_score() + gap_open_score,
189  first_column_is_free ? previous_cell.vertical_score() : new_vertical};
190  }
191 
206  template <typename affine_cell_t>
208  requires is_type_specialisation_of_v<affine_cell_t, affine_cell_proxy>
210  affine_cell_type initialise_first_row_cell(affine_cell_t previous_cell) const noexcept
211  {
212  score_type new_horizontal_score = previous_cell.horizontal_score() + gap_extension_score;
213  return {previous_cell.horizontal_score(),
214  first_row_is_free ? previous_cell.horizontal_score() : new_horizontal_score,
215  previous_cell.horizontal_score() + gap_open_score};
216  }
217 
228  score_type lowest_viable_score() const noexcept
229  {
230  assert(gap_open_score <= 0 && gap_extension_score <= 0);
231  return std::numeric_limits<score_type>::lowest() - (gap_open_score + gap_extension_score);
232  }
233 };
234 } // namespace seqan3::detail
align_config_gap_cost_affine.hpp
Provides seqan3::align_config::gap_cost_affine.
type_traits.hpp
Provides helper type traits for the configuration and execution of the alignment algorithm.
template_inspection.hpp
Provides seqan3::type_list and auxiliary type traits.
tuple
concept.hpp
Provides seqan3::simd::simd_concept.
std::numeric_limits::lowest
T lowest(T... args)
simd_algorithm.hpp
Provides algorithms to modify seqan3::simd::simd_type.
affine_cell_proxy.hpp
Provides seqan3::detail::affine_cell_proxy.