BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
translate_single.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <concepts>
17#include <ranges>
18#include <stdexcept>
19#include <vector>
20
26
27// ============================================================================
28// translate_fn (adaptor definition for both views)
29// ============================================================================
30
31namespace bio::ranges::detail
32{
33
36struct translate_single_fn
37{
40
42 constexpr auto operator()(alphabet::translation_frames const tf = default_frames) const
43 {
44 return detail::adaptor_from_functor{*this, tf};
45 }
46
52 template <std::ranges::range urng_t>
53 constexpr auto operator()(urng_t && urange, alphabet::translation_frames const tf = default_frames) const
54 {
55 static_assert(std::ranges::viewable_range<urng_t>,
56 "The range parameter to views::translate_single must be viewable.");
57 static_assert(std::ranges::sized_range<urng_t>,
58 "The range parameter to views::translate_single must model std::ranges::sized_range.");
59 static_assert(std::ranges::random_access_range<urng_t>,
60 "The range parameter to views::translate_single must model std::ranges::random_access_range.");
61 static_assert(alphabet::nucleotide<std::ranges::range_reference_t<urng_t>>,
62 "The range parameter to views::translate_single must be over elements of "
63 "bio::alphabet::alphabet::nucleotide.");
64
65 /* frames */
66 if (size_t const num_frames = std::popcount(static_cast<uint8_t>(tf));
67 num_frames > 1 ||
68 static_cast<uint8_t>(tf) > static_cast<uint8_t>(alphabet::translation_frames::REV_FRAME_2))
69 {
71 "Error: Invalid type of frame. Choose one out of FWD_FRAME_0, "
72 "REV_FRAME_0, FWD_FRAME_1, REV_FRAME_1, FWD_FRAME_2 and "
73 "REV_FRAME_2."};
74 }
75
76 /* size */
77 size_t const old_size = std::ranges::size(urange);
78 size_t const new_size = comp_new_size(old_size, tf);
79
80 return detail::view_transform_by_pos{
81 std::forward<urng_t>(urange),
82 trans_fn{.old_size = old_size, .new_size = new_size, .tf = tf},
83 new_size
84 };
85 }
86
88 template <std::ranges::range urng_t>
89 constexpr friend auto operator|(urng_t && urange, translate_single_fn const & me)
90 {
91 return me(std::forward<urng_t>(urange));
92 }
93
94private:
96 static size_t comp_new_size(size_t const old_size, alphabet::translation_frames const tf)
97 {
98 switch (tf)
99 {
101 [[fallthrough]];
103 return old_size / 3;
105 [[fallthrough]];
107 return (std::max<size_t>(old_size, 1) - 1) / 3;
109 [[fallthrough]];
111 return (std::max<size_t>(old_size, 2) - 2) / 3;
112 default: /* GCOVR_EXCL_LINE */
114 break; /* GCOVR_EXCL_LINE */
115 }
116
118 }
119
121 struct trans_fn
122 {
124 size_t old_size{};
126 size_t new_size{};
129
131 auto operator()(auto && urange2, size_t const n) const
132 {
133 assert(n < new_size);
134 switch (tf) //TODO create function ptr so we do not need to switch every time? → benchmark
135 {
137 return alphabet::translate_triplet(urange2[n * 3], urange2[n * 3 + 1], urange2[n * 3 + 2]);
139 return alphabet::translate_triplet(alphabet::complement(urange2[old_size - n * 3 - 1]),
140 alphabet::complement(urange2[old_size - n * 3 - 2]),
141 alphabet::complement(urange2[old_size - n * 3 - 3]));
143 return alphabet::translate_triplet(urange2[n * 3 + 1], urange2[n * 3 + 2], urange2[n * 3 + 3]);
145 return alphabet::translate_triplet(alphabet::complement(urange2[old_size - n * 3 - 2]),
146 alphabet::complement(urange2[old_size - n * 3 - 3]),
147 alphabet::complement(urange2[old_size - n * 3 - 4]));
149 return alphabet::translate_triplet(urange2[n * 3 + 2], urange2[n * 3 + 3], urange2[n * 3 + 4]);
151 return alphabet::translate_triplet(alphabet::complement(urange2[old_size - n * 3 - 3]),
152 alphabet::complement(urange2[old_size - n * 3 - 4]),
153 alphabet::complement(urange2[old_size - n * 3 - 5]));
154 default: /* GCOVR_EXCL_LINE */
156 break; /* GCOVR_EXCL_LINE */
157 }
159 }
160 };
161};
162
163} // namespace bio::ranges::detail
164
165// ============================================================================
166// translate_single (adaptor object)
167// ============================================================================
168
169namespace bio::ranges::views
170{
171
225inline constexpr auto translate_single = deep{detail::translate_single_fn{}};
226
227} // namespace bio::ranges::views
Provides bio::alphabet::aa27, container aliases and string literals.
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition: deep.hpp:104
#define BIOCPP_UNREACHABLE
A macro to mark unreachable code.
Definition: core.hpp:186
Provides bio::views::deep.
Provides bio::alphabet::dna5, container aliases and string literals.
constexpr aa27 translate_triplet(nucl_type const &n1, nucl_type const &n2, nucl_type const &n3) noexcept
Translate one nucleotide triplet into single amino acid (single nucleotide interface).
Definition: translation.hpp:54
translation_frames
Specialisation values for single and multiple translation frames.
Definition: translation.hpp:85
@ REV_FRAME_0
The first reverse frame starting at position 0.
@ REV_FRAME_1
The second reverse frame starting at position 1.
@ FWD_FRAME_2
The third forward frame starting at position 2.
@ FWD_FRAME_1
The second forward frame starting at position 1.
@ REV_FRAME_2
The third reverse frame starting at position 2.
@ FWD_FRAME_0
The first forward frame starting at position 0.
constexpr auto complement
Return the complement of a nucleotide object.
Definition: concept.hpp:68
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate_single.hpp:225
constexpr translation_frames operator|(translation_frames lhs, translation_frames rhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:111
The BioC++ namespace for views.
T popcount(T... args)
Provides bio::views::transform_by_pos.
Provides functions for translating a triplet of nucleotides into an amino acid.