SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
simd_match_mismatch_scoring_scheme.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
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
21 #include <seqan3/std/concepts>
22 
23 namespace seqan3::detail
24 {
25 
63 template <simd_concept simd_score_t, semialphabet alphabet_t, typename alignment_t>
65  requires (seqan3::alphabet_size<alphabet_t> > 1) &&
66  (std::same_as<alignment_t, align_cfg::method_local> ||
67  std::same_as<alignment_t, align_cfg::method_global>)
69 class simd_match_mismatch_scoring_scheme
70 {
71 public:
75  constexpr simd_match_mismatch_scoring_scheme() = default;
78  constexpr simd_match_mismatch_scoring_scheme(simd_match_mismatch_scoring_scheme const &) = default;
80  constexpr simd_match_mismatch_scoring_scheme(simd_match_mismatch_scoring_scheme &&) = default;
82  constexpr simd_match_mismatch_scoring_scheme & operator=(simd_match_mismatch_scoring_scheme const &) = default;
84  constexpr simd_match_mismatch_scoring_scheme & operator=(simd_match_mismatch_scoring_scheme &&) = default;
86  ~simd_match_mismatch_scoring_scheme() = default;
87 
89  template <typename scoring_scheme_t>
93  constexpr explicit simd_match_mismatch_scoring_scheme(scoring_scheme_t const & scoring_scheme)
94  {
95  initialise_from_scalar_scoring_scheme(scoring_scheme);
96  }
97 
99  template <typename scoring_scheme_t>
103  constexpr simd_match_mismatch_scoring_scheme & operator=(scoring_scheme_t const & scoring_scheme)
104  {
105  initialise_from_scalar_scoring_scheme(scoring_scheme);
106  return *this;
107  }
109 
139  constexpr simd_score_t score(simd_score_t const & lhs, simd_score_t const & rhs) const noexcept
140  {
141  typename simd_traits<simd_score_t>::mask_type mask;
142  // For global and local alignment there are slightly different formulas because
143  // in global alignment padded characters always match
144  if constexpr (std::same_as<alignment_t, align_cfg::method_global>)
145  mask = (lhs ^ rhs) <= simd::fill<simd_score_t>(0);
146  else // and in local alignment type padded characters always mismatch.
147  mask = (lhs ^ rhs) == simd::fill<simd_score_t>(0);
148 
149  return mask ? match_score : mismatch_score;
150  }
152 
154  constexpr auto padding_match_score() noexcept
155  {
156  return match_score[0];
157  }
158 
159 private:
175  template <typename scoring_scheme_t>
176  constexpr void initialise_from_scalar_scoring_scheme(scoring_scheme_t const & scoring_scheme)
177  {
178  using score_t = decltype(std::declval<scoring_scheme_t const &>().score(alphabet_t{}, alphabet_t{}));
179  using simd_scalar_t = typename simd_traits<simd_score_t>::scalar_type;
180 
181  score_t scalar_match_score = scoring_scheme.score(seqan3::assign_rank_to(0, alphabet_t{}),
182  seqan3::assign_rank_to(0, alphabet_t{}));
183  score_t scalar_mismatch_score = scoring_scheme.score(seqan3::assign_rank_to(0, alphabet_t{}),
184  seqan3::assign_rank_to(1, alphabet_t{}));
185 
186  // Check if the scoring scheme match and mismatch scores do not overflow with the respective scalar type.
187  if constexpr (sizeof(simd_scalar_t) < sizeof(score_t))
188  {
189  if (scalar_match_score > static_cast<score_t>(std::numeric_limits<simd_scalar_t>::max()) ||
190  scalar_mismatch_score < static_cast<score_t>(std::numeric_limits<simd_scalar_t>::lowest()))
191  {
192  throw std::invalid_argument{"The selected scoring scheme score overflows "
193  "for the selected scalar type of the simd type."};
194  }
195  }
196 
197  match_score = simd::fill<simd_score_t>(static_cast<simd_scalar_t>(scalar_match_score));
198  mismatch_score = simd::fill<simd_score_t>(static_cast<simd_scalar_t>(scalar_mismatch_score));
199  }
200 
201  simd_score_t match_score;
202  simd_score_t mismatch_score;
203 };
204 
205 } // namespace seqan3::detail
seqan3::assign_rank_to
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:239
align_config_method.hpp
Provides global and local alignment configurations.
concept.hpp
Provides seqan3::simd::simd_concept.
concepts
The Concepts library.
simd_algorithm.hpp
Provides algorithms to modify seqan3::simd::simd_type.
scoring_scheme_concept.hpp
Provides seqan3::scoring_scheme_for.
std::invalid_argument
scoring_scheme_for
A concept that requires that type be able to score two letters.
cereal.hpp
Adaptions of concepts from the Cereal library.
std::numeric_limits
concept.hpp
Core alphabet concept and free function/type trait wrappers.