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 
69 enum class translation_frames : uint8_t
70 {
71  FWD_FRAME_0 = 1,
72  FWD_FRAME_1 = 1 << 1,
73  FWD_FRAME_2 = 1 << 2,
74  REV_FRAME_0 = 1 << 3,
75  REV_FRAME_1 = 1 << 4,
76  REV_FRAME_2 = 1 << 5,
82  SIX_FRAME = FWD | REV
83 };
84 
88 template <>
91 
92 }
93 
94 namespace seqan3::detail
95 {
96 
97 // ============================================================================
98 // translate_fn (adaptor definition for both views)
99 // ============================================================================
100 
104 template <bool single>
106 {
111 
113  constexpr auto operator()(translation_frames const tf = default_frames) const
114  {
115  return detail::adaptor_from_functor{*this, tf};
116  }
117 
123  template <std::ranges::range urng_t>
124  constexpr auto operator()(urng_t && urange, translation_frames const tf = default_frames) const
125  {
126  static_assert(std::ranges::viewable_range<urng_t>,
127  "The range parameter to views::translate[_single] cannot be a temporary of a non-view range.");
128  static_assert(std::ranges::sized_range<urng_t>,
129  "The range parameter to views::translate[_single] must model std::ranges::sized_range.");
130  static_assert(std::ranges::random_access_range<urng_t>,
131  "The range parameter to views::translate[_single] must model std::ranges::random_access_range.");
132  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<urng_t>>,
133  "The range parameter to views::translate[_single] must be over elements of seqan3::nucleotide_alphabet.");
134 
135  if constexpr (single)
136  return detail::view_translate_single{std::forward<urng_t>(urange), tf};
137  else
138  return detail::view_translate{std::forward<urng_t>(urange), tf};
139  }
140 
142  template <std::ranges::range urng_t>
143  constexpr friend auto operator|(urng_t && urange, translate_fn const & me)
144  {
145  return me(std::forward<urng_t>(urange));
146  }
147 };
148 
149 // ============================================================================
150 // view_translate_single (range definition)
151 // ============================================================================
152 
159 template <std::ranges::view urng_t>
161  requires std::ranges::sized_range<urng_t> &&
162  std::ranges::random_access_range<urng_t> &&
165 class view_translate_single : public std::ranges::view_base
166 {
167 private:
169  urng_t urange;
173  static constexpr small_string multiple_frame_error{"Error: Invalid type of frame. Choose one out of FWD_FRAME_0, "
174  "REV_FRAME_0, FWD_FRAME_1, REV_FRAME_1, FWD_FRAME_2 and "
175  "REV_FRAME_2."};
176 public:
181  using reference = aa27;
185  using value_type = aa27;
187  using size_type = std::ranges::range_size_t<urng_t>;
189  using difference_type = std::ranges::range_difference_t<urng_t>;
195 
199  view_translate_single() noexcept = default;
200  constexpr view_translate_single(view_translate_single const & rhs) noexcept = default;
201  constexpr view_translate_single(view_translate_single && rhs) noexcept = default;
202  constexpr view_translate_single & operator=(view_translate_single const & rhs) noexcept = default;
203  constexpr view_translate_single & operator=(view_translate_single && rhs) noexcept = default;
204  ~view_translate_single() noexcept = default;
205 
206 
215  view_translate_single(urng_t _urange, translation_frames const _tf = translation_frames::FWD_FRAME_0)
216  : urange{std::move(_urange)}, tf{_tf}
217  {
218  if (__builtin_popcount(static_cast<uint8_t>(_tf)) > 1)
219  {
221  }
222  }
223 
232  template <typename rng_t>
234  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_single>) &&
235  std::ranges::viewable_range<rng_t> &&
236  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
239  : view_translate_single{std::views::all(std::forward<rng_t>(_urange)), _tf}
240  {}
242 
259  iterator begin() noexcept
260  {
261  return {*this, 0};
262  }
263 
265  const_iterator begin() const noexcept
266  {
267  return {*this, 0};
268  }
269 
283  iterator end() noexcept
284  {
285  return {*this, size()};
286  }
287 
289  const_iterator end() const noexcept
290  {
291  return {*this, size()};
292  }
294 
307  {
308  switch (tf)
309  {
311  [[fallthrough]];
313  return std::ranges::size(urange) / 3;
314  break;
316  [[fallthrough]];
318  return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
319  break;
321  [[fallthrough]];
323  return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
324  break;
325  default:
327  break;
328  }
329  }
330 
332  size_type size() const
333  {
334  switch (tf)
335  {
337  [[fallthrough]];
339  return std::ranges::size(urange) / 3;
340  break;
342  [[fallthrough]];
344  return (std::max<size_type>(std::ranges::size(urange), 1) - 1) / 3;
345  break;
347  [[fallthrough]];
349  return (std::max<size_type>(std::ranges::size(urange), 2) - 2) / 3;
350  break;
351  default:
353  break;
354  }
355  }
356 
376  {
377  // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
378  // we catch that error in debug-builds to make this function consistent with the behaviour in
379  // release-builds (-DNDEBUG).
380 #ifndef NDEBUG
381  try { assert(n < size()); } catch (std::invalid_argument const &) {}
382 #endif
383 
384  switch (tf)
385  {
387  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
388  break;
390  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
391  break;
393  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
394  break;
396  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
397  break;
399  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
400  break;
402  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
403  break;
404  default:
406  break;
407  }
408  }
409 
412  {
413  // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
414  // we catch that error in debug-builds to make this function consistent with the behaviour in
415  // release-builds (-DNDEBUG).
416 #ifndef NDEBUG
417  try { assert(n < size()); } catch (std::invalid_argument const &) {}
418 #endif
419 
420  switch (tf)
421  {
423  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
424  break;
426  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
427  break;
429  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
430  break;
432  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
433  break;
435  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
436  break;
438  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
439  break;
440  default:
442  break;
443  }
444  }
446 };
447 
449 template <typename urng_t>
451 
452 
454 template <typename urng_t>
456 
457 } // namespace seqan3::detail
458 
459 // ============================================================================
460 // translate_single (adaptor object)
461 // ============================================================================
462 
463 namespace seqan3::views
464 {
465 
515 
516 } // seqan3::views
517 
518 // ============================================================================
519 // view_translate (range definition)
520 // ============================================================================
521 
522 namespace seqan3::detail
523 {
524 
533 template <std::ranges::view urng_t>
535  requires std::ranges::sized_range<urng_t> &&
536  std::ranges::random_access_range<urng_t> &&
539 class view_translate : public std::ranges::view_base
540 {
541 private:
543  urng_t urange;
548 
549 public:
560  using size_type = std::ranges::range_size_t<urng_t>;
562  using difference_type = std::ranges::range_difference_t<urng_t>;
568 
569 protected:
576  // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
577  template <typename t>
578  requires (range_dimension_v<t> == range_dimension_v<value_type> + 1) &&
579  std::is_same_v<std::remove_cvref_t<range_innermost_value_t<value_type>>,
581  static constexpr bool is_compatible_this_aux = true;
584 
585 public:
586 
590  view_translate() noexcept = default;
591  constexpr view_translate(view_translate const & rhs) noexcept = default;
592  constexpr view_translate(view_translate && rhs) noexcept = default;
593  constexpr view_translate & operator=(view_translate const & rhs) noexcept = default;
594  constexpr view_translate & operator=(view_translate && rhs) noexcept = default;
595  ~view_translate() noexcept = default;
596 
601  view_translate(urng_t _urange, translation_frames const _tf = translation_frames::SIX_FRAME)
602  : urange{std::move(_urange)}, tf{_tf}
603  {
616  }
617 
622  template <typename rng_t>
624  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate>) &&
625  std::ranges::viewable_range<rng_t> &&
626  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  {}
631 
633  #ifdef SEQAN3_DEPRECATED_310
634  template <typename rng_t>
636  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate>) &&
637  std::ranges::viewable_range<rng_t> &&
638  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
640  view_translate(rng_t && _urange)
641  : view_translate{std::views::all(std::forward<rng_t>(_urange)), translation_frames::SIX_FRAME}
642  {}
643  #endif // SEQAN3_DEPRECATED_310
645 
662  iterator begin() noexcept
663  {
664  return {*this, 0};
665  }
666 
668  const_iterator begin() const noexcept
669  {
670  return {*this, 0};
671  }
672 
686  iterator end() noexcept
687  {
688  return {*this, size()};
689  }
690 
692  const_iterator end() const noexcept
693  {
694  return {*this, size()};
695  }
696 
708  size_type size() noexcept
709  {
710  return (size_type) selected_frames.size();
711  }
712 
714  size_type size() const noexcept
715  {
716  return (size_type) selected_frames.size();
717  }
718 
738  {
739  assert(n < size());
741  }
742 
745  {
746  assert(n < size());
748  }
750 };
751 
755 #ifdef SEQAN3_DEPRECATED_310
756 template <typename urng_t>
758  requires std::ranges::sized_range<urng_t> &&
759  std::ranges::random_access_range<urng_t> &&
763 #endif // SEQAN3_DEPRECATED_310
764 
766 template <typename urng_t>
768  requires std::ranges::sized_range<urng_t> &&
769  std::ranges::random_access_range<urng_t> &&
773 } // namespace seqan3::detail
774 
775 // ============================================================================
776 // translate (adaptor object)
777 // ============================================================================
778 
779 namespace seqan3::views
780 {
781 
834 inline constexpr auto translate = deep{detail::translate_fn<false>{}};
836 
837 } // 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:166
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:411
size_type size() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:332
reference operator[](size_type const n)
Return the n-th element.
Definition: translate.hpp:375
size_type size()
Returns the number of elements in the view.
Definition: translate.hpp:306
translation_frames tf
The frame that should be used for translation.
Definition: translate.hpp:171
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: translate.hpp:283
std::ranges::range_difference_t< urng_t > difference_type
A signed integer type, usually std::ptrdiff_t.
Definition: translate.hpp:189
view_translate_single(rng_t &&_urange, translation_frames const _tf=translation_frames::FWD_FRAME_0)
Construct from another range.
Definition: translate.hpp:238
static constexpr small_string multiple_frame_error
Error thrown if tried to be used with multiple frames.
Definition: translate.hpp:173
view_translate_single() noexcept=default
Defaulted.
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: translate.hpp:259
urng_t urange
The input range (of ranges).
Definition: translate.hpp:169
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:289
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:265
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition: translate.hpp:187
The return type of seqan3::views::translate.
Definition: translate.hpp:540
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:744
translation_frames tf
The frames that should be used for translation.
Definition: translate.hpp:545
view_translate(rng_t &&_urange)
Definition: translate.hpp:640
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:562
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:668
reference operator[](size_type const n)
Return the n-th element.
Definition: translate.hpp:737
small_vector< translation_frames, 6 > selected_frames
The selected frames corresponding to the frames required.
Definition: translate.hpp:547
size_type size() noexcept
Returns the number of elements in the view.
Definition: translate.hpp:708
view_translate_single< urng_t > reference
The reference_type.
Definition: translate.hpp:554
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: translate.hpp:662
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition: translate.hpp:560
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: translate.hpp:686
urng_t urange
The data members of view_translate_single.
Definition: translate.hpp:543
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:692
size_type size() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:714
Implements a small string that can be used for compile time computations.
Definition: small_string.hpp:44
constexpr char const * c_str() const noexcept
Returns the content represented as 0-terminated c-style string.
Definition: small_string.hpp:345
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition: small_vector.hpp:861
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: small_vector.hpp:590
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition: deep.hpp:103
The Concepts library.
Provides various transformation traits used by the range module.
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:104
@ 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:834
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate.hpp:514
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 &&) -> view_translate< std::views::all_t< urng_t >>
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_to.hpp:22
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:89
translation_frames
Specialisation values for single and multiple translation frames.
Definition: translate.hpp:70
@ 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:106
constexpr auto operator()(translation_frames const tf=default_frames) const
Store the argument and return a range adaptor closure object.
Definition: translate.hpp:113
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:124
static constexpr translation_frames default_frames
The default frames parameter for the translation view adaptors.
Definition: translate.hpp:108
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:143
Provides functions for translating a triplet of nucleotides into an amino acid.
Provides seqan3::views::deep.