SeqAn3 3.1.0
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-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
15#include <seqan3/std/concepts>
16
24
25namespace seqan3::detail
26{
27
65template <simd_concept simd_score_t, semialphabet alphabet_t, typename alignment_t>
67 requires (seqan3::alphabet_size<alphabet_t> > 1) &&
68 (std::same_as<alignment_t, align_cfg::method_local> ||
69 std::same_as<alignment_t, align_cfg::method_global>)
71class simd_match_mismatch_scoring_scheme
72{
73private:
75 using scalar_type = typename simd_traits<simd_score_t>::scalar_type;
77 using alphabet_ranks_type = simd_score_t;
78
79public:
81 static constexpr scalar_type padding_symbol = static_cast<scalar_type>(1u << (bits_of<scalar_type> - 1));
82
87 constexpr simd_match_mismatch_scoring_scheme() = default;
89 constexpr simd_match_mismatch_scoring_scheme(simd_match_mismatch_scoring_scheme const &) = default;
91 constexpr simd_match_mismatch_scoring_scheme(simd_match_mismatch_scoring_scheme &&) = default;
93 constexpr simd_match_mismatch_scoring_scheme & operator=(simd_match_mismatch_scoring_scheme const &) = default;
95 constexpr simd_match_mismatch_scoring_scheme & operator=(simd_match_mismatch_scoring_scheme &&) = default;
97 ~simd_match_mismatch_scoring_scheme() = default;
98
100 template <typename scoring_scheme_t>
104 constexpr explicit simd_match_mismatch_scoring_scheme(scoring_scheme_t const & scoring_scheme)
105 {
106 initialise_from_scalar_scoring_scheme(scoring_scheme);
107 }
108
110 template <typename scoring_scheme_t>
114 constexpr simd_match_mismatch_scoring_scheme & operator=(scoring_scheme_t const & scoring_scheme)
115 {
116 initialise_from_scalar_scoring_scheme(scoring_scheme);
117 return *this;
118 }
120
150 constexpr simd_score_t score(alphabet_ranks_type const & ranks1, alphabet_ranks_type const & ranks2)
151 const noexcept
152 {
153 typename simd_traits<simd_score_t>::mask_type mask;
154 // For global and local alignment there are slightly different formulas because
155 // in global alignment padded characters always match
156 if constexpr (std::same_as<alignment_t, align_cfg::method_global>)
157 mask = (ranks1 ^ ranks2) <= simd::fill<simd_score_t>(0);
158 else // and in local alignment type padded characters always mismatch.
159 mask = (ranks1 ^ ranks2) == simd::fill<simd_score_t>(0);
160
161 return mask ? match_score : mismatch_score;
162 }
164
166 constexpr auto padding_match_score() noexcept
167 {
168 return match_score[0];
169 }
170
172 template <typename alphabet_ranks_t>
174 requires std::same_as<std::remove_cvref_t<alphabet_ranks_t>, alphabet_ranks_type>
176 constexpr alphabet_ranks_t make_score_profile(alphabet_ranks_t && ranks) const noexcept
177 {
178 return std::forward<alphabet_ranks_t>(ranks);
179 }
180
181private:
197 template <typename scoring_scheme_t>
198 constexpr void initialise_from_scalar_scoring_scheme(scoring_scheme_t const & scoring_scheme)
199 {
200 using score_t = decltype(std::declval<scoring_scheme_t const &>().score(alphabet_t{}, alphabet_t{}));
201 using simd_scalar_t = typename simd_traits<simd_score_t>::scalar_type;
202
203 score_t scalar_match_score = scoring_scheme.score(seqan3::assign_rank_to(0, alphabet_t{}),
204 seqan3::assign_rank_to(0, alphabet_t{}));
205 score_t scalar_mismatch_score = scoring_scheme.score(seqan3::assign_rank_to(0, alphabet_t{}),
206 seqan3::assign_rank_to(1, alphabet_t{}));
207
208 // Check if the scoring scheme match and mismatch scores do not overflow with the respective scalar type.
209 if constexpr (sizeof(simd_scalar_t) < sizeof(score_t))
210 {
211 if (scalar_match_score > static_cast<score_t>(std::numeric_limits<simd_scalar_t>::max()) ||
212 scalar_mismatch_score < static_cast<score_t>(std::numeric_limits<simd_scalar_t>::lowest()))
213 {
214 throw std::invalid_argument{"The selected scoring scheme score overflows "
215 "for the selected scalar type of the simd type."};
216 }
217 }
218
219 match_score = simd::fill<simd_score_t>(static_cast<simd_scalar_t>(scalar_match_score));
220 mismatch_score = simd::fill<simd_score_t>(static_cast<simd_scalar_t>(scalar_mismatch_score));
221 }
222
223 simd_score_t match_score;
224 simd_score_t mismatch_score;
225};
226
227} // namespace seqan3::detail
Provides algorithms to modify seqan3::simd::simd_type.
Provides global and local alignment configurations.
Core alphabet concept and free function/type trait wrappers.
Provides utility functions for bit twiddling.
Adaptions of concepts from the Cereal library.
The <concepts> header from C++20's standard library.
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:294
A concept that requires that type be able to score two letters.
Provides seqan3::scoring_scheme_for.
Provides seqan3::simd::simd_concept.