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  // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
375  // we catch that error in debug-builds to make this function consistent with the behaviour in
376  // release-builds (-DNDEBUG).
377 #ifndef NDEBUG
378  try { assert(n < size()); } catch (std::invalid_argument const &) {}
379 #endif
380 
381  switch (tf)
382  {
384  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
385  break;
387  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
388  break;
390  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
391  break;
393  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
394  break;
396  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
397  break;
399  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
400  break;
401  default:
403  break;
404  }
405  }
406 
409  {
410  // size will throw (only in debug-builds!) if translation_frames is neither (FWD|REV)_FRAME_(0|1|2),
411  // we catch that error in debug-builds to make this function consistent with the behaviour in
412  // release-builds (-DNDEBUG).
413 #ifndef NDEBUG
414  try { assert(n < size()); } catch (std::invalid_argument const &) {}
415 #endif
416 
417  switch (tf)
418  {
420  return translate_triplet((urange)[n * 3], (urange)[n * 3 + 1], (urange)[n * 3 + 2]);
421  break;
423  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 1]), complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]));
424  break;
426  return translate_triplet((urange)[n * 3 + 1], (urange)[n * 3 + 2], (urange)[n * 3 + 3]);
427  break;
429  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 2]), complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]));
430  break;
432  return translate_triplet((urange)[n * 3 + 2], (urange)[n * 3 + 3], (urange)[n * 3 + 4]);
433  break;
435  return translate_triplet(complement((urange)[(urange).size() - n * 3 - 3]), complement((urange)[(urange).size() - n * 3 - 4]), complement((urange)[(urange).size() - n * 3 - 5]));
436  break;
437  default:
439  break;
440  }
441  }
443 };
444 
446 template <typename urng_t>
448 
449 
451 template <typename urng_t>
453 
454 } // namespace seqan3::detail
455 
456 // ============================================================================
457 // translate_single (adaptor object)
458 // ============================================================================
459 
460 namespace seqan3::views
461 {
462 
510 
511 } // seqan3::views
512 
513 // ============================================================================
514 // view_translate (range definition)
515 // ============================================================================
516 
517 namespace seqan3::detail
518 {
519 
528 template <std::ranges::view urng_t>
530  requires std::ranges::sized_range<urng_t> &&
531  std::ranges::random_access_range<urng_t> &&
534 class view_translate : public std::ranges::view_base
535 {
536 private:
538  urng_t urange;
543 
544 public:
555  using size_type = std::ranges::range_size_t<urng_t>;
557  using difference_type = std::ranges::range_difference_t<urng_t>;
563 
564 protected:
571  // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
572  template <typename t>
573  requires (range_dimension_v<t> == range_dimension_v<value_type> + 1) &&
574  std::is_same_v<std::remove_cvref_t<range_innermost_value_t<value_type>>,
576  static constexpr bool is_compatible_this_aux = true;
579 
580 public:
581 
585  view_translate() noexcept = default;
586  constexpr view_translate(view_translate const & rhs) noexcept = default;
587  constexpr view_translate(view_translate && rhs) noexcept = default;
588  constexpr view_translate & operator=(view_translate const & rhs) noexcept = default;
589  constexpr view_translate & operator=(view_translate && rhs) noexcept = default;
590  ~view_translate() noexcept = default;
591 
596  view_translate(urng_t _urange, translation_frames const _tf = translation_frames::SIX_FRAME)
597  : urange{std::move(_urange)}, tf{_tf}
598  {
611  }
612 
617  template <typename rng_t>
619  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate>) &&
620  std::ranges::viewable_range<rng_t> &&
621  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
624  : view_translate{std::views::all(std::forward<rng_t>(_urange)), _tf}
625  {}
627 
644  iterator begin() noexcept
645  {
646  return {*this, 0};
647  }
648 
650  const_iterator begin() const noexcept
651  {
652  return {*this, 0};
653  }
654 
668  iterator end() noexcept
669  {
670  return {*this, size()};
671  }
672 
674  const_iterator end() const noexcept
675  {
676  return {*this, size()};
677  }
678 
690  size_type size() noexcept
691  {
692  return (size_type) selected_frames.size();
693  }
694 
696  size_type size() const noexcept
697  {
698  return (size_type) selected_frames.size();
699  }
700 
720  {
721  assert(n < size());
723  }
724 
727  {
728  assert(n < size());
730  }
732 };
733 
735 template <typename urng_t>
737  requires std::ranges::sized_range<urng_t> &&
738  std::ranges::random_access_range<urng_t> &&
741 view_translate(urng_t &&, translation_frames const = translation_frames{}) -> view_translate<std::views::all_t<urng_t>>;
742 
743 } // namespace seqan3::detail
744 
745 // ============================================================================
746 // translate (adaptor object)
747 // ============================================================================
748 
749 namespace seqan3::views
750 {
751 
798 inline constexpr auto translate = deep{detail::translate_fn<false>{}};
800 
801 } // 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:408
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:535
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:726
translation_frames tf
The frames that should be used for translation.
Definition: translate.hpp:540
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:557
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:650
reference operator[](size_type const n)
Return the n-th element.
Definition: translate.hpp:719
small_vector< translation_frames, 6 > selected_frames
The selected frames corresponding to the frames required.
Definition: translate.hpp:542
size_type size() noexcept
Returns the number of elements in the view.
Definition: translate.hpp:690
view_translate_single< urng_t > reference
The reference_type.
Definition: translate.hpp:549
view_translate(rng_t &&_urange, translation_frames const _tf=translation_frames::SIX_FRAME)
Construct from another range.
Definition: translate.hpp:623
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: translate.hpp:644
std::ranges::range_size_t< urng_t > size_type
The size_type.
Definition: translate.hpp:555
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: translate.hpp:668
urng_t urange
The data members of view_translate_single.
Definition: translate.hpp:538
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:674
size_type size() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: translate.hpp:696
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:798
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate.hpp:509
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.