SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
policy_affine_gap_with_trace_recursion.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 
16 
17 namespace seqan3::detail
18 {
19 
25 template <typename alignment_configuration_t>
26 class policy_affine_gap_with_trace_recursion : protected policy_affine_gap_recursion<alignment_configuration_t>
27 {
28 protected:
30  using base_t = policy_affine_gap_recursion<alignment_configuration_t>;
31 
32  // Import base types.
33  using typename base_t::traits_type;
34  using typename base_t::score_type;
35  using typename base_t::affine_score_tuple_t;
36 
38  using trace_type = typename traits_type::trace_type;
40  using affine_trace_tuple_t = std::tuple<trace_type, trace_type, trace_type>;
42  using affine_cell_type = affine_cell_proxy<std::pair<affine_score_tuple_t, affine_trace_tuple_t>>;
43 
44  // Import base member.
45  using base_t::gap_extension_score;
46  using base_t::gap_open_score;
47  using base_t::first_row_is_free;
48  using base_t::first_column_is_free;
49 
53  policy_affine_gap_with_trace_recursion() = default;
54  policy_affine_gap_with_trace_recursion(policy_affine_gap_with_trace_recursion const &) = default;
55  policy_affine_gap_with_trace_recursion(policy_affine_gap_with_trace_recursion &&) = default;
56  policy_affine_gap_with_trace_recursion & operator=(policy_affine_gap_with_trace_recursion const &)
57  = default;
58  policy_affine_gap_with_trace_recursion & operator=(policy_affine_gap_with_trace_recursion &&)
59  = default;
60  ~policy_affine_gap_with_trace_recursion() = default;
61 
63  explicit policy_affine_gap_with_trace_recursion(alignment_configuration_t const & config) : base_t{config}
64  {}
66 
68  template <typename affine_cell_t>
69  affine_cell_type compute_inner_cell(score_type diagonal_score,
70  affine_cell_t previous_cell,
71  score_type const sequence_score) const noexcept
72  {
73  diagonal_score += sequence_score;
74  score_type horizontal_score = previous_cell.horizontal_score();
75  score_type vertical_score = previous_cell.vertical_score();
76  trace_directions best_trace = trace_directions::diagonal;
77 
78  diagonal_score = (diagonal_score < vertical_score)
79  ? (best_trace = previous_cell.vertical_trace(), vertical_score)
80  : (best_trace |= previous_cell.vertical_trace(), diagonal_score);
81  diagonal_score = (diagonal_score < horizontal_score)
82  ? (best_trace = previous_cell.horizontal_trace(), horizontal_score)
83  : (best_trace |= previous_cell.horizontal_trace(), diagonal_score);
84 
85  score_type tmp = diagonal_score + gap_open_score;
86  vertical_score += gap_extension_score;
87  horizontal_score += gap_extension_score;
88 
89  // store the vertical_score and horizontal_score value in the next path
90  trace_directions next_vertical_trace = trace_directions::up;
91  trace_directions next_horizontal_trace = trace_directions::left;
92 
93  vertical_score = (vertical_score < tmp)
94  ? (next_vertical_trace = trace_directions::up_open, tmp)
95  : vertical_score;
96  horizontal_score = (horizontal_score < tmp)
97  ? (next_horizontal_trace = trace_directions::left_open, tmp)
98  : horizontal_score;
99 
100  return {{diagonal_score, horizontal_score, vertical_score},
101  {best_trace, next_horizontal_trace, next_vertical_trace}};
102  }
103 
105  affine_cell_type initialise_origin_cell() const noexcept
106  {
107  return {base_t::initialise_origin_cell(),
108  {trace_directions::none,
109  first_row_is_free ? trace_directions::none : trace_directions::left_open,
110  first_column_is_free ? trace_directions::none : trace_directions::up_open}};
111  }
112 
114  template <typename affine_cell_t>
115  affine_cell_type initialise_first_column_cell(affine_cell_t previous_cell) const noexcept
116  {
117  return {base_t::initialise_first_column_cell(previous_cell),
118  {previous_cell.vertical_trace(),
119  trace_directions::left_open,
120  first_column_is_free ? trace_directions::none : trace_directions::up}};
121  }
122 
124  template <typename affine_cell_t>
125  affine_cell_type initialise_first_row_cell(affine_cell_t previous_cell) const noexcept
126  {
127  return {base_t::initialise_first_row_cell(previous_cell),
128  {previous_cell.horizontal_trace(),
129  first_row_is_free ? trace_directions::none : trace_directions::left,
130  trace_directions::up_open}};
131  }
132 };
133 } // namespace seqan3::detail
Provides seqan3::detail::policy_affine_gap_recursion.