Loading...
Searching...
No Matches
sam_tag_dictionary.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 <concepts>
#include <map>
#include <variant>
#include <seqan3/core/detail/template_inspection.hpp>
#include <seqan3/utility/char_operations/predicate.hpp>
#include <seqan3/utility/container/small_string.hpp>
namespace seqan3::detail
{
using sam_tag_variant = std::variant<char,
int32_t,
float,
std::string,
std::vector<std::byte>,
std::vector<int8_t>,
std::vector<uint8_t>,
std::vector<int16_t>,
std::vector<uint16_t>,
std::vector<int32_t>,
std::vector<uint32_t>,
std::vector<float>>;
constexpr char sam_tag_type_char[12] = {'A', 'i', 'f', 'Z', 'H', 'B', 'B', 'B', 'B', 'B', 'B', 'B'};
constexpr char sam_tag_type_char_extra[12] = {'\0', '\0', '\0', '\0', '\0', 'c', 'C', 's', 'S', 'i', 'I', 'f'};
} // namespace seqan3::detail
namespace seqan3
{
inline namespace literals
{
template <small_string<2> str> // TODO: better handling if too large string is provided?
constexpr uint16_t operator""_tag()
{
static_assert(str.size() == 2, "Illegal SAM tag: Exactly two characters must be given.");
constexpr char char0 = str[0];
constexpr char char1 = str[1];
static_assert((is_alpha(char0) && is_alnum(char1)), "Illegal SAM tag: a SAM tag must match /[A-Za-z][A-Za-z0-9]/.");
return static_cast<uint16_t>(char0) * 256 + static_cast<uint16_t>(char1);
}
} // namespace literals
template <uint16_t tag_value>
struct sam_tag_type
{
using type = detail::sam_tag_variant;
};
template <uint16_t tag_value>
using sam_tag_type_t = typename sam_tag_type<tag_value>::type;
// clang-format off
template <> struct sam_tag_type<"AM"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"AS"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"BC"_tag> { using type = std::string; };
template <> struct sam_tag_type<"BQ"_tag> { using type = std::string; };
template <> struct sam_tag_type<"BZ"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CB"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CC"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CG"_tag> { using type = std::vector<int32_t>; };
template <> struct sam_tag_type<"CM"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"CO"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CP"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"CQ"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CR"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CS"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CT"_tag> { using type = std::string; };
template <> struct sam_tag_type<"CY"_tag> { using type = std::string; };
template <> struct sam_tag_type<"E2"_tag> { using type = std::string; };
template <> struct sam_tag_type<"FI"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"FS"_tag> { using type = std::string; };
template <> struct sam_tag_type<"FZ"_tag> { using type = std::vector<uint16_t>; };
// template <> struct sam_tag_type<"GC"_tag> {};
// template <> struct sam_tag_type<"GQ"_tag> {};
// template <> struct sam_tag_type<"GS"_tag> {};
template <> struct sam_tag_type<"H0"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"H1"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"H2"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"HI"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"IH"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"LB"_tag> { using type = std::string; };
template <> struct sam_tag_type<"MC"_tag> { using type = std::string; };
template <> struct sam_tag_type<"MD"_tag> { using type = std::string; };
// template <> struct sam_tag_type<"MF"_tag> {};
template <> struct sam_tag_type<"MI"_tag> { using type = std::string; };
template <> struct sam_tag_type<"MQ"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"NH"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"NM"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"OC"_tag> { using type = std::string; };
template <> struct sam_tag_type<"OP"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"OQ"_tag> { using type = std::string; };
template <> struct sam_tag_type<"OX"_tag> { using type = std::string; };
template <> struct sam_tag_type<"PG"_tag> { using type = std::string; };
template <> struct sam_tag_type<"PQ"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"PT"_tag> { using type = std::string; };
template <> struct sam_tag_type<"PU"_tag> { using type = std::string; };
template <> struct sam_tag_type<"Q2"_tag> { using type = std::string; };
template <> struct sam_tag_type<"QT"_tag> { using type = std::string; };
template <> struct sam_tag_type<"QX"_tag> { using type = std::string; };
template <> struct sam_tag_type<"R2"_tag> { using type = std::string; };
template <> struct sam_tag_type<"RG"_tag> { using type = std::string; };
template <> struct sam_tag_type<"RT"_tag> { using type = std::string; };
template <> struct sam_tag_type<"RX"_tag> { using type = std::string; };
// template <> struct sam_tag_type<"S2"_tag> {};
template <> struct sam_tag_type<"SA"_tag> { using type = std::string; };
template <> struct sam_tag_type<"SM"_tag> { using type = int32_t; };
// template <> struct sam_tag_type<"SQ"_tag> {};
template <> struct sam_tag_type<"TC"_tag> { using type = int32_t; };
template <> struct sam_tag_type<"U2"_tag> { using type = std::string; };
template <> struct sam_tag_type<"UQ"_tag> { using type = int32_t; };
// clang-format on
class sam_tag_dictionary : public std::map<uint16_t, detail::sam_tag_variant>
{
private:
using base_type = std::map<uint16_t, detail::sam_tag_variant>;
public:
using variant_type = detail::sam_tag_variant;
template <uint16_t tag>
requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
auto & get() &
{
if ((*this).count(tag) == 0)
(*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
return std::get<sam_tag_type_t<tag>>((*this)[tag]);
}
template <uint16_t tag>
requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
auto && get() &&
{
if ((*this).count(tag) == 0)
(*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
return std::get<sam_tag_type_t<tag>>(std::move((*this)[tag]));
}
template <uint16_t tag>
requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
auto const & get() const &
{
return std::get<sam_tag_type_t<tag>>((*this).at(tag));
}
template <uint16_t tag>
requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
auto const && get() const &&
{
return std::get<sam_tag_type_t<tag>>(std::move((*this).at(tag)));
}
};
} // namespace seqan3
std::string
seqan3::sam_tag_dictionary
The SAM tag dictionary class that stores all optional SAM fields.
Definition sam_tag_dictionary.hpp:327
seqan3::sam_tag_dictionary::variant_type
detail::sam_tag_variant variant_type
The variant type defining all valid SAM tag field types.
Definition sam_tag_dictionary.hpp:334
seqan3::sam_tag_dictionary::get
auto && get() &&
Uses std::map::operator[] for access and default initializes new keys.
Definition sam_tag_dictionary.hpp:365
seqan3::sam_tag_dictionary::get
auto & get() &
Uses std::map::operator[] for access and default initializes new keys.
Definition sam_tag_dictionary.hpp:354
seqan3::sam_tag_dictionary::get
auto const && get() const &&
Uses std::map::at() for access and throws when the key is unknown.
Definition sam_tag_dictionary.hpp:386
seqan3::sam_tag_dictionary::get
auto const & get() const &
Uses std::map::at() for access and throws when the key is unknown.
Definition sam_tag_dictionary.hpp:377
seqan3::is_alpha
constexpr auto is_alpha
Checks whether c is a graphic character.
Definition predicate.hpp:211
map
seqan3::literals
The SeqAn namespace for literals.
seqan3
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
predicate.hpp
Provides character predicates for tokenisation.
small_string.hpp
A constexpr string implementation to manipulate string literals at compile time.
seqan3::sam_tag_type
The generic base class.
Definition sam_tag_dictionary.hpp:165
seqan3::sam_tag_type::type
detail::sam_tag_variant type
The type for all unknown tags with no extra overload defaults to a std::variant.
Definition sam_tag_dictionary.hpp:167
seqan3::sam_tag_type::sam_tag_type_t
typename sam_tag_type< tag_value >::type sam_tag_type_t
Short cut helper for seqan3::sam_tag_type::type.
Definition sam_tag_dictionary.hpp:173
template_inspection.hpp
Provides type traits for working with templates.
variant
Hide me