SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
align_pairwise.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <concepts>
16 #include <functional>
17 #include <iostream>
18 #include <ranges>
19 #include <tuple>
20 #include <type_traits>
21 
32 
33 namespace seqan3
34 {
35 
130 template <typename sequence_t, typename alignment_config_t>
131  requires detail::align_pairwise_single_input<sequence_t>
132  && std::copy_constructible<std::remove_reference_t<sequence_t>>
133  && detail::is_type_specialisation_of_v<alignment_config_t, configuration>
134 constexpr auto align_pairwise(sequence_t && seq, alignment_config_t const & config)
135 {
136  using std::get;
137 
138  if constexpr (std::is_lvalue_reference_v<sequence_t>) // Forward tuple elements as references.
139  {
140  return align_pairwise(std::tie(get<0>(seq), get<1>(seq)), config);
141  }
142  else
143  {
145  "Alignment configuration error: Expects exactly two sequences for pairwise alignments.");
146 
147  static_assert(std::ranges::viewable_range<std::tuple_element_t<0, std::remove_reference_t<sequence_t>>>
148  && std::ranges::viewable_range<std::tuple_element_t<1, std::remove_reference_t<sequence_t>>>,
149  "Alignment configuration error: The tuple elements must model std::ranges::viewable_range.");
150 
151  return align_pairwise(std::views::single(std::forward<sequence_t>(seq)), config);
152  }
153 }
154 
156 template <typename sequence_t, typename alignment_config_t>
157  requires detail::align_pairwise_range_input<sequence_t>
158  && detail::is_type_specialisation_of_v<alignment_config_t, configuration>
159 constexpr auto align_pairwise(sequence_t && sequences, alignment_config_t const & config)
160 {
161  using first_seq_t = std::tuple_element_t<0, std::ranges::range_value_t<sequence_t>>;
162  using second_seq_t = std::tuple_element_t<1, std::ranges::range_value_t<sequence_t>>;
163 
164  static_assert(std::ranges::random_access_range<first_seq_t> && std::ranges::sized_range<first_seq_t>,
165  "Alignment configuration error: The sequence must model random_access_range and sized_range.");
166  static_assert(std::ranges::random_access_range<second_seq_t> && std::ranges::sized_range<second_seq_t>,
167  "Alignment configuration error: The sequence must model random_access_range and sized_range.");
168 
169  // Pipe with detail::persist to allow rvalue non-view ranges.
170  auto seq_view = std::forward<sequence_t>(sequences) | detail::persist;
171  // Configure the alignment algorithm.
172  auto && [algorithm, complete_config] = detail::alignment_configurator::configure<decltype(seq_view)>(config);
173 
174  using complete_config_t = std::remove_cvref_t<decltype(complete_config)>;
175  using traits_t = detail::alignment_configuration_traits<complete_config_t>;
176 
177  auto indexed_sequence_chunk_view =
178  views::zip(seq_view, std::views::iota(0)) | views::chunk(traits_t::alignments_per_vector);
179 
180  using indexed_sequences_t = decltype(indexed_sequence_chunk_view);
181  using alignment_result_t = typename traits_t::alignment_result_type;
183  detail::execution_handler_parallel,
184  detail::execution_handler_sequential>;
185  using executor_t = detail::
186  algorithm_executor_blocking<indexed_sequences_t, decltype(algorithm), alignment_result_t, execution_handler_t>;
187 
188  // Select the execution handler for the alignment configuration.
189  auto select_execution_handler = [parallel = complete_config.get_or(align_cfg::parallel{})]()
190  {
191  if constexpr (std::same_as<execution_handler_t, detail::execution_handler_parallel>)
192  {
193  auto thread_count = parallel.thread_count;
194  if (!thread_count)
195  throw std::runtime_error{"You must configure the number of threads in seqan3::align_cfg::parallel."};
196 
197  return execution_handler_t{*thread_count};
198  }
199  else
200  {
201  return execution_handler_t{};
202  }
203  };
204 
205  if constexpr (traits_t::is_one_way_execution) // Just compute alignment and wait until all alignments are computed.
206  select_execution_handler().bulk_execute(algorithm,
207  indexed_sequence_chunk_view,
208  get<align_cfg::on_result>(complete_config).callback);
209  else // Require two way execution: return the range over the alignments.
210  return algorithm_result_generator_range{executor_t{std::move(indexed_sequence_chunk_view),
211  std::move(algorithm),
212  alignment_result_t{},
213  select_execution_handler()}};
214 }
216 
217 } // namespace seqan3
Provides seqan3::detail::algorithm_executor_blocking.
Provides seqan3::detail::algorithm_result_generator_range.
Provides concepts needed internally for the alignment algorithms.
Provides helper type traits for the configuration and execution of the alignment algorithm.
Provides seqan3::detail::alignment_selector.
Provides seqan3::alignment_result.
Provides various type traits on generic types.
The <concepts> header from C++20's standard library.
seqan3::detail::parallel_mode< std::integral_constant< seqan3::detail::align_config_id, seqan3::detail::align_config_id::parallel > > parallel
Enables the parallel execution of the alignment algorithm if possible for the given configuration.
Definition: align_config_parallel.hpp:38
requires detail::align_pairwise_single_input< sequence_t > &&std::copy_constructible< std::remove_reference_t< sequence_t > > &&constexpr detail::is_type_specialisation_of_v< alignment_config_t, configuration > 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:134
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
@ seq
The "sequence", usually a range of nucleotides or amino acids.
@ single
The text is a single range.
Definition: search/fm_index/concept.hpp:93
constexpr auto chunk
Divide a range in chunks.
Definition: chunk.hpp:835
constexpr auto zip
A view adaptor that takes several views and returns tuple-like values from every i-th element of each...
Definition: zip.hpp:573
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:415
Provides seqan3::detail::persist.
The <ranges> header from C++20's standard library.
Provides seqan3::simd::simd_type.
Provides seqan3::simd::simd_traits.
T tie(T... args)
T tuple_size_v