Loading...
Searching...
No Matches
wuss.hpp
Go to the documentation of this file.
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <cmath>
#include <limits>
#include <vector>
#include <seqan3/alphabet/alphabet_base.hpp>
#include <seqan3/alphabet/structure/concept.hpp>
#include <seqan3/utility/char_operations/transform.hpp>
// ------------------------------------------------------------------
// wuss
// ------------------------------------------------------------------
namespace seqan3
{
template <uint8_t SIZE = 51>
class wuss : public alphabet_base<wuss<SIZE>, SIZE>
{
static_assert(SIZE >= 15 && SIZE <= 67 && SIZE % 2 == 1,
"The wuss<> alphabet size must be an odd number in range 15..67.");
private:
using base_t = alphabet_base<wuss<SIZE>, SIZE>;
friend base_t;
protected:
using typename base_t::char_type;
using typename base_t::rank_type;
public:
using base_t::alphabet_size;
using base_t::to_char;
using base_t::to_rank;
constexpr wuss() noexcept = default;
constexpr wuss(wuss const &) noexcept = default;
constexpr wuss(wuss &&) noexcept = default;
constexpr wuss & operator=(wuss const &) noexcept = default;
constexpr wuss & operator=(wuss &&) noexcept = default;
~wuss() noexcept = default;
constexpr bool is_pair_open() const noexcept
{
return interaction_tab[to_rank()] < 0;
}
constexpr bool is_pair_close() const noexcept
{
return interaction_tab[to_rank()] > 0;
}
constexpr bool is_unpaired() const noexcept
{
return interaction_tab[to_rank()] == 0;
}
// formula: (alphabet size - 7 unpaired characters) / 2, as every bracket exists as opening/closing pair
static constexpr uint8_t max_pseudoknot_depth{static_cast<uint8_t>((alphabet_size - 7) / 2)};
constexpr std::optional<uint8_t> pseudoknot_id() const noexcept
{
if (interaction_tab[to_rank()] != 0)
return std::abs(interaction_tab[to_rank()]) - 1;
else
return std::nullopt; // unpaired
}
private:
static constexpr char_type rank_to_char(rank_type const rank)
{
return rank_to_char_table[rank];
}
static constexpr rank_type char_to_rank(char_type const chr)
{
using index_t = std::make_unsigned_t<char_type>;
return char_to_rank_table[static_cast<index_t>(chr)];
}
static constexpr std::array<char_type, alphabet_size> rank_to_char_table{
[]() constexpr
{
std::array<char_type, alphabet_size>
chars{'.', ':', ',', '-', '_', '~', ';', '<', '(', '[', '{', '>', ')', ']', '}'};
// pseudoknot letters
for (rank_type rnk = 15u; rnk + 1u < alphabet_size; rnk += 2u)
{
char_type const off = static_cast<char_type>((rnk - 15u) / 2u);
chars[rnk] = 'A' + off;
chars[rnk + 1u] = 'a' + off;
}
return chars;
}()};
static constexpr std::array<rank_type, 256> char_to_rank_table{[]() constexpr
{
std::array<rank_type, 256> rank_table{};
rank_table.fill(6u);
// set alphabet values
for (rank_type rnk = 0u; rnk < alphabet_size;
++rnk)
rank_table[rank_to_char_table[rnk]] = rnk;
return rank_table;
}()};
static constexpr std::array<int8_t, SIZE> interaction_tab{
[]() constexpr
{
static_assert(static_cast<int16_t>(std::numeric_limits<int8_t>::max()) >= SIZE);
static_assert(-static_cast<int16_t>(std::numeric_limits<int8_t>::min()) >= SIZE);
std::array<int8_t, alphabet_size> interaction_table{};
int8_t cnt_open = 0;
int8_t cnt_close = 0;
for (rank_type rnk = 0u; rnk <= 6u; ++rnk)
interaction_table[rnk] = 0;
for (rank_type rnk = 7u; rnk <= 10u; ++rnk)
interaction_table[rnk] = --cnt_open;
for (rank_type rnk = 11u; rnk <= 14u; ++rnk)
interaction_table[rnk] = ++cnt_close;
for (rank_type rnk = 15u; rnk + 1u < alphabet_size; rnk += 2u)
{
interaction_table[rnk] = --cnt_open;
interaction_table[rnk + 1u] = ++cnt_close;
}
return interaction_table;
}()};
};
using wuss51 = wuss<51>;
inline namespace literals
{
constexpr wuss51 operator""_wuss51(char const ch) noexcept
{
return wuss51{}.assign_char(ch);
}
SEQAN3_WORKAROUND_LITERAL std::vector<wuss51> operator""_wuss51(char const * str, std::size_t len)
{
std::vector<wuss51> vec;
vec.resize(len);
for (size_t idx = 0ul; idx < len; ++idx)
vec[idx].assign_char(str[idx]);
return vec;
}
} // namespace literals
} // namespace seqan3
concept.hpp
Provides seqan3::rna_structure_alphabet.
alphabet_base.hpp
Provides seqan3::alphabet_base.
seqan3::alphabet_base< wuss< SIZE >, SIZE >::assign_char
constexpr wuss< SIZE > & assign_char(char_type const chr) noexcept
Definition alphabet_base.hpp:160
seqan3::alphabet_base< wuss< 51 >, 51 >::alphabet_base
constexpr alphabet_base() noexcept=default
seqan3::alphabet_base< wuss< SIZE >, SIZE >::to_rank
constexpr rank_type to_rank() const noexcept
Definition alphabet_base.hpp:134
seqan3::alphabet_base< wuss< SIZE >, SIZE >::rank_type
detail::min_viable_uint_t< size - 1 > rank_type
Definition alphabet_base.hpp:77
seqan3::alphabet_base< wuss< SIZE >, SIZE >::alphabet_size
static constexpr detail::min_viable_uint_t< size > alphabet_size
Definition alphabet_base.hpp:196
seqan3::alphabet_base< wuss< SIZE >, SIZE >::to_char
constexpr char_type to_char() const noexcept
Definition alphabet_base.hpp:112
seqan3::alphabet_base< wuss< SIZE >, SIZE >::char_type
std::conditional_t< std::same_as< char, void >, char, char > char_type
Definition alphabet_base.hpp:69
seqan3::wuss::to_rank
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition alphabet_base.hpp:134
seqan3::wuss< 51 >::alphabet_size
static constexpr detail::min_viable_uint_t< size > alphabet_size
seqan3::wuss< 51 >::max_pseudoknot_depth
static constexpr uint8_t max_pseudoknot_depth
Definition wuss.hpp:129
seqan3::wuss::is_pair_close
constexpr bool is_pair_close() const noexcept
Check whether the character represents a leftward interaction in an RNA structure.
Definition wuss.hpp:108
seqan3::wuss< 51 >::is_pair_open
constexpr bool is_pair_open() const noexcept
Definition wuss.hpp:98
seqan3::wuss::pseudoknot_id
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
seqan3::wuss::wuss51
wuss< 51 > wuss51
Alias for the default type wuss51.
Definition wuss.hpp:230
seqan3::wuss::wuss
constexpr wuss() noexcept=default
Defaulted.
seqan3::wuss::is_unpaired
constexpr bool is_unpaired() const noexcept
Check whether the character represents an unpaired position in an RNA structure.
Definition wuss.hpp:118
cmath
std::array::fill
T fill(T... args)
limits
std::make_unsigned_t
std::numeric_limits::max
T max(T... args)
std::numeric_limits::min
T min(T... args)
seqan3::literals
The SeqAn namespace for literals.
seqan3
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
seqan3::update_notifications::off
@ off
Automatic update notifications should be disabled.
Definition auxiliary.hpp:270
std::optional
SEQAN3_WORKAROUND_LITERAL
#define SEQAN3_WORKAROUND_LITERAL
Our char literals returning std::vector should be constexpr if constexpr std::vector is supported.
Definition platform.hpp:310
std::vector::resize
T resize(T... args)
std::size_t
transform.hpp
Provides utilities for modifying characters.
vector
Hide me