OpenMS
Loading...
Searching...
No Matches
LinearResamplerAlign.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
11#include <limits>
12#include <atomic>
19
20namespace OpenMS
21{
23 extern OPENMS_DLLAPI std::atomic<bool> suppress_resampling_spacing_warning;
24
25 namespace Internal
26 {
53 } // namespace Internal
54
73 class OPENMS_DLLAPI LinearResamplerAlign :
75 public ProgressLogger
76 {
77
78 public:
79 LinearResamplerAlign() : DefaultParamHandler("LinearResamplerAlign")
80 {
81 defaults_.setValue("spacing", 0.05, "Spacing of the resampled output peaks.");
82 defaults_.setValue("ppm", "false", "Whether spacing is in ppm or Th");
83 defaultsToParam_();
84 }
85
95 template <class PeakContainerT>
96 void raster(PeakContainerT& container)
97 {
98 //return if nothing to do
99 if (container.empty()) return;
100
101 auto first = container.begin();
102 auto last = container.end();
103
104 double end_pos = (last - 1)->getPos();
105 double start_pos = first->getPos();
106 int number_resampled_points = (int)(ceil((end_pos - start_pos) / spacing_ + 1));
107
108 std::vector<typename PeakContainerT::PeakType> resampled_peak_container;
109 populate_raster_(resampled_peak_container, start_pos, end_pos, number_resampled_points);
110
111 raster(container.begin(), container.end(), resampled_peak_container.begin(), resampled_peak_container.end());
112
113 container.swap(resampled_peak_container);
114 }
115
130 template <typename PeakContainerT>
131 void raster_align(PeakContainerT& container, double start_pos, double end_pos)
132 {
133 //return if nothing to do
134 if (container.empty()) return;
135
136 if (end_pos < start_pos)
137 {
138 std::vector<typename PeakContainerT::PeakType> empty;
139 container.swap(empty);
140 return;
141 }
142
143 auto first = container.begin();
144 auto last = container.end();
145
146 verifySpacing_(first, last, [](auto x){return x->getPos();});
147
148 // get the iterators just before / after the two points start_pos / end_pos
149 while (first != container.end() && (first)->getPos() < start_pos) {++first;}
150 while (last != first && (last - 1)->getPos() > end_pos) {--last;}
151
152 int number_resampled_points = (int)(ceil((end_pos - start_pos) / spacing_ + 1));
153
154 std::vector<typename PeakContainerT::PeakType> resampled_peak_container;
155 populate_raster_(resampled_peak_container, start_pos, end_pos, number_resampled_points);
156
157 raster(first, last, resampled_peak_container.begin(), resampled_peak_container.end());
158
159 container.swap(resampled_peak_container);
160 }
161
183 template <typename PeakTypeIterator, typename ConstPeakTypeIterator>
184 void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resampled_begin, PeakTypeIterator resampled_end)
185 {
186 OPENMS_PRECONDITION(resampled_begin != resampled_end, "Output iterators cannot be identical") // as we use +1
187 // OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical")
188
189 verifySpacing_(raw_it, raw_end, [](auto x){return x->getPos();});
190
191 PeakTypeIterator resample_start = resampled_begin;
192
193 // need to get the raw iterator between two resampled iterators of the raw data
194 while (raw_it != raw_end && raw_it->getPos() < resampled_begin->getPos())
195 {
196 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity());
197 raw_it++;
198 }
199
200 while (raw_it != raw_end)
201 {
202 //advance the resample iterator until our raw point is between two resampled iterators
203 while (resampled_begin != resampled_end && resampled_begin->getPos() < raw_it->getPos()) {resampled_begin++;}
204 if (resampled_begin != resample_start) {resampled_begin--;}
205
206 // if we have the last datapoint we break
207 if ((resampled_begin + 1) == resampled_end) {break;}
208
209 double dist_left = fabs(raw_it->getPos() - resampled_begin->getPos());
210 double dist_right = fabs(raw_it->getPos() - (resampled_begin + 1)->getPos());
211
212 // distribute the intensity of the raw point according to the distance to resample_it and resample_it+1
213 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity() * dist_right / (dist_left + dist_right));
214 (resampled_begin + 1)->setIntensity((resampled_begin + 1)->getIntensity() + raw_it->getIntensity() * dist_left / (dist_left + dist_right));
215
216 raw_it++;
217 }
218
219 // add the final intensity to the right
220 while (raw_it != raw_end)
221 {
222 resampled_begin->setIntensity(resampled_begin->getIntensity() + raw_it->getIntensity());
223 raw_it++;
224 }
225 }
226
253 template <typename PeakTypeIterator, typename ConstPeakTypeIterator>
254 void raster(ConstPeakTypeIterator mz_raw_it, ConstPeakTypeIterator mz_raw_end,
255 ConstPeakTypeIterator int_raw_it, ConstPeakTypeIterator int_raw_end,
256 ConstPeakTypeIterator mz_resample_it, ConstPeakTypeIterator mz_resample_end,
257 PeakTypeIterator int_resample_it, PeakTypeIterator int_resample_end)
258 {
259 (void)int_raw_end; // avoid 'unused parameter' compile error
260 (void)int_resample_end; // avoid 'unused parameter' compile error
261 OPENMS_PRECONDITION(mz_resample_it != mz_resample_end, "Output iterators cannot be identical") // as we use +1
262 OPENMS_PRECONDITION(std::distance(mz_resample_it, mz_resample_end) == std::distance(int_resample_it, int_resample_end),
263 "Resample m/z and intensity iterators need to cover the same distance")
264 OPENMS_PRECONDITION(std::distance(mz_raw_it, mz_raw_end) == std::distance(int_raw_it, int_raw_end),
265 "Raw m/z and intensity iterators need to cover the same distance")
266 // OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical")
267
268 verifySpacing_(mz_raw_it, mz_raw_end, [](auto x){return *x;});
269
270 PeakTypeIterator mz_resample_start = mz_resample_it;
271
272 // need to get the raw iterator between two resampled iterators of the raw data
273 while (mz_raw_it != mz_raw_end && (*mz_raw_it) < (*mz_resample_it) )
274 {
275 (*int_resample_it) = *int_resample_it + *int_raw_it;
276 ++mz_raw_it;
277 ++int_raw_it;
278 }
279
280 while (mz_raw_it != mz_raw_end)
281 {
282 //advance the resample iterator until our raw point is between two resampled iterators
283 while (mz_resample_it != mz_resample_end && *mz_resample_it < *mz_raw_it)
284 {
285 ++mz_resample_it; ++int_resample_it;
286 }
287 if (mz_resample_it != mz_resample_start)
288 {
289 --mz_resample_it; --int_resample_it;
290 }
291
292 // if we have the last datapoint we break
293 if ((mz_resample_it + 1) == mz_resample_end) {break;}
294
295 double dist_left = fabs(*mz_raw_it - *mz_resample_it);
296 double dist_right = fabs(*mz_raw_it - *(mz_resample_it + 1));
297
298 // distribute the intensity of the raw point according to the distance to resample_it and resample_it+1
299 *(int_resample_it) = *int_resample_it + (*int_raw_it) * dist_right / (dist_left + dist_right);
300 *(int_resample_it + 1) = *(int_resample_it + 1) + (*int_raw_it) * dist_left / (dist_left + dist_right);
301
302 ++mz_raw_it;
303 ++int_raw_it;
304 }
305
306 // add the final intensity to the right
307 while (mz_raw_it != mz_raw_end)
308 {
309 *int_resample_it = *int_resample_it + (*int_raw_it);
310 ++mz_raw_it;
311 ++int_raw_it;
312 }
313 }
314
331 template <typename PeakTypeIterator>
332 void raster_interpolate(PeakTypeIterator raw_it, PeakTypeIterator raw_end, PeakTypeIterator resampled_start, PeakTypeIterator resampled_end)
333 {
334 // OPENMS_PRECONDITION(resampled_start != resampled_end, "Output iterators cannot be identical")
335 OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical") // as we use +1
336
337 verifySpacing_(raw_it, raw_end, [](PeakTypeIterator x){return x->getPos();});
338
339 PeakTypeIterator raw_start = raw_it;
340
341 // need to get the resampled iterator between two iterators of the raw data
342 while (resampled_start != resampled_end && resampled_start->getPos() < raw_it->getPos()) {resampled_start++;}
343
344 while (resampled_start != resampled_end)
345 {
346 //advance the raw_iterator until our current point we want to interpolate is between them
347 while (raw_it != raw_end && raw_it->getPos() < resampled_start->getPos()) {raw_it++;}
348 if (raw_it != raw_start) {raw_it--;}
349
350 // if we have the last datapoint we break
351 if ((raw_it + 1) == raw_end) {break;}
352
353 // use a linear interpolation between raw_it and raw_it+1
354 double m = ((raw_it + 1)->getIntensity() - raw_it->getIntensity()) / ((raw_it + 1)->getPos() - raw_it->getPos());
355 resampled_start->setIntensity(raw_it->getIntensity() + (resampled_start->getPos() - raw_it->getPos()) * m);
356 resampled_start++;
357 }
358
359 }
360
369 {
370 startProgress(0, exp.size(), "resampling of data");
371 for (Size i = 0; i < exp.size(); ++i)
372 {
373 raster(exp[i]);
374 setProgress(i);
375 }
376 endProgress();
377 }
378
379
380protected:
381
383 double spacing_;
384
386 bool ppm_;
387
388 void updateMembers_() override
389 {
390 spacing_ = param_.getValue("spacing");
391 ppm_ = (bool)param_.getValue("ppm").toBool();
392 }
393
395 template <typename PeakType>
396 void populate_raster_(std::vector<PeakType>& resampled_peak_container,
397 double start_pos, double end_pos, int number_resampled_points)
398 {
399 if (!ppm_)
400 {
401 // generate the resampled peaks at positions origin+i*spacing_
402 resampled_peak_container.resize(number_resampled_points);
403 typename std::vector<PeakType>::iterator it = resampled_peak_container.begin();
404 for (int i = 0; i < number_resampled_points; ++i)
405 {
406 it->setPos(start_pos + i * spacing_);
407 ++it;
408 }
409 }
410 else
411 {
412 // generate resampled peaks with ppm distance (not fixed)
413 double current_mz = start_pos;
414 while (current_mz < end_pos)
415 {
416 PeakType p;
417 p.setIntensity(0);
418 p.setPos(current_mz);
419 resampled_peak_container.push_back(p);
420
421 // increment current_mz
422 current_mz += current_mz * (spacing_ / 1e6);
423 }
424 }
425 }
426
427
429 template <typename PeakTypeIterator>
430 void verifySpacing_(PeakTypeIterator it, PeakTypeIterator end, auto access)
431 {
432 // ppm_ spacing is relative (parts-per-million) and cannot be compared
433 // directly against the absolute neighbour distance computed below.
434 if (ppm_) return;
435 if (it == end || std::next(it) == end) return;
436 double min_dist = std::numeric_limits<double>::infinity();
437 double current_dist{};
438
439 while (std::next(it) != end)
440 {
441 current_dist = (access(std::next(it)) - access(it));
442 if (min_dist > current_dist) min_dist = current_dist;
443 ++it;
444 }
445
446 if (spacing_ < min_dist && !suppress_resampling_spacing_warning.load())
447 {
448 OPENMS_LOG_WARN << "Resampling spacing (" << spacing_
449 << ") is smaller than the smallest distance between data points ("
450 << min_dist << "). This approximates the detector dead time and may produce spurious peaks.\n";
451 }
452 }
453
454 };
455}
#define OPENMS_LOG_WARN
Macro for warnings.
Definition LogStream.h:583
A base class for all classes handling default parameters.
Definition DefaultParamHandler.h:66
Internal RAII guard for temporary resampling warning suppression.
Definition LinearResamplerAlign.h:35
ScopedResamplingWarningSuppression(bool suppress=true)
Definition LinearResamplerAlign.h:37
bool previous_
Definition LinearResamplerAlign.h:51
~ScopedResamplingWarningSuppression()
Definition LinearResamplerAlign.h:42
ScopedResamplingWarningSuppression & operator=(const ScopedResamplingWarningSuppression &)=delete
ScopedResamplingWarningSuppression(const ScopedResamplingWarningSuppression &)=delete
Linear Resampling of raw data with alignment.
Definition LinearResamplerAlign.h:76
void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resampled_begin, PeakTypeIterator resampled_end)
Resample points (e.g. Peak1D) from an input range onto a prepopulated output range with given m/z,...
Definition LinearResamplerAlign.h:184
double spacing_
Spacing of the resampled data.
Definition LinearResamplerAlign.h:383
LinearResamplerAlign()
Definition LinearResamplerAlign.h:79
void raster_align(PeakContainerT &container, double start_pos, double end_pos)
Applies the resampling algorithm to a container (MSSpectrum or MSChromatogram) with fixed coordinates...
Definition LinearResamplerAlign.h:131
void raster_interpolate(PeakTypeIterator raw_it, PeakTypeIterator raw_end, PeakTypeIterator resampled_start, PeakTypeIterator resampled_end)
Applies the resampling algorithm using a linear interpolation.
Definition LinearResamplerAlign.h:332
void raster(PeakContainerT &container)
Applies the resampling algorithm to a container (MSSpectrum or MSChromatogram).
Definition LinearResamplerAlign.h:96
bool ppm_
Whether spacing_ is interpreted in ppm (true) or Th (false)
Definition LinearResamplerAlign.h:386
void updateMembers_() override
This method is used to update extra member variables at the end of the setParameters() method.
Definition LinearResamplerAlign.h:388
void populate_raster_(std::vector< PeakType > &resampled_peak_container, double start_pos, double end_pos, int number_resampled_points)
Generate raster for resampled peak container.
Definition LinearResamplerAlign.h:396
void rasterExperiment(PeakMap &exp)
Applies the resampling algorithm to all spectra of an MSExperiment.
Definition LinearResamplerAlign.h:368
void raster(ConstPeakTypeIterator mz_raw_it, ConstPeakTypeIterator mz_raw_end, ConstPeakTypeIterator int_raw_it, ConstPeakTypeIterator int_raw_end, ConstPeakTypeIterator mz_resample_it, ConstPeakTypeIterator mz_resample_end, PeakTypeIterator int_resample_it, PeakTypeIterator int_resample_end)
Resample points (with m/z and intensity in separate containers, but of same length) from an input ran...
Definition LinearResamplerAlign.h:254
void verifySpacing_(PeakTypeIterator it, PeakTypeIterator end, auto access)
helper function to warn the user when the resampling rate is too high
Definition LinearResamplerAlign.h:430
In-Memory representation of a mass spectrometry run.
Definition MSExperiment.h:49
Size size() const noexcept
The number of spectra.
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
Base class for all classes that want to report their progress.
Definition ProgressLogger.h:27
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition openms/include/OpenMS/CONCEPT/Macros.h:94
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
std::atomic< bool > suppress_resampling_spacing_warning
Shared process-wide flag to suppress repeated resampling-spacing warnings. During OpenSwathWorkflow e...