SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
align_pairwise.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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 <functional>
17#include <iostream>
18#include <seqan3/std/ranges>
19#include <tuple>
20#include <type_traits>
21
32
33namespace seqan3
34{
35
130template <typename sequence_t, typename alignment_config_t>
132 requires detail::align_pairwise_single_input<sequence_t> &&
133 std::copy_constructible<std::remove_reference_t<sequence_t>> &&
134 detail::is_type_specialisation_of_v<alignment_config_t, configuration>
136constexpr auto align_pairwise(sequence_t && seq, alignment_config_t const & config)
137{
138 using std::get;
139
140 if constexpr (std::is_lvalue_reference_v<sequence_t>) // Forward tuple elements as references.
141 {
142 return align_pairwise(std::tie(get<0>(seq), get<1>(seq)), config);
143 }
144 else
145 {
146 static_assert(std::tuple_size_v<std::remove_reference_t<sequence_t>> == 2,
147 "Alignment configuration error: Expects exactly two sequences for pairwise alignments.");
148
149 static_assert(std::ranges::viewable_range<std::tuple_element_t<0, std::remove_reference_t<sequence_t>>> &&
150 std::ranges::viewable_range<std::tuple_element_t<1, std::remove_reference_t<sequence_t>>>,
151 "Alignment configuration error: The tuple elements must model std::ranges::viewable_range.");
152
153 return align_pairwise(std::views::single(std::forward<sequence_t>(seq)), config);
154 }
155}
156
158template <typename sequence_t, typename alignment_config_t>
159 requires detail::align_pairwise_range_input<sequence_t> &&
160 detail::is_type_specialisation_of_v<alignment_config_t, configuration>
161constexpr auto align_pairwise(sequence_t && sequences,
162 alignment_config_t const & config)
163{
164 using first_seq_t = std::tuple_element_t<0, std::ranges::range_value_t<sequence_t>>;
165 using second_seq_t = std::tuple_element_t<1, std::ranges::range_value_t<sequence_t>>;
166
167 static_assert(std::ranges::random_access_range<first_seq_t> && std::ranges::sized_range<first_seq_t>,
168 "Alignment configuration error: The sequence must model random_access_range and sized_range.");
169 static_assert(std::ranges::random_access_range<second_seq_t> && std::ranges::sized_range<second_seq_t>,
170 "Alignment configuration error: The sequence must model random_access_range and sized_range.");
171
172 // Pipe with detail::persist to allow rvalue non-view ranges.
173 auto seq_view = std::forward<sequence_t>(sequences) | detail::persist;
174 // Configure the alignment algorithm.
175 auto && [algorithm, complete_config] = detail::alignment_configurator::configure<decltype(seq_view)>(config);
176
177 using complete_config_t = std::remove_cvref_t<decltype(complete_config)>;
178 using traits_t = detail::alignment_configuration_traits<complete_config_t>;
179
180 auto indexed_sequence_chunk_view = views::zip(seq_view, std::views::iota(0))
181 | views::chunk(traits_t::alignments_per_vector);
182
183 using indexed_sequences_t = decltype(indexed_sequence_chunk_view);
184 using alignment_result_t = typename traits_t::alignment_result_type;
186 detail::execution_handler_parallel,
187 detail::execution_handler_sequential>;
188 using executor_t = detail::algorithm_executor_blocking<indexed_sequences_t,
189 decltype(algorithm),
190 alignment_result_t,
191 execution_handler_t>;
192
193 // Select the execution handler for the alignment configuration.
194 auto select_execution_handler = [&] ()
195 {
196 if constexpr (std::same_as<execution_handler_t, detail::execution_handler_parallel>)
197 {
198 auto thread_count = get<align_cfg::parallel>(complete_config).thread_count;
199 if (!thread_count)
200 throw std::runtime_error{"You must configure the number of threads in seqan3::align_cfg::parallel."};
201
202 return execution_handler_t{*thread_count};
203 }
204 else
205 {
206 return execution_handler_t{};
207 }
208 };
209
210 if constexpr (traits_t::is_one_way_execution) // Just compute alignment and wait until all alignments are computed.
211 select_execution_handler().bulk_execute(algorithm,
212 indexed_sequence_chunk_view,
213 get<align_cfg::on_result>(complete_config).callback);
214 else // Require two way execution: return the range over the alignments.
215 return algorithm_result_generator_range{executor_t{std::move(indexed_sequence_chunk_view),
216 std::move(algorithm),
217 alignment_result_t{},
218 select_execution_handler()}};
219}
221
222} // 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.
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:135
@ single
The text is a single range.
Definition: concept.hpp:74
constexpr auto chunk
A chunk view.
Definition: chunk.hpp:29
constexpr auto zip
A zip view.
Definition: zip.hpp:29
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
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:429
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)