From 5264f6c735380cc3511354283dfb09e429b9b595 Mon Sep 17 00:00:00 2001 From: smehringer Date: Thu, 14 May 2020 10:36:57 +0200 Subject: [PATCH] [FEATURE] Make search modi into individual pipeable config elements. --- CHANGELOG.md | 12 ++- .../read_mapper/read_mapper_step2.cpp | 2 +- .../read_mapper/read_mapper_step3.cpp | 2 +- .../read_mapper/read_mapper_step4.cpp | 2 +- doc/tutorial/search/index.md | 27 ++--- doc/tutorial/search/search_small_snippets.cpp | 12 +-- doc/tutorial/search/search_solution4.cpp | 8 +- doc/tutorial/search/search_solution5.cpp | 4 +- include/seqan3/search/configuration/all.hpp | 41 ++++--- .../configuration/default_configuration.hpp | 4 +- .../seqan3/search/configuration/detail.hpp | 4 +- include/seqan3/search/configuration/hit.hpp | 93 ++++++++++++++++ include/seqan3/search/configuration/mode.hpp | 102 ------------------ .../search/detail/policy_result_builder.hpp | 4 +- .../search/detail/search_scheme_algorithm.hpp | 20 ++-- .../seqan3/search/detail/search_traits.hpp | 24 ++--- .../unidirectional_search_algorithm.hpp | 18 ++-- include/seqan3/search/search.hpp | 17 +-- test/performance/search/search_benchmark.cpp | 4 +- test/snippet/search/configuration_default.cpp | 4 +- test/snippet/search/configuration_modes.cpp | 18 ---- .../search/hit_configuration_examples.cpp | 30 ++++++ test/unit/search/configuration/CMakeLists.txt | 1 + test/unit/search/configuration/hit_test.cpp | 59 ++++++++++ .../unit/search/search_configuration_test.cpp | 2 +- test/unit/search/search_test.cpp | 32 +++--- 26 files changed, 316 insertions(+), 230 deletions(-) create mode 100644 include/seqan3/search/configuration/hit.hpp delete mode 100644 include/seqan3/search/configuration/mode.hpp delete mode 100644 test/snippet/search/configuration_modes.cpp create mode 100644 test/snippet/search/hit_configuration_examples.cpp create mode 100644 test/unit/search/configuration/CMakeLists.txt create mode 100644 test/unit/search/configuration/hit_test.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index cb8ead6ec3..17f65e2da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,13 +72,23 @@ Note that 3.1.0 will be the first API stable release and interfaces in this rele #### Search * Moved `seqan3::search` from `search/algorithm/` to `search/` ([\#1696](https://github.com/seqan/seqan3/pull/1696)). +* Configuration refactoring: + * The names for the search mode configuration have changed and are now individual config elements + that are pipeable ([\#1639](https://github.com/seqan/seqan3/pull/1639)): + `seqan3::search_cfg::all` to `seqan3::search_cfg::hit_all` + `seqan3::search_cfg::best` to `seqan3::search_cfg::hit_single_best` + `seqan3::search_cfg::all_best` to `seqan3::search_cfg::hit_all_best` + `seqan3::search_cfg::strata{5}` to `seqan3::search_cfg::hit_strata{5}` + * The configuration element `seqan3::search_cfg::mode` does not exist anymore. + You can replace it by directly using one of the above mentioned "hit strategy" configuration elements + ([\#1639](https://github.com/seqan/seqan3/pull/1639)). ## Notable Bug-fixes ### Argument Parser * Long option identifiers and their value must be separated by a space or equal sign `=`. - Handling this restriction resolves the ambiguity if one long option identifier is the prefix of + Handling this restriction resolves the ambiguity if one long option identifier is the prefix of another ([\#1792](https://github.com/seqan/seqan3/pull/1792)). Valid short id value pairs: `-iValue`, `-i=Value`, `-i Value` diff --git a/doc/tutorial/read_mapper/read_mapper_step2.cpp b/doc/tutorial/read_mapper/read_mapper_step2.cpp index e07e202cc4..a658e5e5ac 100644 --- a/doc/tutorial/read_mapper/read_mapper_step2.cpp +++ b/doc/tutorial/read_mapper/read_mapper_step2.cpp @@ -48,7 +48,7 @@ void map_reads(std::filesystem::path const & query_path, seqan3::sequence_file_input query_in{query_path}; seqan3::configuration const search_config = seqan3::search_cfg::max_error{seqan3::search_cfg::total{errors}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; for (auto & [query, id, qual] : query_in | seqan3::views::take(20)) { diff --git a/doc/tutorial/read_mapper/read_mapper_step3.cpp b/doc/tutorial/read_mapper/read_mapper_step3.cpp index cbdf6e94c3..a4b34af330 100644 --- a/doc/tutorial/read_mapper/read_mapper_step3.cpp +++ b/doc/tutorial/read_mapper/read_mapper_step3.cpp @@ -49,7 +49,7 @@ void map_reads(std::filesystem::path const & query_path, seqan3::sequence_file_input query_in{query_path}; seqan3::configuration const search_config = seqan3::search_cfg::max_error{seqan3::search_cfg::total{errors}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; //! [alignment_config] seqan3::configuration const align_config = seqan3::align_cfg::edit | diff --git a/doc/tutorial/read_mapper/read_mapper_step4.cpp b/doc/tutorial/read_mapper/read_mapper_step4.cpp index ede4219266..6bdb3935d9 100644 --- a/doc/tutorial/read_mapper/read_mapper_step4.cpp +++ b/doc/tutorial/read_mapper/read_mapper_step4.cpp @@ -59,7 +59,7 @@ void map_reads(std::filesystem::path const & query_path, //! [alignment_file_output] seqan3::configuration const search_config = seqan3::search_cfg::max_error{seqan3::search_cfg::total{errors}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; seqan3::configuration const align_config = seqan3::align_cfg::edit | seqan3::align_cfg::aligned_ends{seqan3::free_ends_first} | diff --git a/doc/tutorial/search/index.md b/doc/tutorial/search/index.md index 21bebfa92b..95730b39e5 100644 --- a/doc/tutorial/search/index.md +++ b/doc/tutorial/search/index.md @@ -212,27 +212,28 @@ At position 85: ACT ``` \endsolution -## Search modes +## Which hits are reported? -Besides the error configuration, you can define what kind of hits should be reported: +Besides the error configuration, you can define which hits should be reported: -- seqan3::search_cfg::all: Report all hits that satisfy the (approximate) search. -- seqan3::search_cfg::best: Report the best hit, i.e. the *first* hit with the lowest edit distance. -- seqan3::search_cfg::all_best: Report all hits with the lowest edit distance. -- seqan3::search_cfg::strata: best+x mode. Report all hits within the x-neighbourhood of the best hit. +- seqan3::search_cfg::hit_all: Report all hits that satisfy the (approximate) search. +- seqan3::search_cfg::hit_single_best: Report the best hit, i.e. the *first* hit with the lowest edit distance. +- seqan3::search_cfg::hit_all_best: Report all hits with the lowest edit distance. +- seqan3::search_cfg::hit_strata: best+x strategy. Report all hits within the x-neighbourhood of the best hit. -The mode is appended to the error configuration by using the `|`-operator: -\snippet doc/tutorial/search/search_small_snippets.cpp mode_best +Any hit configuration element is appended to the error configuration by using the `|`-operator: +\snippet doc/tutorial/search/search_small_snippets.cpp hit_best -The strata mode needs an additional parameter: -\snippet doc/tutorial/search/search_small_snippets.cpp mode_strata +The `seqan3::search_cfg::strata` configuration element needs an additional parameter: +\snippet doc/tutorial/search/search_small_snippets.cpp hit_strata -If the best hit had an edit distance of 1, the strata mode would report all hits with up to an edit distance of 3. +If the best hit had an edit distance of 1, the strata strategy would report all hits with up to an edit distance of 3. Since in this example the total error number is set to 2, all hits with 1 or 2 errors would be reported. \assignment{Assignment 4} Search for all occurrences of `GCT` in the text from [assignment 1](#assignment_create_index).
-Allow up to 1 error of any type and print the number of hits for each search mode (use `mode::strata{1}`). +Allow up to 1 error of any type and print the number of hits for each hit strategy (use +`seqan3::search_cfg::strata{1}`). \endassignment \solution @@ -254,7 +255,7 @@ There are 25 hits. \assignment{Assignment 5} Search for all occurrences of `GCT` in the text from [assignment 1](#assignment_create_index).
-Allow up to 1 error of any type search for all occurrences in the all_best mode.
+Allow up to 1 error of any type and search for all occurrences with the strategy `seqan3::search_cfg::hit_all_best`.
Align the query to each of the found positions in the genome and print the score and alignment.
**BONUS**
Do the same for the text collection from [assignment 2](#assignment_exact_search). diff --git a/doc/tutorial/search/search_small_snippets.cpp b/doc/tutorial/search/search_small_snippets.cpp index 480acde5ae..f94cb95b66 100644 --- a/doc/tutorial/search/search_small_snippets.cpp +++ b/doc/tutorial/search/search_small_snippets.cpp @@ -89,23 +89,23 @@ seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_c } { -//![mode_best] +//![hit_best] seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}, seqan3::search_cfg::substitution{0}, seqan3::search_cfg::insertion{1}, seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::best}; -//![mode_best] + seqan3::search_cfg::hit_single_best; +//![hit_best] } { -//![mode_strata] +//![hit_strata] seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{2}, seqan3::search_cfg::substitution{0}, seqan3::search_cfg::insertion{1}, seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{2}}; -//![mode_strata] + seqan3::search_cfg::hit_strata{2}; +//![hit_strata] } } diff --git a/doc/tutorial/search/search_solution4.cpp b/doc/tutorial/search/search_solution4.cpp index 8030574439..320e153fd8 100644 --- a/doc/tutorial/search/search_solution4.cpp +++ b/doc/tutorial/search/search_solution4.cpp @@ -15,25 +15,25 @@ int main() seqan3::debug_stream << "Searching all hits\n"; seqan3::configuration const cfg_all = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all}; + seqan3::search_cfg::hit_all; auto results_all = search(query, index, cfg_all); seqan3::debug_stream << "Hits: " << results_all << "\n"; seqan3::debug_stream << "Searching all best hits\n"; seqan3::configuration const cfg_all_best = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; auto results_all_best = search(query, index, cfg_all_best); seqan3::debug_stream << "Hits: " << results_all_best << "\n"; seqan3::debug_stream << "Searching best hit\n"; seqan3::configuration const cfg_best = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::best}; + seqan3::search_cfg::hit_single_best; auto results_best = search(query, index, cfg_best); seqan3::debug_stream << "Hits " << results_best << "\n"; seqan3::debug_stream << "Searching all hits in the 1-stratum\n"; seqan3::configuration const cfg_strata = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{1}}; + seqan3::search_cfg::hit_strata{1}; auto results_strata = search(query, index, cfg_strata); seqan3::debug_stream << "Hits: " << results_strata << "\n"; } diff --git a/doc/tutorial/search/search_solution5.cpp b/doc/tutorial/search/search_solution5.cpp index 96c5b6ad08..accb53291f 100644 --- a/doc/tutorial/search/search_solution5.cpp +++ b/doc/tutorial/search/search_solution5.cpp @@ -18,7 +18,7 @@ void run_text_single() seqan3::debug_stream << "Searching all best hits allowing for 1 error in a single text\n"; seqan3::configuration const search_config = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; seqan3::configuration const align_config = seqan3::align_cfg::edit | seqan3::align_cfg::aligned_ends{seqan3::free_ends_first} | seqan3::align_cfg::result{seqan3::with_alignment}; @@ -54,7 +54,7 @@ void run_text_collection() seqan3::debug_stream << "Searching all best hits allowing for 1 error in a text collection\n"; seqan3::configuration const search_config = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; + seqan3::search_cfg::hit_all_best; seqan3::configuration const align_config = seqan3::align_cfg::edit | seqan3::align_cfg::aligned_ends{seqan3::free_ends_first} | seqan3::align_cfg::result{seqan3::with_alignment}; diff --git a/include/seqan3/search/configuration/all.hpp b/include/seqan3/search/configuration/all.hpp index c919d7dbf3..c1d8ac8b5c 100644 --- a/include/seqan3/search/configuration/all.hpp +++ b/include/seqan3/search/configuration/all.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -32,19 +32,19 @@ * * \details * - * ### Introduction + * \section search_configuration_section_introduction Introduction * * In SeqAn the search algorithm uses a configuration object to determine the desired * \ref seqan3::search_cfg::max_error "number"/\ref seqan3::search_cfg::max_error_rate "rate" of errors, - * what hits are considered as \ref seqan3::search_cfg::mode "results", and how to - * \ref seqan3::search_cfg::output "output" the result. + * what hits are reported based on a \ref search_configuration_subsection_hit_strategy "strategy", and how to + * \ref seqan3::search_cfg::output "output" the results. * These configurations exist in their own namespace, namely seqan3::search_cfg, to disambiguate them from the * configuration of other algorithms. * * If no configuration is provided upon invoking the seqan3::search algorithm, a default configuration is provided: * \include test/snippet/search/configuration_default.cpp * - * ### Combining configuration elements + * \section search_configuration_section_overview Overview on search configurations * * Configurations can be combined using the `|`-operator. If a combination is invalid, a static assertion is triggered * during compilation and will inform the user that the the last config cannot be combined with any of the configs from @@ -52,11 +52,28 @@ * types cannot be printed within the static assert, but the following table shows which combinations are possible. * In general, the same configuration element cannot occur more than once inside of a configuration specification. * - * | **Config** | **0** | **1** | **2** | **3** | **4** | - * | ------------------------------------------------------------|-------|-------|-------|-------|-------| - * | \ref seqan3::search_cfg::max_error "0: Max error" | ❌ | ❌ | ✅ | ✅ | ✅ | - * | \ref seqan3::search_cfg::max_error_rate "1: Max error rate" | ❌ | ❌ | ✅ | ✅ | ✅ | - * | \ref seqan3::search_cfg::output "2: Output" | ✅ | ✅ | ❌ | ✅ | ✅ | - * | \ref seqan3::search_cfg::mode "3: Mode" | ✅ | ✅ | ✅ | ❌ | ✅ | - * | \ref seqan3::search_cfg::parallel "4: Parallel" | ✅ | ✅ | ✅ | ✅ | ❌ | + * | **Configuration group** | **0** | **1** | **2** | **3** | **4** | + * | --------------------------------------------------------------------|-------|-------|-------|-------|-------| + * | \ref seqan3::search_cfg::max_error "0: Max error" | ❌ | ❌ | ✅ | ✅ | ✅ | + * | \ref seqan3::search_cfg::max_error_rate "1: Max error rate" | ❌ | ❌ | ✅ | ✅ | ✅ | + * | \ref seqan3::search_cfg::output "2: Output" | ✅ | ✅ | ❌ | ✅ | ✅ | + * | \ref search_configuration_subsection_hit_strategy "3. Hit" | ✅ | ✅ | ✅ | ❌ | ✅ | + * | \ref seqan3::search_cfg::parallel "4: Parallel" | ✅ | ✅ | ✅ | ✅ | ❌ | + * + * \subsection search_configuration_subsection_hit_strategy 3. Hit Configuration + * + * This configuration can be used to determine which hits are reported. + * Currently these strategies are available: + * + * | Hit Configurations | Behaviour | + * |-------------------------------------|---------------------------------------------------------------------| + * | seqan3::search_cfg::hit_all | Report all hits within error bounds. | + * | seqan3::search_cfg::hit_all_best | Report all hits with the lowest number of errors within the bounds. | + * | seqan3::search_cfg::hit_single_best | Report one best hit (hit with lowest error) within bounds. | + * | seqan3::search_cfg::hit_strata | Report all hits within best + `stratum` errors. | + * + * The individual configuration elements to select a search strategy cannot be combined with each other + * (mutual exclusivity). + * + * \include test/snippet/search/hit_configuration_examples.cpp */ diff --git a/include/seqan3/search/configuration/default_configuration.hpp b/include/seqan3/search/configuration/default_configuration.hpp index 56b6885a16..39a8298527 100644 --- a/include/seqan3/search/configuration/default_configuration.hpp +++ b/include/seqan3/search/configuration/default_configuration.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include namespace seqan3::search_cfg @@ -27,6 +27,6 @@ namespace seqan3::search_cfg */ inline constexpr configuration default_configuration = max_error{total{0}, substitution{0}, insertion{0}, deletion{0}} | output{text_position} | - mode{all}; + hit_all; } // namespace seqan3::search_cfg diff --git a/include/seqan3/search/configuration/detail.hpp b/include/seqan3/search/configuration/detail.hpp index e36eb83ff3..fc368e9984 100644 --- a/include/seqan3/search/configuration/detail.hpp +++ b/include/seqan3/search/configuration/detail.hpp @@ -42,7 +42,7 @@ enum struct search_config_id : uint8_t max_error, //!< Identifier for the max_errors configuration. max_error_rate, //!< Identifier for the max_error_rate configuration. output, //!< Identifier for the output configuration. - mode, //!< Identifier for the search mode configuration. + hit, //!< Identifier for the hit configuration (all, all_best, single_best, strata). parallel, //!< Identifier for the parallel execution configuration. //!\cond // ATTENTION: Must always be the last item; will be used to determine the number of ids. @@ -69,7 +69,7 @@ inline constexpr std::array(search_config_ static_cast(search_config_id::SIZE)> compatibility_table = { { - // max_error, max_error_rate, output, mode, parallel + // max_error, max_error_rate, output, hit, parallel { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 1, 1, 0, 1, 1}, diff --git a/include/seqan3/search/configuration/hit.hpp b/include/seqan3/search/configuration/hit.hpp new file mode 100644 index 0000000000..b482249a70 --- /dev/null +++ b/include/seqan3/search/configuration/hit.hpp @@ -0,0 +1,93 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik +// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License +// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md +// ----------------------------------------------------------------------------------------------------- + +/*!\file + * \brief Provides the configuration to define the hit strategies "hit_strata", "hit_all", + * "hit_all_best", "hit_single_best". + * \author Christopher Pockrandt + * \author Rene Rahn + * \author Svenja Mehringer + */ + +#pragma once + +#include +#include +#include + +namespace seqan3::detail +{ + +/*!\brief Configuration element to receive all hits within the error bounds. + * \ingroup search_configuration + */ +struct hit_all_tag : public pipeable_config_element +{ + //!\privatesection + //!\brief Internal id to check for consistent configuration settings. + static constexpr detail::search_config_id id{detail::search_config_id::hit}; +}; + +/*!\brief Configuration element to receive all hits with the lowest number of errors within the error bounds. + * \ingroup search_configuration + */ +struct hit_all_best_tag : public pipeable_config_element +{ + //!\privatesection + //!\brief Internal id to check for consistent configuration settings. + static constexpr detail::search_config_id id{detail::search_config_id::hit}; +}; + +/*!\brief Configuration element to receive a single best hit with the lowest number of errors within the error bounds. + * \ingroup search_configuration + */ +struct hit_single_best_tag : public pipeable_config_element +{ + //!\privatesection + //!\brief Internal id to check for consistent configuration settings. + static constexpr detail::search_config_id id{detail::search_config_id::hit}; +}; + +} // namespace seqan3::detail + +namespace seqan3::search_cfg +{ + +/*!\brief \copybrief seqan3::detail::hit_all_tag + * \ingroup search_configuration + * \sa \ref search_configuration_subsection_hit_strategy "Section on Hit Strategy" + * \hideinitializer + */ +inline constexpr detail::hit_all_tag hit_all{}; + +/*!\brief \copybrief seqan3::detail::hit_all_best_tag + * \ingroup search_configuration + * \sa \ref search_configuration_subsection_hit_strategy "Section on Hit Strategy" + * \hideinitializer + */ +inline constexpr detail::hit_all_best_tag hit_all_best{}; + +/*!\brief \copybrief seqan3::detail::hit_single_best_tag + * \ingroup search_configuration + * \sa \ref search_configuration_subsection_hit_strategy "Section on Hit Strategy" + * \hideinitializer + */ +inline constexpr detail::hit_single_best_tag hit_single_best{}; + +/*!\brief Configuration element to receive all hits with the best number of errors plus the given stratum. + * All hits are found with the fewest number of errors plus 'stratum'. + * \ingroup search_configuration + * \sa \ref search_configuration_subsection_hit_strategy "Section on Hit Strategy" + */ +struct hit_strata : public pipeable_config_element +{ + //!\privatesection + //!\brief Internal id to check for consistent configuration settings. + static constexpr detail::search_config_id id{detail::search_config_id::hit}; +}; + +} // namespace seqan3::search_cfg diff --git a/include/seqan3/search/configuration/mode.hpp b/include/seqan3/search/configuration/mode.hpp deleted file mode 100644 index fcd6684394..0000000000 --- a/include/seqan3/search/configuration/mode.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// ----------------------------------------------------------------------------------------------------- -// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin -// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik -// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License -// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md -// ----------------------------------------------------------------------------------------------------- - -/*!\file - * \brief Provides the mode configuration to define the search modes "all", "all_best", "best" and "strata". - * \author Christopher Pockrandt - * \author Rene Rahn - */ - -#pragma once - -#include -#include -#include -#include -#include - - -namespace seqan3::detail -{ - -//!\brief Type for the "all" value for the configuration element "mode". -//!\ingroup search_configuration -struct search_mode_all {}; -//!\brief Type for the "all_best" value for the configuration element "mode". -//!\ingroup search_configuration -struct search_mode_all_best {}; -//!\brief Type for the "best" value for the configuration element "mode". -//!\ingroup search_configuration -struct search_mode_best {}; - -} // namespace seqan3::detail - -namespace seqan3::search_cfg -{ - -//!\brief Configuration element to receive all hits within the error bounds. -//!\ingroup search_configuration -inline detail::search_mode_all constexpr all; -//!\brief Configuration element to receive all hits within the lowest number of errors. -//!\ingroup search_configuration -inline detail::search_mode_all_best constexpr all_best; -//!\brief Configuration element to receive one best hit (with the lowest number of errors). -//!\ingroup search_configuration -inline detail::search_mode_best constexpr best; - -/*!\brief Configuration element to receive all hits with the best number of errors plus the strata value. - * A strong type of underlying type `uint8_t` that represents the number or errors for strata. - * All hits are found with the fewest number of errors plus 'value'. - * \ingroup search_configuration - * \tparam value_t The underlying type. - */ -struct strata : detail::strong_type -{ - using detail::strong_type::strong_type; -}; - -/*!\brief Configuration element to determine the search mode. - * \ingroup search_configuration - * - * \details - * This configuration element can be used to determine which hits are supported. - * Currently these modes are available: - * | Mode | Behaviour | - * |------------------------------|---------------------------------------------------------------------| - * | seqan3::search_cfg::all | Report all hits within error bounds. | - * | seqan3::search_cfg::all_best | Report all hits with the lowest number of errors within the bounds. | - * | seqan3::search_cfg::best | Report one best hit (hit with lowest error) within bounds. | - * | seqan3::search_cfg::strata | Report all hits within best + x errors. | - * - * ### Example - * - * \include test/snippet/search/configuration_modes.cpp - */ -template -//!\cond - requires std::same_as, detail::search_mode_all> || - std::same_as, detail::search_mode_all_best> || - std::same_as, detail::search_mode_best> || - std::same_as, strata> -//!\endcond -struct mode : public pipeable_config_element, mode_t> -{ - //!\privatesection - //!\brief Internal id to check for consistent configuration settings. - static constexpr detail::search_config_id id{detail::search_config_id::mode}; -}; - -/*!\name Type deduction guides - * \relates seqan3::search_cfg::mode - * \{ - */ - -//!\brief Deduces search mode type from constructor argument. -template -mode(mode_t) -> mode>; -//!\} -} // namespace seqan3::search_cfg diff --git a/include/seqan3/search/detail/policy_result_builder.hpp b/include/seqan3/search/detail/policy_result_builder.hpp index b0e48dd665..a0d55b6781 100644 --- a/include/seqan3/search/detail/policy_result_builder.hpp +++ b/include/seqan3/search/detail/policy_result_builder.hpp @@ -51,7 +51,7 @@ struct policy_result_builder template //!\cond requires search_traits::search_return_text_position && - search_traits::search_best_hits + search_traits::search_single_best_hit //!\endcond auto make_results(std::vector internal_hits, configuration_t const &) { @@ -86,7 +86,7 @@ struct policy_result_builder template //!\cond requires search_traits::search_return_text_position && - (!search_traits::search_best_hits) + (!search_traits::search_single_best_hit) //!\endcond auto make_results(std::vector internal_hits, configuration_t const &) { diff --git a/include/seqan3/search/detail/search_scheme_algorithm.hpp b/include/seqan3/search/detail/search_scheme_algorithm.hpp index 27ef5f089a..37710982d9 100644 --- a/include/seqan3/search/detail/search_scheme_algorithm.hpp +++ b/include/seqan3/search/detail/search_scheme_algorithm.hpp @@ -83,7 +83,7 @@ class search_scheme_algorithm : protected policies_t... internal_hits.push_back(it); }; - perform_search_by_mode(internal_hits, query, error_state, on_hit_delegate); + perform_search_by_hit_strategy(internal_hits, query, error_state, on_hit_delegate); return this->make_results(std::move(internal_hits), config); // see policy_result_builder } @@ -99,7 +99,7 @@ class search_scheme_algorithm : protected policies_t... template inline void search_algo_bi(query_t & query, search_param const error_left, delegate_t && delegate); - /*!\brief Calls search_algo_bi depending on the search mode given in the configuration. + /*!\brief Calls search_algo_bi depending on the search strategy (hit configuration) given in the configuration. * \tparam query_t Must model std::ranges::input_range over the index's alphabet. * \param[in, out] internal_hits The result vector to be filled. * \param[in] query Query sequence to be searched with the cursor. @@ -107,18 +107,18 @@ class search_scheme_algorithm : protected policies_t... * \param[in] on_hit_delegate The function to be executed on every single (hit) result. */ template - void perform_search_by_mode(std::vector & internal_hits, - query_t & query, - search_param error_state, - delegate_t const & on_hit_delegate) + void perform_search_by_hit_strategy(std::vector & internal_hits, + query_t & query, + search_param error_state, + delegate_t const & on_hit_delegate) { - if constexpr (traits_t::search_best_hits || traits_t::search_all_best_hits || traits_t::search_strata_hits) + if constexpr (!traits_t::search_all_hits) { auto max_total = error_state.total; error_state.total = 0; // start search with less errors while (internal_hits.empty() && error_state.total <= max_total) { - // * If you only want the best hit (traits_t::search_best_hits), you stop after finding the + // * If you only want the best hit (traits_t::search_single_best_hit), you stop after finding the // first hit, the hit with the least errors (`abort_on_hit` is true). // * If you are in strata mode (traits_t::search_strata_hits), you do the same as with best hits, // but then do the extra step afterwards (`abort_on_hit` is true). @@ -133,7 +133,7 @@ class search_scheme_algorithm : protected policies_t... if (!internal_hits.empty()) { internal_hits.clear(); // TODO:don't clear when using Optimum Search Schemes with lower error bounds - uint8_t const stratum = get(config).value; + uint8_t const stratum = get(config).value; error_state.total += stratum - 1; search_algo_bi(query, error_state, on_hit_delegate); } @@ -165,7 +165,7 @@ inline std::vector compute_ss(uint8_t const min_error, uint8_t const // TODO: Replace this at least by the pigeonhole principle or even better by 01*0 schemes. // NOTE: Make sure that the searches are sorted by their asymptotical running time (i.e. upper error bound string), // s.t. easy to compute searches come first. This improves the running time of algorithms that abort after the - // first hit (e.g. search mode: best). Even though it is not guaranteed, this seems to be a good greedy + // first hit (e.g. search strategy: best). Even though it is not guaranteed, this seems to be a good greedy // approach. std::vector scheme{{{1}, {min_error}, {max_error}}}; return scheme; diff --git a/include/seqan3/search/detail/search_traits.hpp b/include/seqan3/search/detail/search_traits.hpp index f3ccd4e0a6..013ec58ca2 100644 --- a/include/seqan3/search/detail/search_traits.hpp +++ b/include/seqan3/search/detail/search_traits.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include namespace seqan3::detail @@ -42,22 +42,18 @@ struct search_traits static constexpr bool has_error_configuration = search_with_max_error | search_with_max_error_rate; //!\brief A flag indicating whether search should find all hits. - static constexpr bool search_all_hits = - search_configuration_t::template exists>(); + static constexpr bool search_all_hits = search_configuration_t::template exists(); //!\brief A flag indicating whether search should find best hits. - static constexpr bool search_best_hits = - search_configuration_t::template exists>(); + static constexpr bool search_single_best_hit = search_configuration_t::template exists(); //!\brief A flag indicating whether search should find all best hits. - static constexpr bool search_all_best_hits = - search_configuration_t::template exists>(); + static constexpr bool search_all_best_hits = search_configuration_t::template exists(); //!\brief A flag indicating whether search should find strata hits. - static constexpr bool search_strata_hits = - search_configuration_t::template exists>(); - //!\brief A flag indicating whether mode configuration was set in the search configuration. - static constexpr bool has_mode_configuration = search_all_hits | - search_best_hits | - search_all_best_hits | - search_strata_hits; + static constexpr bool search_strata_hits = search_configuration_t::template exists(); + //!\brief A flag indicating whether hit configuration was set in the search configuration. + static constexpr bool has_hit_configuration = search_all_hits | + search_single_best_hit | + search_all_best_hits | + search_strata_hits; //!\brief A flag indicating whether search should return the index cursor. static constexpr bool search_return_index_cursor = diff --git a/include/seqan3/search/detail/unidirectional_search_algorithm.hpp b/include/seqan3/search/detail/unidirectional_search_algorithm.hpp index b8e033ca39..f07c14611b 100644 --- a/include/seqan3/search/detail/unidirectional_search_algorithm.hpp +++ b/include/seqan3/search/detail/unidirectional_search_algorithm.hpp @@ -95,7 +95,7 @@ class unidirectional_search_algorithm : protected policies_t... internal_hits.push_back(it); }; - perform_search_by_mode(internal_hits, query, error_state); + perform_search_by_hit_strategy(internal_hits, query, error_state); return this->make_results(std::move(internal_hits), config); // see policy_result_builder } @@ -118,25 +118,25 @@ class unidirectional_search_algorithm : protected policies_t... search_param const error_left, error_type const prev_error); - /*!\brief Calls search_trivial depending on the search mode given in the configuration. + /*!\brief Calls search_trivial depending on the search strategy (hit configuration) given in the configuration. * \tparam query_t Must model std::ranges::input_range over the index's alphabet. * \param[in, out] internal_hits The result vector to be filled. * \param[in] query Query sequence to be searched with the cursor. * \param[in] error_state Number of errors for matching the query sequence. */ template - void perform_search_by_mode(std::vector & internal_hits, - query_t & query, - search_param error_state) + void perform_search_by_hit_strategy(std::vector & internal_hits, + query_t & query, + search_param error_state) { - if constexpr (traits_t::search_best_hits || traits_t::search_all_best_hits || traits_t::search_strata_hits) + if constexpr (!traits_t::search_all_hits) { auto max_total = error_state.total; error_state.total = 0; // start search with less errors while (internal_hits.empty() && error_state.total <= max_total) { - // * If you only want the best hit (traits_t::search_best_hits), you stop after finding the + // * If you only want the best hit (traits_t::search_single_best_hit), you stop after finding the // first hit, the hit with the least errors (`abort_on_hit` is true). // * If you are in strata mode (traits_t::search_strata_hits), you do the same as with best hits, // but then do the extra step afterwards (`abort_on_hit` is true). @@ -152,13 +152,13 @@ class unidirectional_search_algorithm : protected policies_t... if (!internal_hits.empty()) { internal_hits.clear(); - uint8_t const stratum = get(config).value; + uint8_t const stratum = get(config).value; error_state.total += stratum - 1; search_trivial(index_ptr->cursor(), query, 0, error_state, error_type::none); } } } - else // detail::search_mode_all + else // traits_t::search_all { // If you want to find all hits, you cannot stop once you found any hit () // since you have to find all paths in the search tree that satisfy the hit condition. diff --git a/include/seqan3/search/search.hpp b/include/seqan3/search/search.hpp index bf041aedd5..42dd6c76be 100644 --- a/include/seqan3/search/search.hpp +++ b/include/seqan3/search/search.hpp @@ -34,20 +34,21 @@ namespace seqan3::detail */ struct search_configurator { - /*!\brief Add seqan3::search_cfg::all to the configuration if seqan3::search_cfg::mode was not set. + /*!\brief Add seqan3::search_cfg::hit_all to the configuration if no search strategy (hit configuration) was chosen. * \tparam configuration_t The type of the search configuration. * \param[in] cfg The configuration to be modified if necessary. - * \returns The configuration which is guaranteed to have a seqan3::search_cfg::mode available. + * \returns The configuration which is guaranteed to have a hit configuration element available. * * \details * - * If seqan3::search_cfg::mode was not set, it defaults to seqan3::search_cfg::all. + * If no \ref search_configuration_subsection_hit_strategy "hit configuration" was set, + * it defaults to seqan3::search_cfg::hit_all. */ template - static auto add_default_mode_configuration(configuration_t const & cfg) + static auto add_default_hit_configuration(configuration_t const & cfg) { - if constexpr (!detail::search_traits::has_mode_configuration) - return cfg | search_cfg::mode{search_cfg::all}; + if constexpr (!detail::search_traits::has_hit_configuration) + return cfg | search_cfg::hit_all; else return cfg; } @@ -79,7 +80,7 @@ struct search_configurator * * Modifies the configuration object by adding default configuration elements. * - * \sa seqan3::details::search_configurator::add_default_mode_configuration + * \sa seqan3::details::search_configurator::add_default_hit_configuration * \sa seqan3::details::search_configurator::add_default_output_configuration */ template @@ -88,7 +89,7 @@ struct search_configurator static_assert(detail::is_type_specialisation_of_v, "cfg must be a specialisation of seqan3::configuration."); - auto cfg1 = add_default_mode_configuration(cfg); + auto cfg1 = add_default_hit_configuration(cfg); auto cfg2 = add_default_output_configuration(cfg1); return cfg2; diff --git a/test/performance/search/search_benchmark.cpp b/test/performance/search/search_benchmark.cpp index 11a3e29754..c8b3473a00 100644 --- a/test/performance/search/search_benchmark.cpp +++ b/test/performance/search/search_benchmark.cpp @@ -225,7 +225,7 @@ void unidirectional_search_stratified(benchmark::State & state, options && o) o.simulated_errors, o.prob_insertion, o.prob_deletion, o.stddev); seqan3::configuration cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{o.searched_errors}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{o.strata}}; + seqan3::search_cfg::hit_strata{o.strata}; for (auto _ : state) auto results = search(reads, index, cfg); @@ -247,7 +247,7 @@ void bidirectional_search_stratified(benchmark::State & state, options && o) o.simulated_errors, o.prob_insertion, o.prob_deletion, o.stddev); seqan3::configuration cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{o.searched_errors}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{o.strata}}; + seqan3::search_cfg::hit_strata{o.strata}; for (auto _ : state) auto results = search(reads, index, cfg); diff --git a/test/snippet/search/configuration_default.cpp b/test/snippet/search/configuration_default.cpp index 26a7f92188..cf30af73f5 100644 --- a/test/snippet/search/configuration_default.cpp +++ b/test/snippet/search/configuration_default.cpp @@ -7,7 +7,7 @@ int main() seqan3::search_cfg::substitution{0}, seqan3::search_cfg::insertion{0}, seqan3::search_cfg::deletion{0}} | - seqan3::search_cfg::output{seqan3::search_cfg::text_position} | - seqan3::search_cfg::mode{seqan3::search_cfg::all}; + seqan3::search_cfg::output{seqan3::search_cfg::text_position} | + seqan3::search_cfg::hit_all; return 0; } diff --git a/test/snippet/search/configuration_modes.cpp b/test/snippet/search/configuration_modes.cpp deleted file mode 100644 index 8b2a532b5b..0000000000 --- a/test/snippet/search/configuration_modes.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -int main() -{ - // Report the hit with the least number of errors (either 0 or 1 errors). - seqan3::configuration const cfg1 = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}, - seqan3::search_cfg::substitution{0}, - seqan3::search_cfg::insertion{1}, - seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::best}; - - // Report all hits with best + 1 error. E.g., if the best hit has 1 error, all hits with 1 and 2 error are reported. - seqan3::configuration const cfg2 = seqan3::search_cfg::max_error{seqan3::search_cfg::substitution{0}, - seqan3::search_cfg::insertion{1}, - seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{1}}; - return 0; -} diff --git a/test/snippet/search/hit_configuration_examples.cpp b/test/snippet/search/hit_configuration_examples.cpp new file mode 100644 index 0000000000..b68f35c48d --- /dev/null +++ b/test/snippet/search/hit_configuration_examples.cpp @@ -0,0 +1,30 @@ +#include + +int main() +{ + // Report all hits with 0 errors (maximum number of errors defaults to 0). + seqan3::configuration const cfg1 = seqan3::search_cfg::hit_all; + + // Report all hits with 0 and 1 errors. + seqan3::configuration const cfg2 = seqan3::search_cfg::hit_all | + seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}}; + + // Report the single best hit with the least number of errors (up to 1 error is allowed). + seqan3::configuration const cfg3 = seqan3::search_cfg::hit_single_best | + seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}}; + + // Report all hits with the least number of errors (either 0 or 1 errors). + seqan3::configuration const cfg4 = seqan3::search_cfg::hit_all_best | + seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}}; + + // Report all hits with best + 1 error but no more than 2 (errors). + // E.g., if the best hit has 1 error, all hits with 1 and 2 errors are reported. + // E.g., if the best hit has 2 error, only hits with 2 errors are reported since 3 exceeds total. + seqan3::configuration const cfg5 = seqan3::search_cfg::hit_strata{1} | + seqan3::search_cfg::max_error{seqan3::search_cfg::total{2}}; + + // you must choose only one mode + // auto fail = seqan3::search_cfg::hit_single_best | seqan3::search_cfg::hit_all; // doesn't compile + + return 0; +} diff --git a/test/unit/search/configuration/CMakeLists.txt b/test/unit/search/configuration/CMakeLists.txt new file mode 100644 index 0000000000..e2dd4c93e2 --- /dev/null +++ b/test/unit/search/configuration/CMakeLists.txt @@ -0,0 +1 @@ +seqan3_test(hit_test.cpp) diff --git a/test/unit/search/configuration/hit_test.cpp b/test/unit/search/configuration/hit_test.cpp new file mode 100644 index 0000000000..3defb2b006 --- /dev/null +++ b/test/unit/search/configuration/hit_test.cpp @@ -0,0 +1,59 @@ +// ----------------------------------------------------------------------------------------------------- +// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin +// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik +// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License +// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md +// ----------------------------------------------------------------------------------------------------- + +#include + +#include +#include + +#include "../../core/algorithm/pipeable_config_element_test_template.hpp" + +// --------------------------------------------------------------------------------------------------------------------- +// test template : pipeable_config_element_test +// --------------------------------------------------------------------------------------------------------------------- + +using test_types = ::testing::Types; + +INSTANTIATE_TYPED_TEST_SUITE_P(mode_elements, pipeable_config_element_test, test_types, ); + +// --------------------------------------------------------------------------------------------------------------------- +// individual tests +// --------------------------------------------------------------------------------------------------------------------- + +TEST(config_element_test, tags) +{ + seqan3::configuration elem_all = seqan3::search_cfg::hit_all; + EXPECT_TRUE((std::same_as>)); + + seqan3::configuration elem_all_best = seqan3::search_cfg::hit_all_best; + EXPECT_TRUE((std::same_as>)); + + seqan3::configuration elem_single_best = seqan3::search_cfg::hit_single_best; + EXPECT_TRUE((std::same_as>)); +} + +TEST(hit_strata_test, member_variable) +{ + { // default construction + seqan3::search_cfg::hit_strata strata_mode{}; + EXPECT_EQ(strata_mode.value, 0); + } + + { // construct with value + seqan3::search_cfg::hit_strata strata_mode{3}; + EXPECT_EQ(strata_mode.value, 3); + } + + { // assign value + seqan3::search_cfg::hit_strata strata_mode{}; + strata_mode.value = 3; + EXPECT_EQ(strata_mode.value, 3); + } +} diff --git a/test/unit/search/search_configuration_test.cpp b/test/unit/search/search_configuration_test.cpp index a39cc7f710..ba599a71c7 100644 --- a/test/unit/search/search_configuration_test.cpp +++ b/test/unit/search/search_configuration_test.cpp @@ -17,7 +17,7 @@ class search_configuration_test : public ::testing::Test using test_types = ::testing::Types, seqan3::search_cfg::max_error, - seqan3::search_cfg::mode, + seqan3::detail::hit_single_best_tag, seqan3::search_cfg::output, seqan3::search_cfg::parallel>; diff --git a/test/unit/search/search_test.cpp b/test/unit/search/search_test.cpp index 4ec8260b2c..133578d6ad 100644 --- a/test/unit/search/search_test.cpp +++ b/test/unit/search/search_test.cpp @@ -266,7 +266,7 @@ TYPED_TEST(search_test, search_strategy_all) { seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::all}; + seqan3::search_cfg::hit_all; EXPECT_EQ(uniquify(search("ACGT"_dna4, this->index, cfg)), (hits_result_t{{0, 0}, {0, 1}, {0, 4}, {0, 5}, {0, 8}, {0, 9}})); } @@ -275,12 +275,11 @@ TYPED_TEST(search_test, search_strategy_all) TYPED_TEST(search_test, search_strategy_best) { using hits_result_t = typename TestFixture::hits_result_t; - auto search_cfg_mode_best = seqan3::search_cfg::mode{seqan3::search_cfg::best}; hits_result_t possible_hits{{0, 0}, {0, 4}, {0, 8}}; // any of 0, 4, 8 ... 1, 5, 9 are not best hits { seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -291,7 +290,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with 1 insertion at the end. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::insertion{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGTT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -300,7 +299,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with a match at the end, allowing a insertion. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::insertion{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -309,7 +308,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with a deletion. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::deletion{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("AGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -318,7 +317,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with a match at the end, allowing a deletion. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::deletion{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -327,7 +326,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with a substitution at the end. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::substitution{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGC"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -336,7 +335,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with a match at the end, allowing a substitution. seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::substitution{1}} | - search_cfg_mode_best; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("ACGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -346,7 +345,7 @@ TYPED_TEST(search_test, search_strategy_best) { // Find best match with 2 deletions. hits_result_t possible_hits2d{{0, 0}, {0, 4}}; // any of 0, 4 ... 1, 5 are not best hits seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::deletion{2}} | - seqan3::search_cfg::mode{seqan3::search_cfg::best}; + seqan3::search_cfg::hit_single_best; hits_result_t result = search("AGTAGT"_dna4, this->index, cfg) | seqan3::views::to; ASSERT_EQ(result.size(), 1u); @@ -359,9 +358,8 @@ TYPED_TEST(search_test, search_strategy_all_best) using hits_result_t = typename TestFixture::hits_result_t; { - auto search_cfg_mode_all_best = seqan3::search_cfg::mode{seqan3::search_cfg::all_best}; seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - search_cfg_mode_all_best; + seqan3::search_cfg::hit_all_best; EXPECT_EQ(uniquify(search("ACGT"_dna4, this->index, cfg)), (hits_result_t{{0, 0}, {0, 4}, {0, 8}})); // 1, 5, 9 are not best hits @@ -375,27 +373,27 @@ TYPED_TEST(search_test, search_strategy_strata) { seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{0}}; + seqan3::search_cfg::hit_strata{0}; EXPECT_EQ(uniquify(search("ACGT"_dna4, this->index, cfg)), (hits_result_t{{0, 0}, {0, 4}, {0, 8}})); } { seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{1}}; + seqan3::search_cfg::hit_strata{1}; EXPECT_EQ(uniquify(search("ACGT"_dna4, this->index, cfg)), (hits_result_t{{0, 0}, {0, 1}, {0, 4}, {0, 5}, {0, 8}, {0, 9}})); } { seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_cfg::total{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{1}}; + seqan3::search_cfg::hit_strata{1}; EXPECT_EQ(search("AAAA"_dna4, this->index, cfg) | seqan3::views::to, (hits_result_t{})); // no hit } // { // // best hit ACGT with 1 error, i.e. 1+1 // seqan3::configuration const cfg = seqan3::search_cfg::max_total_error{1} | - // seqan3::search_cfg::strategy_strata{1}; + // seqan3::search_cfg::hit_strata{1}; // EXPECT_EQ(uniquify(search(this->index, "CCGT"_dna4, cfg)), (hits_result_t{{0, 0}, {0, 1}, {0, 2}, {0, 3}, // {0, 4}, {0, 5}, {0, 6}, {0, 7}, // {0, 8}, {0, 9}, {0, 1}, {0, 0}})); @@ -404,7 +402,7 @@ TYPED_TEST(search_test, search_strategy_strata) // { // // best hit ACGT with 1 error, i.e. 1+1 // seqan3::configuration const cfg = seqan3::search_cfg::max_total_error{1} | - // seqan3::search_cfg::strategy_strata{1}; + // seqan3::search_cfg::hit_strata{1}; // EXPECT_EQ(uniquify(search(this->index, "CCGT"_dna4, cfg)), (hits_result_t{{0, 0}, {0, 1}, {0, 2}, {0, 3}, // {0, 4}, {0, 5}, {0, 6}, {0, 7}, // {0, 8}, {0, 9}, {0, 1}, {0, 0}}));