SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
affine_gap_policy.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 
19 
20 namespace seqan3::detail
21 {
22 
23 // ----------------------------------------------------------------------------
24 // affine_gap_policy
25 // ----------------------------------------------------------------------------
26 
45 template <typename alignment_algorithm_t, typename score_t, typename align_local_t = std::false_type>
46 class affine_gap_policy
47 {
48 private:
50  friend alignment_algorithm_t;
51 
53  using alignment_state_t = alignment_algorithm_state<score_t>;
54 
59  constexpr affine_gap_policy() noexcept = default;
60  constexpr affine_gap_policy(affine_gap_policy const &) noexcept = default;
61  constexpr affine_gap_policy(affine_gap_policy &&) noexcept = default;
62  constexpr affine_gap_policy & operator=(affine_gap_policy const &) noexcept = default;
63  constexpr affine_gap_policy & operator=(affine_gap_policy &&) noexcept = default;
64  ~affine_gap_policy() noexcept = default;
65 
80  template <typename cell_t>
81  constexpr void compute_cell(cell_t && current_cell,
82  alignment_algorithm_state<score_t> & cache,
83  score_t const score) const noexcept
84  {
85  // score_cell = seqan3::detail::alignment_score_matrix_proxy
86  // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
87  auto & [score_cell, trace_cell] = current_cell;
88  constexpr bool with_trace = !decays_to_ignore_v<std::remove_reference_t<decltype(trace_cell.current)>>;
89  // Precompute the diagonal score.
90  score_t tmp = score_cell.diagonal + score;
91 
92  if constexpr (with_trace)
93  {
94  tmp = (tmp < score_cell.up) ? (trace_cell.current = trace_cell.up, score_cell.up)
95  : (trace_cell.current = trace_directions::diagonal | trace_cell.up, tmp);
96  tmp = (tmp < score_cell.r_left) ? (trace_cell.current = trace_cell.r_left, score_cell.r_left)
97  : (trace_cell.current |= trace_cell.r_left, tmp);
98  }
99  else
100  {
101  tmp = (tmp < score_cell.up) ? score_cell.up : tmp;
102  tmp = (tmp < score_cell.r_left) ? score_cell.r_left : tmp;
103  }
104 
105  if constexpr (align_local_t::value)
106  tmp = (tmp < 0) ? (trace_cell.current = trace_directions::none, 0) : tmp;
107 
108  // Store the current max score.
109  score_cell.current = tmp;
110  // Check if this was the optimum. Possibly a noop.
111  static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, cache);
112 
113  // Prepare horizontal and vertical score for next column.
114  tmp += cache.gap_open_score;
115  score_cell.up += cache.gap_extension_score;
116  score_cell.w_left = score_cell.r_left + cache.gap_extension_score;
117 
118  score_cell.up = (score_cell.up < tmp) ? (trace_cell.up = trace_directions::up_open, tmp)
119  : (trace_cell.up = trace_directions::up, score_cell.up);
120  score_cell.w_left = (score_cell.w_left < tmp) ? (trace_cell.w_left = trace_directions::left_open, tmp)
121  : (trace_cell.w_left = trace_directions::left, score_cell.w_left);
122  }
123 
137  template <typename cell_t>
138  constexpr void compute_first_band_cell(cell_t && current_cell,
139  alignment_algorithm_state<score_t> & cache,
140  score_t const score) const noexcept
141  {
142  // Compute the diagonal score and the compare with the previous horizontal value.
143  // score_cell = seqan3::detail::alignment_score_matrix_proxy
144  // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
145  auto & [score_cell, trace_cell] = current_cell;
146  score_cell.current = score_cell.diagonal + score;
147 
148  score_cell.current = (score_cell.current < score_cell.r_left)
149  ? (trace_cell.current = trace_cell.r_left, score_cell.r_left)
150  : (trace_cell.current = trace_directions::diagonal, score_cell.current);
151 
152  if constexpr (align_local_t::value)
153  {
154  score_cell.current = (score_cell.current < 0) ? (trace_cell.current = trace_directions::none, 0)
155  : score_cell.current;
156  }
157  // Check if this was the optimum. Possibly a noop.
158  static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, cache);
159 
160  // At the top of the band we can not come from up but only diagonal or left, so the next vertical must be a
161  // gap open.
162  score_cell.up = score_cell.current + cache.gap_open_score; // add gap open cost
163  trace_cell.up = trace_directions::up_open;
164  }
165 
179  template <typename alignment_configuration_t>
180  constexpr void initialise_alignment_state(alignment_configuration_t const & config) noexcept
181  {
182  auto scheme = config.template value_or<align_cfg::gap>(gap_scheme{gap_score{-1}, gap_open_score{-10}});
183 
184  alignment_state.gap_extension_score = static_cast<score_t>(scheme.get_gap_score());
185  alignment_state.gap_open_score = static_cast<score_t>(scheme.get_gap_score() + scheme.get_gap_open_score());
186  }
187 
188  alignment_state_t alignment_state{};
189 };
190 
191 } // namespace seqan3::detail
align_config_gap.hpp
Provides seqan3::align_config::gap.
trace_directions.hpp
Provides the declaration of seqan3::detail::trace_directions.
core_language.hpp
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
std::remove_reference_t
alignment_algorithm_state.hpp
Provides seqan3::detail::alignment_algorithm_state.