SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
search.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 
20 #include <seqan3/std/algorithm>
21 #include <seqan3/std/ranges>
22 
23 
24 namespace seqan3::detail
25 {
26 
30 struct search_configuration_validator
31 {
44  template <typename configuration_t>
45  static void validate_error_configuration(configuration_t const & cfg)
46  {
47  static_assert(detail::is_type_specialisation_of_v<configuration_t, configuration>,
48  "cfg must be a specialisation of seqan3::configuration.");
49 
50  using search_traits_t = detail::search_traits<configuration_t>;
51 
52  if constexpr (search_traits_t::search_with_max_error)
53  {
54  auto const & [total, subs, ins, del] = get<search_cfg::max_error>(cfg).value;
55  if (subs > total)
56  throw std::invalid_argument{"The substitution error threshold is higher than the total error "
57  "threshold."};
58  if (ins > total)
59  throw std::invalid_argument{"The insertion error threshold is higher than the total error threshold."};
60  if (del > total)
61  throw std::invalid_argument{"The deletion error threshold is higher than the total error threshold."};
62  }
63  else if constexpr (search_traits_t::search_with_max_error_rate)
64  {
65  auto const & [total, subs, ins, del] = get<search_cfg::max_error_rate>(cfg).value;
66  if (subs > total)
67  throw std::invalid_argument{"The substitution error threshold is higher than the total error "
68  "threshold."};
69  if (ins > total)
70  throw std::invalid_argument{"The insertion error threshold is higher than the total error threshold."};
71  if (del > total)
72  throw std::invalid_argument{"The deletion error threshold is higher than the total error threshold."};
73  }
74  }
75 
80  template <typename query_t>
81  static void validate_query_type()
82  {
83  using pure_query_t = remove_cvref_t<query_t>;
84  if constexpr(dimension_v<pure_query_t> == 1u)
85  {
86  static_assert(std::ranges::random_access_range<pure_query_t>,
87  "The query sequence must model random_access_range.");
88  static_assert(std::ranges::sized_range<pure_query_t>, "The query sequence must model sized_range.");
89  }
90  else
91  {
92  static_assert(std::ranges::forward_range<pure_query_t>, "The query collection must model forward_range.");
93  static_assert(std::ranges::sized_range<pure_query_t>, "The query collection must model sized_range.");
94  static_assert(std::ranges::random_access_range<std::ranges::range_value_t<pure_query_t>>,
95  "Elements of the query collection must model random_access_range.");
96  static_assert(std::ranges::sized_range<std::ranges::range_value_t<pure_query_t>>,
97  "Elements of the query collection must model sized_range.");
98  }
99  }
100 };
101 } // namespace seqan3::detail
102 
103 namespace seqan3
104 {
105 
166 template <fm_index_specialisation index_t, typename queries_t, typename configuration_t = decltype(search_cfg::default_configuration)>
167 inline auto search(queries_t && queries,
168  index_t const & index,
169  configuration_t const & cfg = search_cfg::default_configuration)
170 {
171  using search_traits_t = detail::search_traits<configuration_t>;
172 
173  // If no mode was set, default to search all hits.
174  if constexpr (!search_traits_t::has_mode_configuration)
175  {
176  return search(std::forward<queries_t>(queries), index, cfg | search_cfg::mode{search_cfg::all});
177  }
178  else
179  { // If no output configuration was, default to returning text positions.
180  if constexpr (!search_traits_t::has_output_configuration)
181  {
182  return search(std::forward<queries_t>(queries), index, cfg | search_cfg::output{search_cfg::text_position});
183  }
184  else
185  {
186  detail::search_configuration_validator::validate_query_type<queries_t>();
187  detail::search_configuration_validator::validate_error_configuration(cfg);
188 
189  return detail::search_all(index, std::forward<queries_t>(queries), cfg);
190  }
191  }
192 }
193 
196 template <fm_index_specialisation index_t, typename configuration_t = decltype(search_cfg::default_configuration)>
197 inline auto search(char const * const queries,
198  index_t const & index,
199  configuration_t const & cfg = search_cfg::default_configuration)
200 {
201  return search(std::string_view{queries}, index, cfg);
202 }
203 
205 template <fm_index_specialisation index_t, typename configuration_t = decltype(search_cfg::default_configuration)>
206 inline auto search(std::initializer_list<char const * const> const & queries,
207  index_t const & index,
208  configuration_t const & cfg = search_cfg::default_configuration)
209 {
211  query.reserve(std::ranges::size(queries));
212  std::ranges::for_each(queries, [&query] (char const * const q) { query.push_back(std::string_view{q}); });
213  return search(std::move(query) | views::persist, index, cfg);
214 }
216 
218 
219 } // namespace seqan3
seqan3::search
auto search(queries_t &&queries, index_t const &index, configuration_t const &cfg=search_cfg::default_configuration)
Search a query or a range of queries in an index.
Definition: search.hpp:167
all.hpp
Meta-header for the FM index module.
std::string_view
std::vector::reserve
T reserve(T... args)
std::vector
configuration.hpp
Provides seqan3::detail::configuration and utility functions.
seqan3::views::move
const auto move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
algorithm
Adaptations of algorithms from the Ranges TS.
seqan3::views::persist
constexpr auto persist
A view adaptor that wraps rvalue references of non-views.
Definition: persist.hpp:248
std::vector::push_back
T push_back(T... args)
seqan3::search_cfg::default_configuration
constexpr configuration default_configuration
The default configuration.
Definition: default_configuration.hpp:28
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
persist.hpp
Provides seqan3::views::persist.
std::invalid_argument
seqan3::search_cfg::all
constexpr detail::search_mode_all all
Configuration element to receive all hits within the error bounds.
Definition: mode.hpp:43
seqan3::pack_traits::size
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
ranges
Adaptations of concepts from the Ranges TS.
search_traits.hpp
Provides seqan3::detail::search_traits.
seqan3::search_cfg::mode
Configuration element to determine the search mode.
Definition: mode.hpp:86
seqan3::search_cfg::output
Configuration element to determine the output type of hits.
Definition: output.hpp:59
search.hpp
Provides the public interface for search algorithms.
seqan3::search_cfg::text_position
constexpr detail::search_output_text_position text_position
Configuration element to receive all hits within the lowest number of errors.
Definition: output.hpp:42
std::initializer_list