Skip to content

Commit 23b8583

Browse files
committed
docs: add example of custom alphabet for seqan2::Dna
1 parent 745c645 commit 23b8583

File tree

6 files changed

+128
-6
lines changed

6 files changed

+128
-6
lines changed

doc/cookbook/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ Here is an example for a dna4-like alphabet:
202202

203203
\snippet test/performance/simd_dna4.hpp cookbook
204204

205+
# Adaptation of seqan2::Dna
206+
207+
In case you want to use `seqan2::Dna` in your SeqAn3 application, you can adapt it to the SeqAn3 alphabet
208+
concepts by specialising the `seqan3::custom::alphabet` class template.
209+
210+
\include test/unit/alphabet/nucleotide/custom_alphabet_seqan2_dna.hpp
211+
205212
# All SeqAn documentation snippets
206213

207214
The following lists all snippets that appear in our documentation.

doc/howto/write_an_alphabet/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,10 @@ from '1', 't' and 'T' for value 1 as well as from '0', 'f' and 'F' for value 0.
188188
\note
189189
You should really make your alphabet types [no-throw-default-constructible](\ref std::is_nothrow_default_constructible)
190190
if you can!
191+
192+
## Adaptation of seqan2::Dna
193+
194+
In case you want to use `seqan2::Dna` in your SeqAn3 application, you can adapt it to the SeqAn3 alphabet
195+
concepts by specialising the `seqan3::custom::alphabet` class template.
196+
197+
\include test/unit/alphabet/nucleotide/custom_alphabet_seqan2_dna.hpp

test/unit/alphabet/nucleotide/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
33
# SPDX-License-Identifier: CC0-1.0
44

5+
seqan3_test (custom_alphabet_seqan2_dna_test.cpp)
56
seqan3_test (dna4_test.cpp)
67
seqan3_test (dna5_test.cpp)
78
seqan3_test (dna15_test.cpp)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
2+
// SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
3+
// SPDX-License-Identifier: CC0-1.0
4+
5+
#pragma once
6+
7+
#include <seqan3/alphabet/concept.hpp>
8+
9+
#include <seqan/basic.h>
10+
#include <seqan/modifier/modifier_functors.h>
11+
12+
// Ranks and letters of `seqan2::Dna` and `seqan3::dna4` are the same:
13+
// 'A' = 0, 'C' = 1, 'G' = 2, 'T' = 3.
14+
template <>
15+
struct seqan3::custom::alphabet<seqan2::Dna>
16+
{
17+
using alphabet_t = seqan2::Dna;
18+
19+
static constexpr size_t alphabet_size = 4u;
20+
21+
static uint8_t to_rank(alphabet_t const a) noexcept
22+
{
23+
return seqan2::ordValue(a);
24+
}
25+
26+
static alphabet_t & assign_rank_to(uint8_t const r, alphabet_t & a) noexcept
27+
{
28+
seqan2::assign(a, r);
29+
return a;
30+
}
31+
32+
static char to_char(alphabet_t const a) noexcept
33+
{
34+
char c;
35+
seqan2::assign(c, a);
36+
return c;
37+
}
38+
39+
static alphabet_t & assign_char_to(char const c, alphabet_t & a) noexcept
40+
{
41+
seqan2::assign(a, c);
42+
return a;
43+
}
44+
45+
static alphabet_t complement(alphabet_t const a) noexcept
46+
{
47+
static seqan2::FunctorComplement<alphabet_t> func;
48+
return func(a);
49+
}
50+
};
51+
52+
// Disable `seqan2::begin` overload for `seqan::Dna`.
53+
// Otherwise, `seqan2::Dna` would be considered a range.
54+
// `seqan2::Dna` is indeed not a range, and assuming otherwise breaks many views.
55+
namespace seqan2
56+
{
57+
58+
void begin(seqan2::Dna) = delete;
59+
60+
} // namespace seqan2
61+
62+
// This is only needed if you want to use `seqan3::debug_stream` with `seqan2::Dna`.
63+
namespace seqan3
64+
{
65+
66+
inline debug_stream_type<char> & operator<<(debug_stream_type<char> & stream, seqan2::Dna const & data)
67+
{
68+
stream << seqan2::convert<char>(data);
69+
return stream;
70+
}
71+
72+
} // namespace seqan3
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
2+
// SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#include <gtest/gtest.h>
6+
7+
#ifdef SEQAN3_HAS_SEQAN2
8+
9+
// # include "../alphabet_constexpr_test_template.hpp"
10+
# include "../alphabet_test_template.hpp"
11+
// # include "../semi_alphabet_constexpr_test_template.hpp"
12+
# include "../semi_alphabet_test_template.hpp"
13+
# include "custom_alphabet_seqan2_dna.hpp"
14+
# include "nucleotide_test_template.hpp"
15+
16+
template <>
17+
struct nucleotide<seqan2::Dna> : public ::testing::Test
18+
{
19+
static constexpr bool skip_trivial_thirdparty = true;
20+
};
21+
22+
INSTANTIATE_TYPED_TEST_SUITE_P(seqan2_dna, alphabet, seqan2::Dna, );
23+
INSTANTIATE_TYPED_TEST_SUITE_P(seqan2_dna, semi_alphabet_test, seqan2::Dna, );
24+
// INSTANTIATE_TYPED_TEST_SUITE_P(seqan2_dna, alphabet_constexpr, seqan2::Dna, );
25+
// INSTANTIATE_TYPED_TEST_SUITE_P(seqan2_dna, semi_alphabet_constexpr, seqan2::Dna, );
26+
INSTANTIATE_TYPED_TEST_SUITE_P(seqan2_dna, nucleotide, seqan2::Dna, );
27+
28+
#endif

test/unit/alphabet/nucleotide/nucleotide_test_template.hpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@
1010
#include <seqan3/alphabet/nucleotide/concept.hpp>
1111

1212
template <typename t>
13-
using nucleotide = ::testing::Test;
13+
struct nucleotide : public ::testing::Test
14+
{
15+
// Do not check the `trivial` concept, because `t` is a third party class and not trivial.
16+
static constexpr bool skip_trivial_thirdparty = false;
17+
};
1418

1519
TYPED_TEST_SUITE_P(nucleotide);
1620

1721
TYPED_TEST_P(nucleotide, concept_check)
1822
{
19-
EXPECT_TRUE(seqan3::trivial<TypeParam>);
23+
if constexpr (!TestFixture::skip_trivial_thirdparty)
24+
{
25+
EXPECT_TRUE(seqan3::trivial<TypeParam>);
26+
}
2027

2128
EXPECT_TRUE(seqan3::nucleotide_alphabet<TypeParam>);
2229
EXPECT_TRUE(seqan3::nucleotide_alphabet<TypeParam &>);
@@ -26,10 +33,10 @@ TYPED_TEST_P(nucleotide, concept_check)
2633

2734
TYPED_TEST_P(nucleotide, complement)
2835
{
29-
EXPECT_EQ(seqan3::complement(TypeParam{}.assign_char('A')), TypeParam{}.assign_char('T'));
30-
EXPECT_EQ(seqan3::complement(TypeParam{}.assign_char('C')), TypeParam{}.assign_char('G'));
31-
EXPECT_EQ(seqan3::complement(TypeParam{}.assign_char('G')), TypeParam{}.assign_char('C'));
32-
EXPECT_EQ(seqan3::complement(TypeParam{}.assign_char('T')), TypeParam{}.assign_char('A'));
36+
EXPECT_EQ(seqan3::complement(seqan3::assign_char_to('A', TypeParam{})), seqan3::assign_char_to('T', TypeParam{}));
37+
EXPECT_EQ(seqan3::complement(seqan3::assign_char_to('C', TypeParam{})), seqan3::assign_char_to('G', TypeParam{}));
38+
EXPECT_EQ(seqan3::complement(seqan3::assign_char_to('G', TypeParam{})), seqan3::assign_char_to('C', TypeParam{}));
39+
EXPECT_EQ(seqan3::complement(seqan3::assign_char_to('T', TypeParam{})), seqan3::assign_char_to('A', TypeParam{}));
3340

3441
using vsize_t = std::decay_t<decltype(seqan3::alphabet_size<TypeParam>)>;
3542

0 commit comments

Comments
 (0)