SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
align_pairwise.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 <functional>
16 #include <iostream>
17 #include <tuple>
18 #include <type_traits>
19 
20 #include <meta/meta.hpp>
21 
33 #include <seqan3/std/concepts>
34 #include <seqan3/std/ranges>
35 
36 namespace seqan3
37 {
38 
133 template <typename sequence_t, typename alignment_config_t>
135  requires detail::align_pairwise_single_input<sequence_t> &&
136  std::copy_constructible<std::remove_reference_t<sequence_t>> &&
137  detail::is_type_specialisation_of_v<alignment_config_t, configuration>
139 constexpr auto align_pairwise(sequence_t && seq, alignment_config_t const & config)
140 {
141  using std::get;
142 
143  if constexpr (std::is_lvalue_reference_v<sequence_t>) // Forward tuple elements as references.
144  {
145  return align_pairwise(std::tie(get<0>(seq), get<1>(seq)), config);
146  }
147  else
148  {
150  "Alignment configuration error: Expects exactly two sequences for pairwise alignments.");
151 
152  static_assert(std::ranges::viewable_range<std::tuple_element_t<0, std::remove_reference_t<sequence_t>>> &&
153  std::ranges::viewable_range<std::tuple_element_t<1, std::remove_reference_t<sequence_t>>>,
154  "Alignment configuration error: The tuple elements must model std::ranges::viewable_range.");
155 
156  return align_pairwise(std::views::single(std::forward<sequence_t>(seq)), config);
157  }
158 }
159 
161 template <typename sequence_t, typename alignment_config_t>
162  requires detail::align_pairwise_range_input<sequence_t> &&
163  detail::is_type_specialisation_of_v<alignment_config_t, configuration>
164 constexpr auto align_pairwise(sequence_t && sequences,
165  alignment_config_t const & config)
166 {
167  using first_seq_t = std::tuple_element_t<0, std::ranges::range_value_t<sequence_t>>;
168  using second_seq_t = std::tuple_element_t<1, std::ranges::range_value_t<sequence_t>>;
169 
170  static_assert(std::ranges::random_access_range<first_seq_t> && std::ranges::sized_range<first_seq_t>,
171  "Alignment configuration error: The sequence must model random_access_range and sized_range.");
172  static_assert(std::ranges::random_access_range<second_seq_t> && std::ranges::sized_range<second_seq_t>,
173  "Alignment configuration error: The sequence must model random_access_range and sized_range.");
174 
175  // Pipe with views::persist to allow rvalue non-view ranges.
176  auto seq_view = std::forward<sequence_t>(sequences) | views::persist;
177  // Configure the alignment algorithm.
178  auto && [algorithm, complete_config] = detail::alignment_configurator::configure<decltype(seq_view)>(config);
179 
180  using complete_config_t = std::remove_cvref_t<decltype(complete_config)>;
181  using traits_t = detail::alignment_configuration_traits<complete_config_t>;
182 
183  auto indexed_sequence_chunk_view = views::zip(seq_view, std::views::iota(0))
184  | views::chunk(traits_t::alignments_per_vector);
185 
186  using indexed_sequences_t = decltype(indexed_sequence_chunk_view);
187  using alignment_result_t = typename traits_t::alignment_result_type;
189  detail::execution_handler_parallel,
190  detail::execution_handler_sequential>;
191  using executor_t = detail::algorithm_executor_blocking<indexed_sequences_t,
192  decltype(algorithm),
193  alignment_result_t,
194  execution_handler_t>;
195 
196  // Select the execution handler for the alignment configuration.
197  auto select_execution_handler = [&] ()
198  {
199  if constexpr (std::same_as<execution_handler_t, detail::execution_handler_parallel>)
200  {
201  auto thread_count = get<align_cfg::parallel>(complete_config).thread_count;
202  if (!thread_count)
203  throw std::runtime_error{"You must configure the number of threads in seqan3::align_cfg::parallel."};
204 
205  return execution_handler_t{*thread_count};
206  }
207  else
208  {
209  return execution_handler_t{};
210  }
211  };
212 
213  if constexpr (traits_t::is_one_way_execution) // Just compute alignment and wait until all alignments are computed.
214  select_execution_handler().bulk_execute(algorithm,
215  indexed_sequence_chunk_view,
216  get<align_cfg::on_result>(complete_config).callback);
217  else // Require two way execution: return the range over the alignments.
218  return algorithm_result_generator_range{executor_t{std::move(indexed_sequence_chunk_view),
219  std::move(algorithm),
220  alignment_result_t{},
221  select_execution_handler()}};
222 }
224 
225 } // namespace seqan3
seqan3::single
@ single
The text is a single range.
Definition: concept.hpp:84
type_traits.hpp
Provides helper type traits for the configuration and execution of the alignment algorithm.
functional
basic.hpp
Provides various type traits on generic types.
tuple
seqan3::views::get
auto const get
A view calling std::get on each element in a range.
Definition: get.hpp:65
seqan3::align_pairwise
constexpr auto align_pairwise(sequence_t &&seq, alignment_config_t const &config)
Computes the pairwise alignment for a pair of sequences or a range over sequence pairs.
Definition: align_pairwise.hpp:138
iostream
execution.hpp
Provides execution policies.
algorithm_result_generator_range.hpp
Provides seqan3::detail::algorithm_result_generator_range.
concepts
The Concepts library.
seqan3::views::persist
constexpr auto persist
A view adaptor that wraps rvalue references of non-views.
Definition: persist.hpp:233
std::tie
T tie(T... args)
seqan3::seq
constexpr sequenced_policy seq
Global execution policy object for sequenced execution policy.
Definition: execution.hpp:54
simd.hpp
Provides seqan3::simd::simd_type.
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
simd_traits.hpp
Provides seqan3::simd::simd_traits.
concept.hpp
Provides concepts needed internally for the alignment algorithms.
algorithm_executor_blocking.hpp
Provides seqan3::detail::algorithm_executor_blocking.
alignment_configurator.hpp
Provides seqan3::detail::alignment_selector.
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
persist.hpp
Provides seqan3::views::persist.
std::runtime_error
alignment_result.hpp
Provides seqan3::alignment_result.
ranges
Adaptations of concepts from the Ranges TS.
std::remove_reference_t
std::remove_cvref_t
std::conditional_t
std::tuple_size_v
T tuple_size_v