SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
affine_gap_init_policy.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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
15#include <tuple>
16
20
21namespace seqan3::detail
22{
23
35template <typename alignment_algorithm_t>
36class affine_gap_init_policy
37{
38private:
40 friend alignment_algorithm_t;
41
43 bool first_row_is_free{};
45 bool first_column_is_free{};
46
51 constexpr affine_gap_init_policy() noexcept = default;
52 constexpr affine_gap_init_policy(affine_gap_init_policy const &) noexcept = default;
53 constexpr affine_gap_init_policy(affine_gap_init_policy &&) noexcept = default;
54 constexpr affine_gap_init_policy & operator=(affine_gap_init_policy const &) noexcept = default;
55 constexpr affine_gap_init_policy & operator=(affine_gap_init_policy &&) noexcept = default;
56 ~affine_gap_init_policy() noexcept = default;
57
59 template <typename config_t>
60 affine_gap_init_policy(config_t const & config)
61 {
62 bool is_local = config.template exists<align_cfg::method_local>();
63 auto method_global_config = config.get_or(align_cfg::method_global{});
64 first_row_is_free = method_global_config.free_end_gaps_sequence1_leading | is_local;
65 first_column_is_free = method_global_config.free_end_gaps_sequence2_leading | is_local;
66 }
68
83 template <typename cell_t, typename score_t>
84 constexpr auto init_origin_cell(cell_t && origin_cell, alignment_algorithm_state<score_t> & state) const noexcept
85 {
86 // score_cell = seqan3::detail::alignment_score_matrix_proxy
87 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
88 auto & [score_cell, trace_cell] = origin_cell;
89
90 // Initialise the first cell.
91 score_cell.current = convert_to_simd_maybe<score_t>(0);
92 trace_cell.current = convert_to_simd_maybe<score_t>(trace_directions::none);
93
94 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(origin_cell, state);
95
96 // Initialise the vertical matrix cell according to the traits settings.
97 if (first_column_is_free)
98 {
99 score_cell.up = convert_to_simd_maybe<score_t>(0);
100 trace_cell.up = convert_to_simd_maybe<score_t>(trace_directions::none);
101 }
102 else // Initialise with gap_open score
103 {
104 score_cell.up = state.gap_open_score;
105 trace_cell.up = convert_to_simd_maybe<score_t>(trace_directions::up_open);
106 }
107
108 // Initialise the horizontal matrix cell according to the traits settings.
109 if (first_row_is_free)
110 {
111 score_cell.w_left = convert_to_simd_maybe<score_t>(0);
112 trace_cell.w_left = convert_to_simd_maybe<score_t>(trace_directions::none);
113 }
114 else // Initialise with gap_open score
115 {
116 score_cell.w_left = state.gap_open_score;
117 trace_cell.w_left = convert_to_simd_maybe<score_t>(trace_directions::left_open);
118 }
119 }
120
135 template <typename cell_t, typename score_t>
136 constexpr auto init_column_cell(cell_t && column_cell, alignment_algorithm_state<score_t> & state) const noexcept
137 {
138 // score_cell = seqan3::detail::alignment_score_matrix_proxy
139 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
140 auto & [score_cell, trace_cell] = column_cell;
141
142 score_cell.current = score_cell.up;
143 trace_cell.current = trace_cell.up;
144
145 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(column_cell, state);
146
147 // Initialise the vertical matrix cell according to the traits settings.
148 if (first_column_is_free)
149 {
150 score_cell.up = convert_to_simd_maybe<score_t>(0);
151 }
152 else
153 {
154 score_cell.up += state.gap_extension_score;
155 trace_cell.up = convert_to_simd_maybe<score_t>(trace_directions::up);
156 }
157
158 score_cell.w_left = score_cell.current + state.gap_open_score;
159 trace_cell.w_left = convert_to_simd_maybe<score_t>(trace_directions::left_open);
160 }
161
176 template <typename cell_t, typename score_t>
177 constexpr auto init_row_cell(cell_t && row_cell, alignment_algorithm_state<score_t> & state) const noexcept
178 {
179 // score_cell = seqan3::detail::alignment_score_matrix_proxy
180 // trace_cell = seqan3::detail::alignment_trace_matrix_proxy
181 auto & [score_cell, trace_cell] = row_cell;
182
183 score_cell.current = score_cell.r_left;
184 trace_cell.current = trace_cell.r_left;
185
186 static_cast<alignment_algorithm_t const &>(*this).check_score_of_cell(row_cell, state);
187
188 score_cell.up = score_cell.current + state.gap_open_score;
189 trace_cell.up = convert_to_simd_maybe<score_t>(trace_directions::up_open);
190
191 if (first_row_is_free)
192 {
193 score_cell.w_left = convert_to_simd_maybe<score_t>(0);
194 trace_cell.w_left = convert_to_simd_maybe<score_t>(trace_directions::none);
195 }
196 else
197 {
198 score_cell.w_left = score_cell.r_left + state.gap_extension_score;
199 trace_cell.w_left = convert_to_simd_maybe<score_t>(trace_directions::left);
200 }
201 }
202
203private:
215 template <typename score_t, typename value_t>
216 constexpr auto convert_to_simd_maybe(value_t const value) const noexcept
217 {
218 if constexpr (simd_concept<score_t>)
219 {
220 using scalar_t = typename simd_traits<score_t>::scalar_type;
221 return simd::fill<score_t>(static_cast<scalar_t>(value));
222 }
223 else
224 {
225 return value;
226 }
227 }
228};
229
230} // namespace seqan3::detail
Provides global and local alignment configurations.
Provides seqan3::detail::alignment_algorithm_state.
Provides the declaration of seqan3::detail::trace_directions.