OpenMS
Loading...
Searching...
No Matches
LinearResampling.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: Hannes Roest $
6// $Authors: Hannes Roest, Luis Jacob Keller, Alen Saric$
7// --------------------------------------------------------------------------
8
9#pragma once
10
13#include <atomic>
14#include <cmath>
15#include <iterator>
16#include <limits>
17#include <vector>
18
19namespace OpenMS
20{
22extern OPENMS_DLLAPI std::atomic<bool> suppress_resampling_spacing_warning;
23
24namespace Internal
25{
32 class OPENMS_DLLAPI LinearResampling
33 {
34 public:
40 explicit LinearResampling(double spacing, bool ppm = false): spacing_(spacing), ppm_(ppm)
41 {
42 }
43
48 template<class PeakContainerT>
49 void raster(PeakContainerT& container)
50 {
51 // return if nothing to do
52 if (container.empty()) return;
53
54 auto first = container.begin();
55 auto last = container.end();
56
57 double end_pos = (last - 1)->getPos();
58 double start_pos = first->getPos();
59 int number_resampled_points = (int)(ceil((end_pos - start_pos) / spacing_ + 1));
60
61 std::vector<typename PeakContainerT::PeakType> resampled_peak_container;
62 populateRaster(resampled_peak_container, start_pos, end_pos, number_resampled_points);
63
64 raster(container.begin(), container.end(), resampled_peak_container.begin(), resampled_peak_container.end());
65
66 container.swap(resampled_peak_container);
67 }
68
79 template<typename PeakTypeIterator, typename ConstPeakTypeIterator>
80 void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resampled_begin, PeakTypeIterator resampled_end)
81 {
82 OPENMS_PRECONDITION(resampled_begin != resampled_end, "Output iterators cannot be identical") // as we use +1
83 // OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical")
84
85 verifySpacing(raw_it, raw_end, [](auto x) { return x->getPos(); });
86
87 PeakTypeIterator resample_start = resampled_begin;
88
89 // need to get the raw iterator between two resampled iterators of the raw data
90 while (raw_it != raw_end && raw_it->getPos() < resampled_begin->getPos())
91 {
92 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity());
93 raw_it++;
94 }
95
96 while (raw_it != raw_end)
97 {
98 // advance the resample iterator until our raw point is between two resampled iterators
99 while (resampled_begin != resampled_end && resampled_begin->getPos() < raw_it->getPos())
100 {
101 resampled_begin++;
102 }
103 if (resampled_begin != resample_start) { resampled_begin--; }
104
105 // if we have the last datapoint we break
106 if ((resampled_begin + 1) == resampled_end) { break; }
107
108 double dist_left = fabs(raw_it->getPos() - resampled_begin->getPos());
109 double dist_right = fabs(raw_it->getPos() - (resampled_begin + 1)->getPos());
110
111 // distribute the intensity of the raw point according to the distance to resample_it and resample_it+1
112 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity() * dist_right / (dist_left + dist_right));
113 (resampled_begin + 1)->setIntensity((resampled_begin + 1)->getIntensity() + raw_it->getIntensity() * dist_left / (dist_left + dist_right));
114
115 raw_it++;
116 }
117
118 // add the final intensity to the right
119 while (raw_it != raw_end)
120 {
121 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity());
122 raw_it++;
123 }
124 }
125
133 template<typename PeakType>
134 void populateRaster(std::vector<PeakType>& resampled_peak_container, double start_pos, double end_pos, int number_resampled_points)
135 {
136 if (! ppm_)
137 {
138 // generate the resampled peaks at positions origin+i*spacing_
139 resampled_peak_container.resize(number_resampled_points);
140 typename std::vector<PeakType>::iterator it = resampled_peak_container.begin();
141 for (int i = 0; i < number_resampled_points; ++i)
142 {
143 it->setPos(start_pos + i * spacing_);
144 ++it;
145 }
146 }
147 else
148 {
149 // generate resampled peaks with ppm distance (not fixed)
150 double current_mz = start_pos;
151 while (current_mz < end_pos)
152 {
153 PeakType p;
154 p.setIntensity(0);
155 p.setPos(current_mz);
156 resampled_peak_container.push_back(p);
157
158 // increment current_mz
159 current_mz += current_mz * (spacing_ / 1e6);
160 }
161 }
162 }
163
170 template<typename PeakTypeIterator>
171 void verifySpacing(PeakTypeIterator it, PeakTypeIterator end, auto access)
172 {
173 // ppm_ spacing is relative (parts-per-million) and cannot be compared
174 // directly against the absolute neighbour distance computed below.
175 if (ppm_) return;
176 if (it == end || std::next(it) == end) return;
177 double min_dist = std::numeric_limits<double>::infinity();
178 double current_dist {};
179
180 while (std::next(it) != end)
181 {
182 current_dist = (access(std::next(it)) - access(it));
183 if (min_dist > current_dist) min_dist = current_dist;
184 ++it;
185 }
186
187 if (spacing_ < min_dist && ! suppress_resampling_spacing_warning.load())
188 {
189 OPENMS_LOG_WARN << "Resampling spacing (" << spacing_ << ") is smaller than the smallest distance between data points (" << min_dist
190 << "). This approximates the detector dead time and may produce spurious peaks.\n";
191 }
192 }
193
194 private:
195 double spacing_;
196 bool ppm_;
197 };
198} // namespace Internal
199} // namespace OpenMS
#define OPENMS_LOG_WARN
Macro for warnings.
Definition LogStream.h:608
Shared linear resampling implementation without parameter or progress handling.
Definition LinearResampling.h:33
void verifySpacing(PeakTypeIterator it, PeakTypeIterator end, auto access)
Emit the existing spacing warning for absolute grids when enabled.
Definition LinearResampling.h:171
void populateRaster(std::vector< PeakType > &resampled_peak_container, double start_pos, double end_pos, int number_resampled_points)
Populate an absolute or ppm grid using the existing endpoint convention.
Definition LinearResampling.h:134
void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resampled_begin, PeakTypeIterator resampled_end)
Distribute input intensities onto an existing output grid.
Definition LinearResampling.h:80
double spacing_
Definition LinearResampling.h:195
void raster(PeakContainerT &container)
Resample a peak container onto a grid spanning its first and last points.
Definition LinearResampling.h:49
bool ppm_
Definition LinearResampling.h:196
LinearResampling(double spacing, bool ppm=false)
Construct a resampler with explicit spacing and units.
Definition LinearResampling.h:40
A 2-dimensional raw data point or peak.
Definition Peak2D.h:30
void setIntensity(IntensityType intensity)
Sets data point intensity (height)
Definition Peak2D.h:149
OpenMS looks in the< code > OPENMS_THERMO_MANAGED_DIR</code > environment variable first
Definition common-cmake-parameters.doxygen:179
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition openms/include/OpenMS/CONCEPT/Macros.h:91
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
std::atomic< bool > suppress_resampling_spacing_warning
Shared process-wide flag controlling resampling-spacing warnings.