SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
affine_gap_policy.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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
20namespace seqan3::detail
21{
22
23// ----------------------------------------------------------------------------
24// affine_gap_policy
25// ----------------------------------------------------------------------------
26
45template <typename alignment_algorithm_t, typename score_t, typename align_local_t = std::false_type>
46class affine_gap_policy
47{
48private:
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
67 template <typename configuration_t>
68 affine_gap_policy(configuration_t const & /*config*/)
69 {}
71
85 template <typename cell_t>
86 constexpr void compute_cell(cell_t && current_cell,
87 alignment_algorithm_state<score_t> & cache,
88 score_t const score) const noexcept
89 {
90 // score_cell = seqan3::detail::alignment_score_matrix_proxy
91 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
92 auto & [score_cell, trace_cell] = current_cell;
93 constexpr bool with_trace = !decays_to_ignore_v<std::remove_reference_t<decltype(trace_cell.current)>>;
94 // Precompute the diagonal score.
95 score_t tmp = score_cell.diagonal + score;
96
97 if constexpr (with_trace)
98 {
99 tmp = (tmp < score_cell.up) ? (trace_cell.current = trace_cell.up, score_cell.up)
100 : (trace_cell.current = trace_directions::diagonal | trace_cell.up, tmp);
101 tmp = (tmp < score_cell.r_left) ? (trace_cell.current = trace_cell.r_left, score_cell.r_left)
102 : (trace_cell.current |= trace_cell.r_left, tmp);
103 }
104 else
105 {
106 tmp = (tmp < score_cell.up) ? score_cell.up : tmp;
107 tmp = (tmp < score_cell.r_left) ? score_cell.r_left : tmp;
108 }
109
110 if constexpr (align_local_t::value)
111 tmp = (tmp < 0) ? (trace_cell.current = trace_directions::none, 0) : tmp;
112
113 // Store the current max score.
114 score_cell.current = tmp;
115 // Check if this was the optimum. Possibly a noop.
116 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, cache);
117
118 // Prepare horizontal and vertical score for next column.
119 tmp += cache.gap_open_score;
120 score_cell.up += cache.gap_extension_score;
121 score_cell.w_left = score_cell.r_left + cache.gap_extension_score;
122
123 score_cell.up = (score_cell.up < tmp) ? (trace_cell.up = trace_directions::up_open, tmp)
124 : (trace_cell.up = trace_directions::up, score_cell.up);
125 score_cell.w_left = (score_cell.w_left < tmp) ? (trace_cell.w_left = trace_directions::left_open, tmp)
126 : (trace_cell.w_left = trace_directions::left, score_cell.w_left);
127 }
128
142 template <typename cell_t>
143 constexpr void compute_first_band_cell(cell_t && current_cell,
144 alignment_algorithm_state<score_t> & cache,
145 score_t const score) const noexcept
146 {
147 // Compute the diagonal score and the compare with the previous horizontal value.
148 // score_cell = seqan3::detail::alignment_score_matrix_proxy
149 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
150 auto & [score_cell, trace_cell] = current_cell;
151 score_cell.current = score_cell.diagonal + score;
152
153 score_cell.current = (score_cell.current < score_cell.r_left)
154 ? (trace_cell.current = trace_cell.r_left, score_cell.r_left)
155 : (trace_cell.current = trace_directions::diagonal, score_cell.current);
156
157 if constexpr (align_local_t::value)
158 {
159 score_cell.current = (score_cell.current < 0) ? (trace_cell.current = trace_directions::none, 0)
160 : score_cell.current;
161 }
162 // Check if this was the optimum. Possibly a noop.
163 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(current_cell, cache);
164
165 // At the top of the band we can not come from up but only diagonal or left, so the next vertical must be a
166 // gap open.
167 score_cell.up = score_cell.current + cache.gap_open_score; // add gap open cost
168 trace_cell.up = trace_directions::up_open;
169 }
170
184 template <typename alignment_configuration_t>
185 constexpr void initialise_alignment_state(alignment_configuration_t const & config) noexcept
186 {
187 auto scheme = config.get_or(align_cfg::gap_cost_affine{align_cfg::open_score{-10},
188 align_cfg::extension_score{-1}});
189
190 alignment_state.gap_extension_score = static_cast<score_t>(scheme.extension_score);
191 alignment_state.gap_open_score = static_cast<score_t>(scheme.extension_score + scheme.open_score);
192 }
193
194 alignment_state_t alignment_state{};
195};
196
197} // namespace seqan3::detail
Provides seqan3::align_config::gap_cost_affine.
Provides seqan3::detail::alignment_algorithm_state.
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
Provides the declaration of seqan3::detail::trace_directions.