Raptor 4.0.0-rc.1
A fast and space-efficient pre-filter
Loading...
Searching...
No Matches
is_fpr_exceeded.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <algorithm>
13#include <cassert>
14#include <cmath>
15#include <cstddef>
16
17#include <raptor/index.hpp>
18
19#include "strong_types.hpp"
20
21namespace raptor::detail
22{
23
25inline size_t level_of(raptor_index<index_structure::hibf> const & index, size_t ibf_idx)
26{
27 [[maybe_unused]] size_t const number_of_ibfs = index.ibf().ibf_vector.size();
28 size_t level{};
29
30 while (ibf_idx != 0u)
31 {
32 assert(level < number_of_ibfs && "Cycle in the chain of parent IBFs.");
33 ++level;
34 ibf_idx = index.ibf().prev_ibf_id[ibf_idx].ibf_idx;
35 }
36
37 return level;
38}
39
47 size_t const ibf_idx,
48 size_t const bin_idx,
49 size_t const level)
50{
51 auto const & hibf = index.ibf();
52 auto const & ibf = hibf.ibf_vector[ibf_idx];
53
54 double const new_fpr = [&ibf, bin_idx]()
55 {
56 double const exp_arg =
57 (ibf.hash_function_count() * ibf.occupancy[bin_idx]) / static_cast<double>(ibf.bin_size());
58 double const log_arg = 1.0 - std::exp(-exp_arg);
59 return std::exp(ibf.hash_function_count() * std::log(log_arg));
60 }();
61
62 bool const is_bin_merged = hibf.ibf_bin_to_user_bin_id[ibf_idx][bin_idx] == seqan::hibf::bin_kind::merged;
63 double const target_fpr = [&]() -> double
64 {
65 // A bin holding a user bin must respect the maximum FPR.
66 if (!is_bin_merged)
67 return index.fpr();
68
69 // A merged bin only needs to respect the relaxed FPR, because a query passing it is checked again in the
70 // IBF below. Rebuilding is more expensive the closer an IBF is to the top, so merged bins are granted
71 // additional slack that decays with the level: 2x the relaxed FPR at the top level, 1.25x one level below,
72 // and so on. The target FPR never exceeds 0.95, or the relaxed FPR itself if that is already higher.
73 double const relaxed_fpr = index.config().relaxed_fpr;
74 double const factor = 1.0 + 1.0 / ((level + 1u) * (level + 1u));
75 return std::min(relaxed_fpr * factor, std::max(relaxed_fpr, 0.95));
76 }();
77
78 return new_fpr > target_fpr;
79}
80
89
93{
94 auto const level = level_of(index, rebuild_location.ibf_idx);
95 assert(level == 0u); // This overload should only be called with the top-level IBF as rebuild location.
97}
98
99} // namespace raptor::detail
Definition index.hpp:48
T exp(T... args)
Provides raptor::raptor_index.
size_t level_of(raptor_index< index_structure::hibf > const &index, size_t ibf_idx)
The level of the IBF at ibf_idx within the HIBF. The top-level IBF has level 0.
Definition is_fpr_exceeded.hpp:25
bool is_fpr_exceeded(raptor_index< index_structure::hibf > const &index, insert_location const &insert_location)
Whether the first bin of insert_location exceeds its target FPR.
Definition is_fpr_exceeded.hpp:82
bool is_fpr_exceeded_impl(raptor_index< index_structure::hibf > const &index, size_t const ibf_idx, size_t const bin_idx, size_t const level)
Whether the technical bin at bin_idx in the IBF at ibf_idx exceeds its target FPR.
Definition is_fpr_exceeded.hpp:46
T log(T... args)
T max(T... args)
T min(T... args)
Provides the helper types shared by the raptor::insert_user_bin implementation.
A range of consecutive technical bins within one IBF, i.e. where a user bin is stored.
Definition src/update/insert/strong_types.hpp:36
size_t bin_idx
The first technical bin of the range.
Definition src/update/insert/strong_types.hpp:39
A merged bin whose subtree needs to be rebuilt.
Definition src/update/insert/strong_types.hpp:46
size_t ibf_idx
The IBF containing the merged bin, i.e. the parent of the subtree to rebuild.
Definition src/update/insert/strong_types.hpp:48
size_t bin_idx
The merged bin within that IBF.
Definition src/update/insert/strong_types.hpp:50
Hide me