diff --git a/CHANGELOG.md b/CHANGELOG.md index 54015e11504..44c1484ad8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,13 @@ 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}` ## Notable Bug-fixes diff --git a/doc/tutorial/read_mapper/read_mapper_step2.cpp b/doc/tutorial/read_mapper/read_mapper_step2.cpp index e07e202cc4f..a658e5e5acd 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 cbdf6e94c35..a4b34af330b 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 ede42192667..6bdb3935d9a 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 21bebfa92b0..764897a2127 100644 --- a/doc/tutorial/search/index.md +++ b/doc/tutorial/search/index.md @@ -216,10 +216,10 @@ At position 85: ACT Besides the error configuration, you can define what kind of 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 mode. 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 diff --git a/doc/tutorial/search/search_small_snippets.cpp b/doc/tutorial/search/search_small_snippets.cpp index 480acde5ae9..99e7f38ba25 100644 --- a/doc/tutorial/search/search_small_snippets.cpp +++ b/doc/tutorial/search/search_small_snippets.cpp @@ -94,7 +94,7 @@ seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_c seqan3::search_cfg::substitution{0}, seqan3::search_cfg::insertion{1}, seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::best}; + seqan3::search_cfg::hit_single_best; //![mode_best] } @@ -104,7 +104,7 @@ seqan3::configuration const cfg = seqan3::search_cfg::max_error{seqan3::search_c seqan3::search_cfg::substitution{0}, seqan3::search_cfg::insertion{1}, seqan3::search_cfg::deletion{1}} | - seqan3::search_cfg::mode{seqan3::search_cfg::strata{2}}; + seqan3::search_cfg::hit_strata{2}; //![mode_strata] } diff --git a/doc/tutorial/search/search_solution4.cpp b/doc/tutorial/search/search_solution4.cpp index 80305744391..320e153fd83 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 96c5b6ad081..accb53291f8 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/default_configuration.hpp b/include/seqan3/search/configuration/default_configuration.hpp index 56b6885a160..ae65f938e4b 100644 --- a/include/seqan3/search/configuration/default_configuration.hpp +++ b/include/seqan3/search/configuration/default_configuration.hpp @@ -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/mode.hpp b/include/seqan3/search/configuration/mode.hpp index fcd66843943..119d3033d27 100644 --- a/include/seqan3/search/configuration/mode.hpp +++ b/include/seqan3/search/configuration/mode.hpp @@ -6,97 +6,109 @@ // ----------------------------------------------------------------------------------------------------- /*!\file - * \brief Provides the mode configuration to define the search modes "all", "all_best", "best" and "strata". + * \brief Provides the mode configuration to define the search modes "hit_strata", "hit_all", + * "hit_all_best", "hit_single_best". * \author Christopher Pockrandt * \author Rene Rahn + * \author Svenja Mehringer */ #pragma once -#include +#include + #include -#include -#include +#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 + */ +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::mode}; +}; -//!\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'. +/*!\brief Configuration element to receive all hits with the lowest number of errors within the bounds * \ingroup search_configuration - * \tparam value_t The underlying type. */ -struct strata : detail::strong_type +struct hit_all_best_tag : public pipeable_config_element { - using detail::strong_type::strong_type; + //!\privatesection + //!\brief Internal id to check for consistent configuration settings. + static constexpr detail::search_config_id id{detail::search_config_id::mode}; }; /*!\brief Configuration element to determine the search mode. * \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::mode}; +}; + +} // namespace seqan3::detail + +namespace seqan3::search_cfg +{ + +/*!\brief Configuration element to receive all hits within the error bounds. + * \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. | + * + * | Mode | 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 + x errors. | + * + * The individual configuration elements to select a search mode cannot be combined with each other. * * ### Example * * \include test/snippet/search/configuration_modes.cpp + * + * \hideinitializer */ -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> +inline constexpr detail::hit_all_tag hit_all{}; + +/*!\brief Configuration element to receive all hits with the lowest number of errors within the bounds. + * \ingroup search_configuration + * \copydetails seqan3::search_cfg::hit_all + * \hideinitializer + */ +inline constexpr detail::hit_all_best_tag hit_all_best{}; + +/*!\brief Configuration element to receive one best hit (with the lowest number of errors). + * \ingroup search_configuration + * \copydetails seqan3::search_cfg::hit_all + * \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 strata value. + * All hits are found with the fewest number of errors plus 'stratum'. + * \ingroup search_configuration + * \copydetails seqan3::search_cfg::hit_all + */ +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::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/search_scheme_algorithm.hpp b/include/seqan3/search/detail/search_scheme_algorithm.hpp index 27ef5f089a3..80f169119e9 100644 --- a/include/seqan3/search/detail/search_scheme_algorithm.hpp +++ b/include/seqan3/search/detail/search_scheme_algorithm.hpp @@ -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); } diff --git a/include/seqan3/search/detail/search_traits.hpp b/include/seqan3/search/detail/search_traits.hpp index f3ccd4e0a61..05c8668f0b5 100644 --- a/include/seqan3/search/detail/search_traits.hpp +++ b/include/seqan3/search/detail/search_traits.hpp @@ -42,17 +42,13 @@ 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_best_hits = 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>(); + 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 | diff --git a/include/seqan3/search/detail/unidirectional_search_algorithm.hpp b/include/seqan3/search/detail/unidirectional_search_algorithm.hpp index b8e033ca39b..fc73d6648ad 100644 --- a/include/seqan3/search/detail/unidirectional_search_algorithm.hpp +++ b/include/seqan3/search/detail/unidirectional_search_algorithm.hpp @@ -152,7 +152,7 @@ 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); } diff --git a/include/seqan3/search/search.hpp b/include/seqan3/search/search.hpp index bf041aedd50..3fe195ba765 100644 --- a/include/seqan3/search/search.hpp +++ b/include/seqan3/search/search.hpp @@ -34,20 +34,20 @@ 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 seqan3::search_cfg::mode was not set. * \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. * * \details * - * If seqan3::search_cfg::mode was not set, it defaults to seqan3::search_cfg::all. + * If seqan3::search_cfg::mode was not set, it defaults to seqan3::search_cfg::hit_all. */ template static auto add_default_mode_configuration(configuration_t const & cfg) { if constexpr (!detail::search_traits::has_mode_configuration) - return cfg | search_cfg::mode{search_cfg::all}; + return cfg | search_cfg::hit_all; else return cfg; } diff --git a/test/performance/search/search_benchmark.cpp b/test/performance/search/search_benchmark.cpp index 11a3e297543..c8b3473a006 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 26a7f921885..cf30af73f58 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 index 8b2a532b5b9..b68f35c48d7 100644 --- a/test/snippet/search/configuration_modes.cpp +++ b/test/snippet/search/configuration_modes.cpp @@ -2,17 +2,29 @@ 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 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 - // 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/unit/search/configuration/CMakeLists.txt b/test/unit/search/configuration/CMakeLists.txt new file mode 100644 index 00000000000..d8127cd301b --- /dev/null +++ b/test/unit/search/configuration/CMakeLists.txt @@ -0,0 +1 @@ +seqan3_test(mode_test.cpp) diff --git a/test/unit/search/configuration/mode_test.cpp b/test/unit/search/configuration/mode_test.cpp new file mode 100644 index 00000000000..c95781f827d --- /dev/null +++ b/test/unit/search/configuration/mode_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 a39cc7f7102..ba599a71c70 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 4ec8260b2ce..133578d6ad9 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}}));