SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
wuss.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <cmath>
13#include <limits>
14#include <vector>
15
19
20// ------------------------------------------------------------------
21// wuss
22// ------------------------------------------------------------------
23
24namespace seqan3
25{
26
56template <uint8_t SIZE = 51>
57class wuss : public alphabet_base<wuss<SIZE>, SIZE>
58{
59 static_assert(SIZE >= 15 && SIZE <= 67 && SIZE % 2 == 1,
60 "The wuss<> alphabet size must be an odd number in range 15..67.");
61
62private:
64 using base_t = alphabet_base<wuss<SIZE>, SIZE>;
65
67 friend base_t;
68
69protected:
70 using typename base_t::char_type;
71 using typename base_t::rank_type;
72
73public:
75 using base_t::to_char;
76 using base_t::to_rank;
77
81 constexpr wuss() noexcept = default;
82 constexpr wuss(wuss const &) noexcept = default;
83 constexpr wuss(wuss &&) noexcept = default;
84 constexpr wuss & operator=(wuss const &) noexcept = default;
85 constexpr wuss & operator=(wuss &&) noexcept = default;
86 ~wuss() noexcept = default;
87
89
98 constexpr bool is_pair_open() const noexcept
99 {
100 return interaction_tab[to_rank()] < 0;
101 }
102
108 constexpr bool is_pair_close() const noexcept
109 {
110 return interaction_tab[to_rank()] > 0;
111 }
112
118 constexpr bool is_unpaired() const noexcept
119 {
120 return interaction_tab[to_rank()] == 0;
121 }
122
128 // formula: (alphabet size - 7 unpaired characters) / 2, as every bracket exists as opening/closing pair
129 static constexpr uint8_t max_pseudoknot_depth{static_cast<uint8_t>((alphabet_size - 7) / 2)};
130
139 constexpr std::optional<uint8_t> pseudoknot_id() const noexcept
140 {
141 if (interaction_tab[to_rank()] != 0)
142 return std::abs(interaction_tab[to_rank()]) - 1;
143 else
144 return std::nullopt; // unpaired
145 }
147
148private:
150 static constexpr char_type rank_to_char(rank_type const rank)
151 {
152 return rank_to_char_table[rank];
153 }
154
156 static constexpr rank_type char_to_rank(char_type const chr)
157 {
158 using index_t = std::make_unsigned_t<char_type>;
159 return char_to_rank_table[static_cast<index_t>(chr)];
160 }
161
162 // clang-format off
164 static constexpr std::array<char_type, alphabet_size> rank_to_char_table
165 {
166 []() constexpr {
167 std::array<char_type, alphabet_size> chars{'.', ':', ',', '-', '_', '~', ';', '<', '(', '[', '{', '>', ')',
168 ']', '}'};
169
170 // pseudoknot letters
171 for (rank_type rnk = 15u; rnk + 1u < alphabet_size; rnk += 2u)
172 {
173 char_type const off = static_cast<char_type>((rnk - 15u) / 2u);
174 chars[rnk] = 'A' + off;
175 chars[rnk + 1u] = 'a' + off;
176 }
177
178 return chars;
179 }()
180 };
181
183 static constexpr std::array<rank_type, 256> char_to_rank_table
184 {
185 []() constexpr {
186 std::array<rank_type, 256> rank_table{};
187
188 rank_table.fill(6u);
189
190 // set alphabet values
191 for (rank_type rnk = 0u; rnk < alphabet_size; ++rnk)
192 rank_table[rank_to_char_table[rnk]] = rnk;
193
194 return rank_table;
195 }()
196 };
197
201 static constexpr std::array<int8_t, SIZE> interaction_tab
202 {
203 []() constexpr {
204 static_assert(static_cast<int16_t>(std::numeric_limits<int8_t>::max()) >= SIZE);
205 static_assert(- static_cast<int16_t>(std::numeric_limits<int8_t>::min()) >= SIZE);
206
207 std::array<int8_t, alphabet_size> interaction_table{};
208 int8_t cnt_open = 0;
209 int8_t cnt_close = 0;
210
211 for (rank_type rnk = 0u; rnk <= 6u; ++rnk)
212 interaction_table[rnk] = 0;
213
214 for (rank_type rnk = 7u; rnk <= 10u; ++rnk)
215 interaction_table[rnk] = --cnt_open;
216
217 for (rank_type rnk = 11u; rnk <= 14u; ++rnk)
218 interaction_table[rnk] = ++cnt_close;
219
220 for (rank_type rnk = 15u; rnk + 1u < alphabet_size; rnk += 2u)
221 {
222 interaction_table[rnk] = --cnt_open;
223 interaction_table[rnk + 1u] = ++cnt_close;
224 }
225
226 return interaction_table;
227 }()
228 };
229};
230// clang-format on
231
236
237inline namespace literals
238{
239
253constexpr wuss51 operator""_wuss51(char const ch) noexcept
254{
255 return wuss51{}.assign_char(ch);
256}
257
269SEQAN3_WORKAROUND_LITERAL std::vector<wuss51> operator""_wuss51(char const * str, std::size_t len)
270{
272 vec.resize(len);
273
274 for (size_t idx = 0ul; idx < len; ++idx)
275 vec[idx].assign_char(str[idx]);
276
277 return vec;
278}
280
281} // namespace literals
282
283} // namespace seqan3
Provides seqan3::rna_structure_alphabet.
Provides seqan3::alphabet_base.
A CRTP-base that makes defining a custom alphabet easier.
Definition alphabet_base.hpp:54
constexpr derived_type & assign_char(char_type const chr) noexcept
Assign from a character, implicitly converts invalid characters.
Definition alphabet_base.hpp:160
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition alphabet_base.hpp:134
detail::min_viable_uint_t< size - 1 > rank_type
The type of the alphabet when represented as a number (e.g. via to_rank()).
Definition alphabet_base.hpp:77
static constexpr detail::min_viable_uint_t< size > alphabet_size
The size of the alphabet, i.e. the number of different values it can take.
Definition alphabet_base.hpp:196
constexpr char_type to_char() const noexcept
Return the letter as a character of char_type.
Definition alphabet_base.hpp:112
std::conditional_t< std::same_as< char_t, void >, char, char_t > char_type
The char representation; conditional needed to make semi alphabet definitions legal.
Definition alphabet_base.hpp:69
The WUSS structure alphabet of the characters .<>:,-_~;()[]{}AaBbCcDd...
Definition wuss.hpp:58
static constexpr uint8_t max_pseudoknot_depth
The ability of this alphabet to represent pseudoknots, i.e. crossing interactions,...
Definition wuss.hpp:129
constexpr bool is_pair_close() const noexcept
Check whether the character represents a leftward interaction in an RNA structure.
Definition wuss.hpp:108
constexpr bool is_pair_open() const noexcept
Check whether the character represents a rightward interaction in an RNA structure.
Definition wuss.hpp:98
constexpr std::optional< uint8_t > pseudoknot_id() const noexcept
Get an identifier for a pseudoknotted interaction, where opening and closing brackets of the same typ...
Definition wuss.hpp:139
detail::min_viable_uint_t< size - 1 > rank_type
The type of the alphabet when represented as a number (e.g. via to_rank()).
Definition alphabet_base.hpp:77
static constexpr detail::min_viable_uint_t< size > alphabet_size
The size of the alphabet, i.e. the number of different values it can take.
Definition alphabet_base.hpp:196
constexpr wuss() noexcept=default
Defaulted.
constexpr bool is_unpaired() const noexcept
Check whether the character represents an unpaired position in an RNA structure.
Definition wuss.hpp:118
std::conditional_t< std::same_as< char_t, void >, char, char_t > char_type
The char representation; conditional needed to make semi alphabet definitions legal.
Definition alphabet_base.hpp:69
T fill(T... args)
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
T max(T... args)
T min(T... args)
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
@ off
Automatic update notifications should be disabled.
#define SEQAN3_WORKAROUND_LITERAL
Our char literals returning std::vector should be constexpr if constexpr std::vector is supported.
Definition platform.hpp:269
T resize(T... args)
Provides utilities for modifying characters.
Hide me