OpenMS
Loading...
Searching...
No Matches
NuXLSearchIndex.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Timo Sachsenberg $
6// $Authors: Timo Sachsenberg $
7// --------------------------------------------------------------------------
8
9#pragma once
10
12#include "NuXLConstants.h"
14
15#include <algorithm>
16#include <cmath>
17#include <cstdint>
18#include <limits>
19#include <map>
20#include <numeric>
21#include <string>
22#include <tuple>
23#include <unordered_map>
24#include <vector>
25
26namespace OpenMS
27{
37 {
38 const MSSpectrum* spec = nullptr;
39 std::vector<double> mz;
40 std::vector<float> intensity;
41 std::vector<int> charge;
42 static constexpr double BIN = 2.0;
43 static constexpr double INV_BIN = 1.0 / BIN;
44 std::vector<uint16_t> lb;
46 std::vector<uint8_t> has_tag_for_fa_id;
47
48 void build(const MSSpectrum& s)
49 {
50 spec = &s;
51 const size_t n = s.size();
52 mz.resize(n); intensity.resize(n); charge.resize(n);
54 for (size_t i = 0; i != n; ++i) { mz[i] = s[i].getMZ(); intensity[i] = s[i].getIntensity(); charge[i] = z[i]; }
55 if (n == 0 || n >= std::numeric_limits<uint16_t>::max()) { lb.clear(); return; } // fall back to binary search
56 const size_t nb = (size_t)(mz.back() * INV_BIN) + 2;
57 lb.resize(nb + 1);
58 size_t p = 0;
59 for (size_t k = 0; k <= nb; ++k)
60 {
61 const double edge = k * BIN;
62 while (p < n && mz[p] < edge) ++p;
63 lb[k] = (uint16_t)p;
64 }
65 }
66
68 inline size_t lowerBound(double x) const
69 {
70 if (lb.empty()) return std::lower_bound(mz.begin(), mz.end(), x) - mz.begin();
71 const long nb = (long)lb.size() - 1;
72 const long k = (long)(x * INV_BIN);
73 size_t lo = lb[std::clamp(k - 1, 0L, nb)];
74 const size_t hi = lb[std::clamp(k + 2, 0L, nb)];
75 while (lo < hi && mz[lo] < x) ++lo;
76 return lo;
77 }
78
80 inline size_t nearest(double x) const
81 {
82 const size_t n = mz.size();
83 const size_t it = lowerBound(x);
84 if (it == 0) return 0;
85 if (it == n) return n - 1;
86 if (std::fabs(mz[it] - x) < std::fabs(mz[it - 1] - x)) return it;
87 return it - 1;
88 }
89 };
90
95 {
96 std::vector<const NuXLFragmentAdductDefinition*> by_id;
97 std::unordered_map<std::string, int> name_id;
98 std::vector<int> id_to_name_id;
99 std::vector<int> rank;
100 std::vector<const std::vector<std::vector<double>>*> block_lists_by_name_id;
101
103 {
104 by_id.push_back(f);
105 auto it = name_id.emplace(f->name, (int)name_id.size()).first;
106 id_to_name_id.push_back(it->second);
107 return (int)by_id.size() - 1;
108 }
109
110 void finalize(const std::map<std::string, std::vector<std::vector<double>>>& block)
111 {
112 std::vector<int> order(by_id.size());
113 std::iota(order.begin(), order.end(), 0);
114 std::sort(order.begin(), order.end(), [&](int a, int b) { return *by_id[a] < *by_id[b]; });
115 rank.assign(by_id.size(), 0);
116 int r = 0;
117 for (size_t i = 0; i != order.size(); ++i)
118 {
119 if (i > 0 && *by_id[order[i - 1]] < *by_id[order[i]]) ++r;
120 rank[order[i]] = r;
121 }
122 block_lists_by_name_id.assign(name_id.size(), nullptr);
123 for (const auto& [name, id] : name_id)
124 {
125 auto it = block.find(name);
126 if (it != block.end()) block_lists_by_name_id[id] = &it->second;
127 }
128 }
129
131 {
132 si.has_tag_for_fa_id.assign(name_id.size(), 0);
133 if (si.spec->getStringDataArrays().empty()) return;
134 const auto& tags = si.spec->getStringDataArrays()[0];
135 for (const auto& [name, id] : name_id)
136 {
137 si.has_tag_for_fa_id[id] = std::find(tags.begin(), tags.end(), name) != tags.end();
138 }
139 }
140 };
141
144 {
145 char nucleotide = '?';
146 const std::vector<NuXLFragmentAdductDefinition>* fas = nullptr;
147 std::vector<int> name_ids;
148 std::vector<int> ranks;
149 };
150
153 {
154 std::vector<double> mass;
155 std::vector<std::pair<Size, int>> scan_and_isotope;
156 double lo = 0;
157 static constexpr double BIN = 0.05;
158 std::vector<uint32_t> bucket;
159
160 template <class MultiMap>
161 void build(const MultiMap& mm)
162 {
163 for (const auto& e : mm) { mass.push_back(e.first); scan_and_isotope.push_back(e.second); }
164 lo = mass.empty() ? 0 : mass.front();
165 const size_t nb = mass.empty() ? 1 : (size_t)((mass.back() - lo) / BIN) + 2;
166 bucket.resize(nb + 1);
167 size_t q = 0;
168 for (size_t k = 0; k <= nb; ++k)
169 {
170 const double edge = lo + k * BIN;
171 while (q < mass.size() && mass[q] < edge) ++q;
172 bucket[k] = (uint32_t)q;
173 }
174 }
175 std::pair<size_t, size_t> range_(double x) const
176 {
177 const long nb = (long)bucket.size() - 1;
178 const long k = (long)std::floor((x - lo) / BIN);
179 return {bucket[std::clamp(k - 1, 0L, nb)], bucket[std::clamp(k + 2, 0L, nb)]};
180 }
182 size_t lowerBound(double x) const { auto [a, b] = range_(x); return std::lower_bound(mass.begin() + a, mass.begin() + b, x) - mass.begin(); }
183 size_t upperBound(double x) const { auto [a, b] = range_(x); return std::upper_bound(mass.begin() + a, mass.begin() + b, x) - mass.begin(); }
184 };
185
188 {
189 std::vector<double> t;
191 {
192 t.resize(4096);
193 t[0] = 0; t[1] = 0;
194 double z(0);
195 for (size_t x = 2; x < t.size(); ++x) { z += std::log((double)x); t[x] = z; }
196 }
197 double operator()(UInt x) const
198 {
199 if (x < t.size()) return t[x];
200 const double dx = static_cast<double>(x);
201 double z(0);
202 for (double y = 2; y <= dx; ++y) { z += std::log(y); }
203 return z;
204 }
205 };
206
209 {
210 std::vector<double> intensity_sum, b, y, a, intensity_xl, b_xl, y_xl, a_xl;
211 std::vector<uint8_t> peak_matched, peak_matched_xl;
212 static constexpr int N_ION_TYPES = 6;
213 struct FirstPassEntry { double mass; uint32_t cnt[3][2]; size_t off; };
214 std::vector<FirstPassEntry> fa_entries;
215 std::vector<int32_t> fa_idx;
216 std::vector<std::tuple<size_t, size_t, const NuXLFragmentAdductDefinition*, int>> matches_z_fa;
217 std::vector<std::vector<double>> match_odds;
218 void resetCandidate() { fa_entries.clear(); fa_idx.clear(); }
219
220 template <class F>
221 double matchOdds(size_t N, size_t matches, double p, F f)
222 {
223 if (N >= match_odds.size()) match_odds.resize(N + 1);
224 auto& row = match_odds[N];
225 if (matches > N) return f(N, matches, p);
226 // grows only to the largest match count seen (matches stays small, N can be ~2000)
227 if (matches >= row.size()) row.resize(matches + 1, std::numeric_limits<double>::quiet_NaN());
228 double& v = row[matches];
229 if (std::isnan(v)) v = f(N, matches, p);
230 return v;
231 }
232 };
233} // namespace OpenMS
The representation of a 1D spectrum.
Definition MSSpectrum.h:45
const IntegerDataArrays & getIntegerDataArrays() const
Returns a const reference to the integer meta data arrays.
const StringDataArrays & getStringDataArrays() const
Returns a const reference to the string meta data arrays.
void clear(bool clear_meta_data)
Clears all data and meta data.
static constexpr size_t IA_CHARGE_INDEX
IntegerDataArray slot holding the per-peak charge.
Definition NuXLConstants.h:40
unsigned int UInt
Unsigned integer type.
Definition Types.h:64
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
char nucleotide
Definition NuXLSearchIndex.h:145
const std::vector< NuXLFragmentAdductDefinition > * fas
Definition NuXLSearchIndex.h:146
std::vector< int > name_ids
Definition NuXLSearchIndex.h:147
std::vector< int > ranks
Definition NuXLSearchIndex.h:148
Fragment adducts of one cross-linked nucleotide with their registry ids and ranks.
Definition NuXLSearchIndex.h:144
Definition NuXLFragmentAdductDefinition.h:24
std::string name
Definition NuXLFragmentAdductDefinition.h:26
Definition NuXLSearchIndex.h:95
std::vector< const NuXLFragmentAdductDefinition * > by_id
Definition NuXLSearchIndex.h:96
void finalize(const std::map< std::string, std::vector< std::vector< double > > > &block)
Definition NuXLSearchIndex.h:110
std::vector< int > rank
Definition NuXLSearchIndex.h:99
std::vector< int > id_to_name_id
Definition NuXLSearchIndex.h:98
std::unordered_map< std::string, int > name_id
has_tag only depends on the name
Definition NuXLSearchIndex.h:97
void annotateSpectrum(NuXLSpectrumIndex &si) const
Definition NuXLSearchIndex.h:130
int add(const NuXLFragmentAdductDefinition *f)
Definition NuXLSearchIndex.h:102
std::vector< const std::vector< std::vector< double > > * > block_lists_by_name_id
Definition NuXLSearchIndex.h:100
logfactorial with the exact same summation sequence as the loop it replaces
Definition NuXLSearchIndex.h:188
double operator()(UInt x) const
Definition NuXLSearchIndex.h:197
std::vector< double > t
Definition NuXLSearchIndex.h:189
NuXLLogFactorialTable()
Definition NuXLSearchIndex.h:190
Sorted precursor masses (same order as the multimap they are created from) with a bucket index.
Definition NuXLSearchIndex.h:153
size_t upperBound(double x) const
Definition NuXLSearchIndex.h:183
size_t lowerBound(double x) const
== multimap::lower_bound / upper_bound (as index)
Definition NuXLSearchIndex.h:182
std::vector< std::pair< Size, int > > scan_and_isotope
Definition NuXLSearchIndex.h:155
double lo
Definition NuXLSearchIndex.h:156
static constexpr double BIN
Definition NuXLSearchIndex.h:157
std::vector< double > mass
Definition NuXLSearchIndex.h:154
std::vector< uint32_t > bucket
bucket[k] = index of the first precursor with mass >= lo + k * BIN
Definition NuXLSearchIndex.h:158
void build(const MultiMap &mm)
Definition NuXLSearchIndex.h:161
std::pair< size_t, size_t > range_(double x) const
Definition NuXLSearchIndex.h:175
per-thread buffers (no heap allocations per candidate) and memoized match odds
Definition NuXLSearchIndex.h:209
std::vector< double > a
Definition NuXLSearchIndex.h:210
std::vector< double > b_xl
Definition NuXLSearchIndex.h:210
double mass
Definition NuXLSearchIndex.h:213
std::vector< FirstPassEntry > fa_entries
first pass of the shifted ion scoring, per fragment adduct mass
Definition NuXLSearchIndex.h:214
std::vector< uint8_t > peak_matched
Definition NuXLSearchIndex.h:211
std::vector< double > a_xl
Definition NuXLSearchIndex.h:210
std::vector< std::tuple< size_t, size_t, const NuXLFragmentAdductDefinition *, int > > matches_z_fa
Definition NuXLSearchIndex.h:216
std::vector< double > y
Definition NuXLSearchIndex.h:210
std::vector< double > y_xl
Definition NuXLSearchIndex.h:210
std::vector< int32_t > fa_idx
matched peak index (or -1) per [entry][ion type][charge][ion]
Definition NuXLSearchIndex.h:215
size_t off
Definition NuXLSearchIndex.h:213
static constexpr int N_ION_TYPES
shifted b, a, y (pre-selection) and b-H2O, y-H2O, y-NH3 (neutral loss peaks)
Definition NuXLSearchIndex.h:212
std::vector< double > b
Definition NuXLSearchIndex.h:210
std::vector< uint8_t > peak_matched_xl
Definition NuXLSearchIndex.h:211
std::vector< std::vector< double > > match_odds
[N][matches], NaN = not yet computed
Definition NuXLSearchIndex.h:217
uint32_t cnt[3][2]
Definition NuXLSearchIndex.h:213
void resetCandidate()
Definition NuXLSearchIndex.h:218
std::vector< double > intensity_xl
Definition NuXLSearchIndex.h:210
std::vector< double > intensity_sum
Definition NuXLSearchIndex.h:210
double matchOdds(size_t N, size_t matches, double p, F f)
Definition NuXLSearchIndex.h:221
Definition NuXLSearchIndex.h:213
Search-time lookup structures for the OpenNuXL database search.
Definition NuXLSearchIndex.h:37
std::vector< uint16_t > lb
lb[k] = index of the first peak with m/z >= k * BIN
Definition NuXLSearchIndex.h:44
size_t nearest(double x) const
same result as MSSpectrum::findNearest(x)
Definition NuXLSearchIndex.h:80
std::vector< int > charge
peak charges (IntegerDataArray NuXLConstants::IA_CHARGE_INDEX)
Definition NuXLSearchIndex.h:41
size_t lowerBound(double x) const
same result as std::lower_bound on the peak m/z
Definition NuXLSearchIndex.h:68
const MSSpectrum * spec
Definition NuXLSearchIndex.h:38
static constexpr double INV_BIN
Definition NuXLSearchIndex.h:43
float marker_ions_sub_score
MorpheusScore of the spectrum against all marker ions (independent of the candidate)
Definition NuXLSearchIndex.h:45
static constexpr double BIN
Definition NuXLSearchIndex.h:42
std::vector< double > mz
peak m/z (copy, contiguous)
Definition NuXLSearchIndex.h:39
std::vector< float > intensity
peak intensities (copy, contiguous)
Definition NuXLSearchIndex.h:40
std::vector< uint8_t > has_tag_for_fa_id
fragment adduct name (by registry id) is listed in StringDataArray 0 (nucleotide tags)
Definition NuXLSearchIndex.h:46
void build(const MSSpectrum &s)
Definition NuXLSearchIndex.h:48