SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
aligned_sequence_builder.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 <type_traits>
18 #include <vector>
19 
32 
33 namespace seqan3::detail
34 {
35 
53 template <std::ranges::viewable_range range_t>
55 {
56 private:
57  // The following expressions are used to check if the sequence types can be used as template arguments for the
58  // seqan3::gap_decorator. Ranges that do not model std::random_access_range for instance cannot be augmented with
59  // the gap_decorator and need to be copied instead.
60 
62  using unaligned_sequence_type = decltype(std::declval<range_t>() | views::type_reduce | views::slice(0, 1));
63 
64 public:
66  using type = lazy_conditional_t<is_class_template_declarable_with_v<gap_decorator, unaligned_sequence_type>,
69 };
70 
78 template <std::ranges::viewable_range first_sequence_t, std::ranges::viewable_range second_sequence_t>
80 {
85 
87  "first_aligned_t is required to model seqan3::writable_aligned_sequence!");
89  "second_aligned_t is required to model seqan3::writable_aligned_sequence!");
90 
93 };
94 
116 template <std::ranges::viewable_range fst_sequence_t, std::ranges::viewable_range sec_sequence_t>
118 {
119 public:
122 
124  struct [[nodiscard]] result_type
125  {
127  std::pair<size_t, size_t> first_sequence_slice_positions{};
129  std::pair<size_t, size_t> second_sequence_slice_positions{};
133  };
134 
138  constexpr aligned_sequence_builder() = default;
139  constexpr aligned_sequence_builder(aligned_sequence_builder const &) = default;
144 
149  constexpr aligned_sequence_builder(fst_sequence_t fst_rng, sec_sequence_t sec_rng) :
150  fst_rng{views::type_reduce(std::forward<fst_sequence_t>(fst_rng))},
151  sec_rng{views::type_reduce(std::forward<sec_sequence_t>(sec_rng))}
152  {}
154 
169  template <std::ranges::input_range trace_path_t>
170  result_type operator()(trace_path_t && trace_path)
171  {
172  static_assert(std::same_as<std::ranges::range_value_t<trace_path_t>, trace_directions>,
173  "The value type of the trace path must be seqan3::detail::trace_directions");
174 
175  result_type res{};
176  auto trace_it = std::ranges::begin(trace_path);
177  std::tie(res.first_sequence_slice_positions.second, res.second_sequence_slice_positions.second) =
178  std::pair<size_t, size_t>{trace_it.coordinate()};
179 
181 
182  while (trace_it != std::ranges::end(trace_path))
183  {
184  trace_directions last_dir = *trace_it;
185  size_t span = 0;
186  for (; trace_it != std::ranges::end(trace_path) && *trace_it == last_dir; ++trace_it, ++span)
187  {}
188 
189  trace_segments.emplace_back(last_dir, span);
190  }
191 
192  std::tie(res.first_sequence_slice_positions.first, res.second_sequence_slice_positions.first) =
193  std::pair<size_t, size_t>{trace_it.coordinate()};
194 
195  assign_unaligned(std::get<0>(res.alignment),
196  std::views::all(fst_rng) | views::slice(res.first_sequence_slice_positions.first,
197  res.first_sequence_slice_positions.second));
198  assign_unaligned(std::get<1>(res.alignment),
199  std::views::all(sec_rng) | views::slice(res.second_sequence_slice_positions.first,
200  res.second_sequence_slice_positions.second));
201 
202  // Now we need to insert the values.
203  fill_aligned_sequence(trace_segments | std::views::reverse,
204  std::get<0>(res.alignment),
205  std::get<1>(res.alignment));
206 
207  return res;
208  }
209 
210 private:
211 
218  template <typename reverse_traces_t, typename fst_aligned_t, typename sec_aligned_t>
219  void fill_aligned_sequence(reverse_traces_t && rev_traces,
220  fst_aligned_t & fst_aligned,
221  sec_aligned_t & sec_aligned) const
222  {
223  if (std::ranges::empty(rev_traces))
224  return;
225 
226  auto fst_it = std::ranges::begin(fst_aligned);
227  auto sec_it = std::ranges::begin(sec_aligned);
228 
229  for (auto const & [dir, span] : rev_traces)
230  {
232 
233  if (dir == trace_directions::up)
234  fst_it = insert_gap(fst_aligned, fst_it, span);
235 
236  if (dir == trace_directions::left)
237  sec_it = insert_gap(sec_aligned, sec_it, span);
238 
239  fst_it += span;
240  sec_it += span;
241  }
242  }
243 
246 };
247 
253 template <std::ranges::viewable_range fst_sequence_t, std::ranges::viewable_range sec_sequence_t>
254 aligned_sequence_builder(fst_sequence_t &&, sec_sequence_t &&) ->
257 } // namespace seqan3::detail
Includes the aligned_sequence and the related insert_gap and erase_gap functions to enable stl contai...
Builds the alignment for a given pair of sequences and the respective trace.
Definition: aligned_sequence_builder.hpp:118
typename make_pairwise_alignment_type< fst_sequence_t, sec_sequence_t >::type alignment_type
The pairwise alignment type of the two sequences.
Definition: aligned_sequence_builder.hpp:121
constexpr aligned_sequence_builder(aligned_sequence_builder &&)=default
Defaulted.
constexpr aligned_sequence_builder(aligned_sequence_builder const &)=default
Defaulted.
aligned_sequence_builder(fst_sequence_t &&, sec_sequence_t &&) -> aligned_sequence_builder< fst_sequence_t, sec_sequence_t >
Deduces the type from the passed constructor arguments.
result_type operator()(trace_path_t &&trace_path)
Builds the aligned sequences from the given trace path.
Definition: aligned_sequence_builder.hpp:170
type_reduce_view< fst_sequence_t > fst_rng
A view over the first range.
Definition: aligned_sequence_builder.hpp:244
void fill_aligned_sequence(reverse_traces_t &&rev_traces, fst_aligned_t &fst_aligned, sec_aligned_t &sec_aligned) const
Fills the sequences with gaps according to the given trace segments.
Definition: aligned_sequence_builder.hpp:219
constexpr aligned_sequence_builder()=default
Defaulted.
type_reduce_view< sec_sequence_t > sec_rng
A view over the second range.
Definition: aligned_sequence_builder.hpp:245
~aligned_sequence_builder()=default
Defaulted.
constexpr aligned_sequence_builder(fst_sequence_t fst_rng, sec_sequence_t sec_rng)
Construction from the underlying sequences.
Definition: aligned_sequence_builder.hpp:149
constexpr aligned_sequence_builder & operator=(aligned_sequence_builder const &)=default
Defaulted.
constexpr aligned_sequence_builder & operator=(aligned_sequence_builder &&)=default
Defaulted.
The Concepts library.
T emplace_back(T... args)
Provides seqan3::gap_decorator.
Provides seqan3::gapped.
trace_directions
The possible directions a trace can have. The values can be combined by the logical |-operator.
Definition: trace_directions.hpp:29
@ up
Trace comes from the above entry.
@ left
Trace comes from the left entry.
@ diagonal
Trace comes from the diagonal entry.
@ alignment
The (pairwise) alignment stored in an object that models seqan3::detail::pairwise_alignment.
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:141
constexpr auto type_reduce
A view adaptor that behaves like std::views::all, but type erases certain ranges.
Definition: type_reduce.hpp:158
The generic concept for an aligned sequence that is writable.
Provides a type trait for verifying valid template declarations.
Provides lazy template instantiation traits.
Provides seqan3::detail::alignment_coordinate and associated strong types.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
decltype(views::type_reduce(std::declval< t >())) type_reduce_view
Deduces the return value of seqan3::views::type_reduce.
Definition: type_reduce.hpp:168
SeqAn specific customisations in the standard namespace.
Provides seqan3::views::convert.
Adaptations of concepts from the Ranges TS.
Provides seqan3::views::slice.
The result type when building the aligned sequences.
Definition: aligned_sequence_builder.hpp:125
An empty type whose only purpose is to hold an uninstantiated template plus its arguments.
Definition: lazy_conditional.hpp:36
A transformation trait that returns the correct aligned sequence type for a given sequence type.
Definition: aligned_sequence_builder.hpp:55
decltype(std::declval< range_t >()|views::type_reduce|views::slice(0, 1)) unaligned_sequence_type
The unaligned sequence type that will be used to assign a sequence to seqan3::assign_unaligned.
Definition: aligned_sequence_builder.hpp:62
lazy_conditional_t< is_class_template_declarable_with_v< gap_decorator, unaligned_sequence_type >, lazy< gap_decorator, unaligned_sequence_type >, lazy< std::vector, gapped< std::ranges::range_value_t< unaligned_sequence_type > >> > type
The resulting aligned sequence type.
Definition: aligned_sequence_builder.hpp:68
A transformation trait that returns the correct pairwise alignment type for two given sequence types.
Definition: aligned_sequence_builder.hpp:80
typename make_aligned_sequence_type< second_sequence_t >::type second_aligned_t
The aligned sequence type for the second sequence.
Definition: aligned_sequence_builder.hpp:84
typename make_aligned_sequence_type< first_sequence_t >::type first_aligned_t
The aligned sequence type for the first sequence.
Definition: aligned_sequence_builder.hpp:82
T tie(T... args)
Provides seqan3::views::to.
Provides the declaration of seqan3::detail::trace_directions.
Provides seqan3::views::type_reduce.
Provides the concepts seqan3::transformation_trait and seqan3::unary_type_trait.