SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
translate.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <seqan3/std/concepts>
16 #include <seqan3/std/ranges>
17 #include <vector>
18 #include <stdexcept>
19 
30 
31 // ============================================================================
32 // forwards
33 // ============================================================================
34 
35 namespace seqan3::detail
36 {
37 
38 template <std::ranges::view urng_t>
40  requires std::ranges::sized_range<urng_t> &&
41  std::ranges::random_access_range<urng_t> &&
44 class view_translate;
45 
46 template <std::ranges::view urng_t>
48  requires std::ranges::sized_range<urng_t> &&
49  std::ranges::random_access_range<urng_t> &&
53 
54 } // namespace seqan3::detail
55 
56 // ============================================================================
57 // translation_frames
58 // ============================================================================
59 
60 namespace seqan3
61 {
62 
66 enum class translation_frames : uint8_t
67 {
68  FWD_FRAME_0 = 1,
69  FWD_FRAME_1 = 1 << 1,
70  FWD_FRAME_2 = 1 << 2,
71  REV_FRAME_0 = 1 << 3,
72  REV_FRAME_1 = 1 << 4,
73  REV_FRAME_2 = 1 << 5,
79  SIX_FRAME = FWD | REV
80 };
81 
85 template <>
88 
89 }
90 
91 namespace seqan3::detail
92 {
93 
94 // ============================================================================
95 // translate_fn (adaptor definition for both views)
96 // ============================================================================
97 
101 template <bool single>
103 {
108 
110  constexpr auto operator()(translation_frames const tf = default_frames) const
111  {
112  return detail::adaptor_from_functor{*this, tf};
113  }
114 
120  template <std::ranges::range urng_t>
121  constexpr auto operator()(urng_t && urange, translation_frames const tf = default_frames) const
122  {
123  static_assert(std::ranges::viewable_range<urng_t>,
124  "The range parameter to views::translate[_single] cannot be a temporary of a non-view range.");
125  static_assert(std::ranges::sized_range<urng_t>,
126  "The range parameter to views::translate[_single] must model std::ranges::sized_range.");
127  static_assert(std::ranges::random_access_range<urng_t>,
128  "The range parameter to views::translate[_single] must model std::ranges::random_access_range.");
129  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<urng_t>>,
130  "The range parameter to views::translate[_single] must be over elements of seqan3::nucleotide_alphabet.");
131 
132  if constexpr (single)
133  return detail::view_translate_single{std::forward<urng_t>(urange), tf};
134  else
135  return detail::view_translate{std::forward<urng_t>(urange), tf};
136  }
137 
139  template <std::ranges::range urng_t>
140  constexpr friend auto operator|(urng_t && urange, translate_fn const & me)
141  {
142  return me(std::forward<urng_t>(urange));
143  }
144 };
145 
146 // ============================================================================
147 // view_translate_single (range definition)
148 // ============================================================================
149 
156 template <std::ranges::view urng_t>
158  requires std::ranges::sized_range<urng_t> &&
159  std::ranges::random_access_range<urng_t> &&
162 class view_translate_single : public std::ranges::view_base
163 {
164 private:
166  urng_t urange;
170  static constexpr small_string multiple_frame_error{"Error: Invalid type of frame. Choose one out of FWD_FRAME_0, "
171  "REV_FRAME_0, FWD_FRAME_1, REV_FRAME_1, FWD_FRAME_2 and "
172  "REV_FRAME_2."};
173 public:
178  using reference = aa27;
182  using value_type = aa27;
184  using size_type = std::ranges::range_size_t<urng_t>;
186  using difference_type = std::ranges::range_difference_t<urng_t>;
192 
196  view_translate_single() noexcept = default;
197  constexpr view_translate_single(view_translate_single const & rhs) noexcept = default;
198  constexpr view_translate_single(view_translate_single && rhs) noexcept = default;
199  constexpr view_translate_single & operator=(view_translate_single const & rhs) noexcept = default;
200  constexpr view_translate_single & operator=(view_translate_single && rhs) noexcept = default;
201  ~view_translate_single() noexcept = default;
202 
203 
212  view_translate_single(urng_t _urange, translation_frames const _tf = translation_frames::FWD_FRAME_0)
213  : urange{std::move(_urange)}, tf{_tf}
214  {
215  if (__builtin_popcount(static_cast<uint8_t>(_tf)) > 1)
216  {
218  }
219  }
220 
229  template <typename rng_t>
231  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_single>) &&
232  std::ranges::viewable_range<rng_t> &&
233  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
236  : view_translate_single{std::views::all(std::forward<rng_t>(_urange)), _tf}
237  {}
239 
256  iterator begin() noexcept
257  {
258  return {*this, 0};
259  }
260 
262  const_iterator begin() const noexcept
263  {
264  return {*this, 0};
265  }
266 
280  iterator end() noexcept
281  {
282  return {*this, size()};
283  }
284 
286  const_iterator end() const noexcept
287  {
288  return {*this, size()};
289  }
291 
304  {
305  switch (tf)
306  {
308  [[fallthrough]];
310  return std::ranges::size(urange) / 3;
311  break;
313  [[fallthrough]];
315  return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
316  break;
318  [[fallthrough]];
320  return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
321  break;
322  default:
324  break;
325  }
326  }
327 
329  size_type size() const
330  {
331  switch (tf)
332  {
334  [[fallthrough]];
336  return std::ranges::size(urange) / 3;
337  break;
339  [[fallthrough]];
341  return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
342  break;
344  [[fallthrough]];
346  return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
347  break;
348  default:
350  break;
351  }
352  }
353 
373  {
374  assert(n < size());
375  switch (tf)
376  {
378  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
379  break;
381  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
382  break;
384  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
385  break;
387  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
388  break;
390  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
391  break;
393  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
394  break;
395  default:
397  break;
398  }
399  }
400 
403  {
404  assert(n < size());
405  switch (tf)
406  {
408  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
409  break;
411  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
412  break;
414  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
415  break;
417  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
418  break;
420  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
421  break;
423  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
424  break;
425  default:
427  break;
428  }
429  }
431 };
432 
434 template <typename urng_t>
436 
437 
439 template <typename urng_t>
441 
442 } // namespace seqan3::detail
443 
444 // ============================================================================
445 // translate_single (adaptor object)
446 // ============================================================================
447 
448 namespace seqan3::views
449 {
450 
498 
499 } // seqan3::views
500 
501 // ============================================================================
502 // view_translate (range definition)
503 // ============================================================================
504 
505 namespace seqan3::detail
506 {
507 
516 template <std::ranges::view urng_t>
518  requires std::ranges::sized_range<urng_t> &&
519  std::ranges::random_access_range<urng_t> &&
522 class view_translate : public std::ranges::view_base
523 {
524 private:
526  urng_t urange;
531 
532 public:
543  using size_type = std::ranges::range_size_t<urng_t>;
545  using difference_type = std::ranges::range_difference_t<urng_t>;
551 
552 protected:
559  // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
560  template <typename t>
561  requires (range_dimension_v<t> == range_dimension_v<value_type> + 1) &&
562  std::is_same_v<std::remove_cvref_t<range_innermost_value_t<value_type>>,
564  static constexpr bool is_compatible_this_aux = true;
567 
568 public:
569 
573  view_translate() noexcept = default;
574  constexpr view_translate(view_translate const & rhs) noexcept = default;
575  constexpr view_translate(view_translate && rhs) noexcept = default;
576  constexpr view_translate & operator=(view_translate const & rhs) noexcept = default;
577  constexpr view_translate & operator=(view_translate && rhs) noexcept = default;
578  ~view_translate() noexcept = default;
579 
584  view_translate(urng_t _urange, translation_frames const _tf = translation_frames::SIX_FRAME)
585  : urange{std::move(_urange)}, tf{_tf}
586  {
599  }
600 
605  template <typename rng_t>
607  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate>) &&
608  std::ranges::viewable_range<rng_t> &&
609  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
612  : view_translate{std::views::all(std::forward<rng_t>(_urange)), _tf}
613  {}
615 
632  iterator begin() noexcept
633  {
634  return {*this, 0};
635  }
636 
638  const_iterator begin() const noexcept
639  {
640  return {*this, 0};
641  }
642 
656  iterator end() noexcept
657  {
658  return {*this, size()};
659  }
660 
662  const_iterator end() const noexcept
663  {
664  return {*this, size()};
665  }
666 
678  size_type size() noexcept
679  {
680  return (size_type) selected_frames.size();
681  }
682 
684  size_type size() const noexcept
685  {
686  return (size_type) selected_frames.size();
687  }
688 
708  {
709  assert(n < size());
711  }
712 
715  {
716  assert(n < size());
718  }
720 };
721 
723 template <typename urng_t>
725  requires std::ranges::sized_range<urng_t> &&
726  std::ranges::random_access_range<urng_t> &&
729 view_translate(urng_t &&, translation_frames const = translation_frames{}) -> view_translate<std::views::all_t<urng_t>>;
730 
731 } // namespace seqan3::detail
732 
733 // ============================================================================
734 // translate (adaptor object)
735 // ============================================================================
736 
737 namespace seqan3::views
738 {
739 
786 inline constexpr auto translate = deep{detail::translate_fn<false>{}};
788 
789 } // namespace seqan3::views
Provides seqan3::aa27, container aliases and string literals.
Provides seqan3::add_enum_bitwise_operators.
The twenty-seven letter amino acid alphabet.
Definition: aa27.hpp:46
Template for range adaptor closure objects that store arguments and wrap a proto-adaptor.
Definition: detail.hpp:371
A generic random access iterator that delegates most operations to the range.
Definition: random_access_iterator.hpp:310
The return type of seqan3::views::translate_single.
Definition: translate.hpp:163
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:402
size_type size() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:329
reference operator[](size_type const n)
Return the n-th element.
Definition: translate.hpp:372
size_type size()
Returns the number of elements in the view.
Definition: translate.hpp:303
translation_frames tf
The frame that should be used for translation.
Definition: translate.hpp:168
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: translate.hpp:280
std::ranges::range_difference_t< urng_t > difference_type
A signed integer type, usually std::ptrdiff_t.
Definition: translate.hpp:186
view_translate_single(rng_t &&_urange, translation_frames const _tf=translation_frames::FWD_FRAME_0)
Construct from another range.
Definition: translate.hpp:235
static constexpr small_string multiple_frame_error
Error thrown if tried to be used with multiple frames.
Definition: translate.hpp:170
view_translate_single() noexcept=default
Defaulted.
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: translate.hpp:256
urng_t urange
The input range (of ranges).
Definition: translate.hpp:166
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:286
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:262
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition: translate.hpp:184
The return type of seqan3::views::translate.
Definition: translate.hpp:523
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:714
translation_frames tf
The frames that should be used for translation.
Definition: translate.hpp:528
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:545
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:638
reference operator[](size_type const n)
Return the n-th element.
Definition: translate.hpp:707
small_vector< translation_frames, 6 > selected_frames
The selected frames corresponding to the frames required.
Definition: translate.hpp:530
size_type size() noexcept
Returns the number of elements in the view.
Definition: translate.hpp:678
view_translate_single< urng_t > reference
The reference_type.
Definition: translate.hpp:537
view_translate(rng_t &&_urange, translation_frames const _tf=translation_frames::SIX_FRAME)
Construct from another range.
Definition: translate.hpp:611
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: translate.hpp:632
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition: translate.hpp:543
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: translate.hpp:656
urng_t urange
The data members of view_translate_single.
Definition: translate.hpp:526
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:662
size_type size() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:684
Implements a small string that can be used for compile time computations.
Definition: small_string.hpp:43
constexpr char const * c_str() const noexcept
Returns the content represented as 0-terminated c-style string.
Definition: small_string.hpp:320
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition: small_vector.hpp:756
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: small_vector.hpp:511
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition: deep.hpp:102
The Concepts library.
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:55
constexpr auto complement
Return the complement of a nucleotide object.
Definition: concept.hpp:95
@ single
The text is a single range.
Definition: concept.hpp:84
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:150
constexpr auto translate
A view that translates nucleotide into aminoacid alphabet with 1, 2, 3 or 6 frames.
Definition: translate.hpp:786
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate.hpp:497
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:70
A concept that indicates whether an alphabet represents nucleotides.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
view_translate(urng_t &&, translation_frames const =translation_frames{}) -> 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.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr bool add_enum_bitwise_operators< translation_frames >
Enable bitwise operators for enum translation_frames.
Definition: translate.hpp:86
translation_frames
Specialisation values for single and multiple translation frames.
Definition: translate.hpp:67
@ FWD_REV_0
The first forward and first reverse frame.
@ REV_FRAME_0
The first reverse frame starting at position 0.
@ REV_FRAME_1
The second reverse frame starting at position 1.
@ FWD_REV_2
The first third and third reverse frame.
@ FWD_FRAME_2
The third forward frame starting at position 2.
@ FWD_FRAME_1
The second forward frame starting at position 1.
@ FWD
All forward frames.
@ REV_FRAME_2
The third reverse frame starting at position 2.
@ REV
All reverse frames.
@ FWD_FRAME_0
The first forward frame starting at position 0.
@ FWD_REV_1
The second forward and second reverse frame.
SeqAn specific customisations in the standard namespace.
Provides the seqan3::detail::random_access_iterator class.
Adaptations of concepts from the standard library.
Auxiliary header for the views submodule .
Adaptations of concepts from the Ranges TS.
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:103
constexpr auto operator()(translation_frames const tf=default_frames) const
Store the argument and return a range adaptor closure object.
Definition: translate.hpp:110
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:121
static constexpr translation_frames default_frames
The default frames parameter for the translation view adaptors.
Definition: translate.hpp:105
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:140
Provides functions for translating a triplet of nucleotides into an amino acid.