SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
translate.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 <concepts>
13#include <ranges>
14#include <stdexcept>
15#include <vector>
16
25
26// ============================================================================
27// forwards
28// ============================================================================
29
30namespace seqan3::detail
31{
32
33template <std::ranges::view urng_t>
34 requires std::ranges::sized_range<urng_t> && std::ranges::random_access_range<urng_t>
36class view_translate;
37
38template <std::ranges::view urng_t>
39 requires std::ranges::sized_range<urng_t> && std::ranges::random_access_range<urng_t>
42
43} // namespace seqan3::detail
44
45// ============================================================================
46// translation_frames
47// ============================================================================
48
49namespace seqan3
50{
51
73
77template <>
80
81} // namespace seqan3
82
83namespace seqan3::detail
84{
85
86// ============================================================================
87// translate_fn (adaptor definition for both views)
88// ============================================================================
89
93template <bool single>
95{
99
101 constexpr auto operator()(translation_frames const tf = default_frames) const
102 {
103 return detail::adaptor_from_functor{*this, tf};
104 }
105
111 template <std::ranges::range urng_t>
112 constexpr auto operator()(urng_t && urange, translation_frames const tf = default_frames) const
113 {
114 static_assert(std::ranges::viewable_range<urng_t>,
115 "The range parameter to views::translate[_single] cannot be a temporary of a non-view range.");
116 static_assert(std::ranges::sized_range<urng_t>,
117 "The range parameter to views::translate[_single] must model std::ranges::sized_range.");
118 static_assert(std::ranges::random_access_range<urng_t>,
119 "The range parameter to views::translate[_single] must model std::ranges::random_access_range.");
120 static_assert(
122 "The range parameter to views::translate[_single] must be over elements of seqan3::nucleotide_alphabet.");
123
124 if constexpr (single)
125 return detail::view_translate_single{std::forward<urng_t>(urange), tf};
126 else
127 return detail::view_translate{std::forward<urng_t>(urange), tf};
128 }
129
131 template <std::ranges::range urng_t>
132 constexpr friend auto operator|(urng_t && urange, translate_fn const & me)
133 {
134 return me(std::forward<urng_t>(urange));
135 }
136};
137
138// ============================================================================
139// view_translate_single (range definition)
140// ============================================================================
141
148template <std::ranges::view urng_t>
149 requires std::ranges::sized_range<urng_t> && std::ranges::random_access_range<urng_t>
151class view_translate_single : public std::ranges::view_base
152{
153private:
155 urng_t urange;
159 static constexpr small_string multiple_frame_error{"Error: Invalid type of frame. Choose one out of "
160 "forward_frame0, reverse_frame0, forward_frame1, "
161 "reverse_frame1, forward_frame2 and reverse_frame2."};
162
163public:
174 using size_type = std::ranges::range_size_t<urng_t>;
176 using difference_type = std::ranges::range_difference_t<urng_t>;
182
186 view_translate_single() noexcept = default;
187 constexpr view_translate_single(view_translate_single const & rhs) noexcept = default;
188 constexpr view_translate_single(view_translate_single && rhs) noexcept = default;
189 constexpr view_translate_single & operator=(view_translate_single const & rhs) noexcept = default;
190 constexpr view_translate_single & operator=(view_translate_single && rhs) noexcept = default;
191 ~view_translate_single() noexcept = default;
192
202 urange{std::move(_urange)},
203 tf{_tf}
204 {
205 if (__builtin_popcount(static_cast<uint8_t>(_tf)) > 1)
206 {
208 }
209 }
210
219 template <typename rng_t>
220 requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_single>)
221 && std::ranges::viewable_range<rng_t>
222 && std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
224 view_translate_single{std::views::all(std::forward<rng_t>(_urange)), _tf}
225 {}
227
244 iterator begin() noexcept
245 {
246 return {*this, 0};
247 }
248
250 const_iterator begin() const noexcept
251 {
252 return {*this, 0};
253 }
254
268 iterator end() noexcept
269 {
270 return {*this, size()};
271 }
272
274 const_iterator end() const noexcept
275 {
276 return {*this, size()};
277 }
279
292 {
293 switch (tf)
294 {
296 [[fallthrough]];
298 return std::ranges::size(urange) / 3;
299 break;
301 [[fallthrough]];
303 return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
304 break;
306 [[fallthrough]];
308 return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
309 break;
310 default:
312 break;
313 }
314 }
315
318 {
319 switch (tf)
320 {
322 [[fallthrough]];
324 return std::ranges::size(urange) / 3;
325 break;
327 [[fallthrough]];
329 return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
330 break;
332 [[fallthrough]];
334 return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
335 break;
336 default:
338 break;
339 }
340 }
341
361 {
362 // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
363 // we catch that error in debug-builds to make this function consistent with the behaviour in
364 // release-builds (-DNDEBUG).
365#ifndef NDEBUG
366 try
367 {
368 assert(n < size());
369 }
370 catch (std::invalid_argument const &)
371 {}
372#endif
373
374 switch (tf)
375 {
377 return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
378 break;
380 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]),
381 complement((urange)[(urange).size() - n * 3 - 2]),
382 complement((urange)[(urange).size() - n * 3 - 3]));
383 break;
385 return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
386 break;
388 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]),
389 complement((urange)[(urange).size() - n * 3 - 3]),
390 complement((urange)[(urange).size() - n * 3 - 4]));
391 break;
393 return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
394 break;
396 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]),
397 complement((urange)[(urange).size() - n * 3 - 4]),
398 complement((urange)[(urange).size() - n * 3 - 5]));
399 break;
400 default:
402 break;
403 }
404 }
405
408 {
409 // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
410 // we catch that error in debug-builds to make this function consistent with the behaviour in
411 // release-builds (-DNDEBUG).
412#ifndef NDEBUG
413 try
414 {
415 assert(n < size());
416 }
417 catch (std::invalid_argument const &)
418 {}
419#endif
420
421 switch (tf)
422 {
424 return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
425 break;
427 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]),
428 complement((urange)[(urange).size() - n * 3 - 2]),
429 complement((urange)[(urange).size() - n * 3 - 3]));
430 break;
432 return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
433 break;
435 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]),
436 complement((urange)[(urange).size() - n * 3 - 3]),
437 complement((urange)[(urange).size() - n * 3 - 4]));
438 break;
440 return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
441 break;
443 return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]),
444 complement((urange)[(urange).size() - n * 3 - 4]),
445 complement((urange)[(urange).size() - n * 3 - 5]));
446 break;
447 default:
449 break;
450 }
451 }
453};
454
456template <typename urng_t>
458
460template <typename urng_t>
462
463} // namespace seqan3::detail
464
465// ============================================================================
466// translate_single (adaptor object)
467// ============================================================================
468
469namespace seqan3::views
470{
471
521
522} // namespace seqan3::views
523
524// ============================================================================
525// view_translate (range definition)
526// ============================================================================
527
528namespace seqan3::detail
529{
530
539template <std::ranges::view urng_t>
540 requires std::ranges::sized_range<urng_t> && std::ranges::random_access_range<urng_t>
542class view_translate : public std::ranges::view_base
543{
544private:
546 urng_t urange;
551
552public:
563 using size_type = std::ranges::range_size_t<urng_t>;
565 using difference_type = std::ranges::range_difference_t<urng_t>;
571
572protected:
579 // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
580 template <typename t>
581 requires (range_dimension_v<t> == range_dimension_v<value_type> + 1)
584 static constexpr bool is_compatible_this_aux = true;
587
588public:
592 view_translate() noexcept = default;
593 constexpr view_translate(view_translate const & rhs) noexcept = default;
594 constexpr view_translate(view_translate && rhs) noexcept = default;
595 constexpr view_translate & operator=(view_translate const & rhs) noexcept = default;
596 constexpr view_translate & operator=(view_translate && rhs) noexcept = default;
597 ~view_translate() noexcept = default;
598
620
625 template <typename rng_t>
626 requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate>) && std::ranges::viewable_range<rng_t>
627 && std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
628 view_translate(rng_t && _urange, translation_frames const _tf) :
629 view_translate{std::views::all(std::forward<rng_t>(_urange)), _tf}
630 {}
632
649 iterator begin() noexcept
650 {
651 return {*this, 0};
652 }
653
655 const_iterator begin() const noexcept
656 {
657 return {*this, 0};
658 }
659
673 iterator end() noexcept
674 {
675 return {*this, size()};
676 }
677
679 const_iterator end() const noexcept
680 {
681 return {*this, size()};
682 }
683
695 size_type size() noexcept
696 {
698 }
699
701 size_type size() const noexcept
702 {
704 }
705
725 {
726 assert(n < size());
728 }
729
732 {
733 assert(n < size());
735 }
737};
738
740template <typename urng_t>
741 requires std::ranges::sized_range<urng_t> && std::ranges::random_access_range<urng_t>
744} // namespace seqan3::detail
745
746// ============================================================================
747// translate (adaptor object)
748// ============================================================================
749
750namespace seqan3::views
751{
800inline constexpr auto translate = deep{detail::translate_fn<false>{}};
801
802} // namespace seqan3::views
Provides seqan3::aa27, container aliases and string literals.
Provides seqan3::detail::adaptor_from_functor.
Provides seqan3::add_enum_bitwise_operators.
The twenty-seven letter amino acid alphabet.
Definition aa27.hpp:43
Template for range adaptor closure objects that store arguments and wrap a proto-adaptor.
Definition adaptor_from_functor.hpp:54
A generic random access iterator that delegates most operations to the range.
Definition random_access_iterator.hpp:288
The return type of seqan3::views::translate_single.
Definition translate.hpp:152
const_reference operator[](size_type const n) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:407
size_type size() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:317
reference operator[](size_type const n)
Return the n-th element.
Definition translate.hpp:360
size_type size()
Returns the number of elements in the view.
Definition translate.hpp:291
translation_frames tf
The frame that should be used for translation.
Definition translate.hpp:157
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition translate.hpp:268
std::ranges::range_difference_t< urng_t > difference_type
A signed integer type, usually std::ptrdiff_t.
Definition translate.hpp:176
static constexpr small_string multiple_frame_error
Error thrown if tried to be used with multiple frames.
Definition translate.hpp:159
view_translate_single() noexcept=default
Defaulted.
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition translate.hpp:244
urng_t urange
The input range (of ranges).
Definition translate.hpp:155
view_translate_single(rng_t &&_urange, translation_frames const _tf=translation_frames::forward_frame0)
Construct from another range.
Definition translate.hpp:223
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:274
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:250
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition translate.hpp:174
The return type of seqan3::views::translate.
Definition translate.hpp:543
const_reference operator[](size_type const n) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:731
translation_frames tf
The frames that should be used for translation.
Definition translate.hpp:548
view_translate(rng_t &&_urange, translation_frames const _tf)
Construct from another range.
Definition translate.hpp:628
view_translate() noexcept=default
Defaulted.
std::ranges::range_difference_t< urng_t > difference_type
A signed integer type, usually std::ptrdiff_t.
Definition translate.hpp:565
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:655
reference operator[](size_type const n)
Return the n-th element.
Definition translate.hpp:724
small_vector< translation_frames, 6 > selected_frames
The selected frames corresponding to the frames required.
Definition translate.hpp:550
size_type size() noexcept
Returns the number of elements in the view.
Definition translate.hpp:695
view_translate_single< urng_t > reference
The reference_type.
Definition translate.hpp:557
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition translate.hpp:649
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition translate.hpp:563
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition translate.hpp:673
urng_t urange
The data members of view_translate_single.
Definition translate.hpp:546
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:679
size_type size() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition translate.hpp:701
Implements a small string that can be used for compile time computations.
Definition small_string.hpp:41
constexpr char const * c_str() const noexcept
Returns the content represented as 0-terminated c-style string.
Definition small_string.hpp:342
A constexpr vector implementation with dynamic size at compile time.
Definition small_vector.hpp:44
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition small_vector.hpp:847
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition small_vector.hpp:571
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition deep.hpp:101
Provides various transformation traits used by the range module.
Provides seqan3::views::deep.
Provides seqan3::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:52
constexpr auto complement
Return the complement of a nucleotide object.
Definition alphabet/nucleotide/concept.hpp:102
constexpr auto translate
A view that translates nucleotide into aminoacid alphabet with 1, 2, 3 or 6 frames.
Definition translate.hpp:800
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition translate.hpp:520
typename range_innermost_value< t >::type range_innermost_value_t
Shortcut for seqan3::range_innermost_value (transformation_trait shortcut).
Definition core/range/type_traits.hpp:95
@ single
The text is a single range.
Definition search/fm_index/concept.hpp:90
A concept that indicates whether an alphabet represents nucleotides.
T is_same_v
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
view_translate(urng_t &&, translation_frames const) -> view_translate< std::views::all_t< urng_t > >
Class template argument deduction for view_translate.
view_translate_single(urng_t &&, translation_frames const) -> view_translate_single< std::views::all_t< urng_t > >
Class template argument deduction for view_translate_single.
The SeqAn namespace for views.
Definition char_strictly_to.hpp:19
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
constexpr bool add_enum_bitwise_operators< translation_frames >
Enable bitwise operators for enum translation_frames.
Definition translate.hpp:78
translation_frames
Specialisation values for single and multiple translation frames.
Definition translate.hpp:59
@ forward_frame2
The third forward frame starting at position 2.
@ forward_frame0
The first forward frame starting at position 0.
@ reverse_frames
All reverse frames.
@ forward_frames
All forward frames.
@ reverse_frame0
The first reverse frame starting at position 0.
@ forward_reverse2
The first third and third reverse frame.
@ reverse_frame2
The third reverse frame starting at position 2.
@ forward_frame1
The second forward frame starting at position 1.
@ reverse_frame1
The second reverse frame starting at position 1.
@ forward_reverse0
The first forward and first reverse frame.
@ forward_reverse1
The second forward and second reverse frame.
A constexpr string implementation to manipulate string literals at compile time.
Definition of the range adaptor object type for seqan3::views::translate and seqan3::views::translate...
Definition translate.hpp:95
constexpr auto operator()(translation_frames const tf=default_frames) const
Store the argument and return a range adaptor closure object.
Definition translate.hpp:101
constexpr auto operator()(urng_t &&urange, translation_frames const tf=default_frames) const
Directly return an instance of the view, initialised with the given parameters.
Definition translate.hpp:112
static constexpr translation_frames default_frames
The default frames parameter for the translation view adaptors.
Definition translate.hpp:97
constexpr friend auto operator|(urng_t &&urange, translate_fn const &me)
This adaptor is usable without setting the frames parameter in which case the default is chosen.
Definition translate.hpp:132
Provides functions for translating a triplet of nucleotides into an amino acid.
Hide me