OpenMS
LinearResamplerAlign.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Hannes Roest $
6 // $Authors: Hannes Roest $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
12 #include <OpenMS/CONCEPT/Macros.h>
13 
14 namespace OpenMS
15 {
16 
31  class OPENMS_DLLAPI LinearResamplerAlign :
32  public LinearResampler
33  {
34 
35 public:
36 
38  {
39  defaults_.setValue("spacing", 0.05, "Spacing of the resampled output peaks.");
40  defaults_.setValue("ppm", "false", "Whether spacing is in ppm or Th");
41  defaultsToParam_();
42  }
43 
53  template <class SpecT>
54  void raster(SpecT& container)
55  {
56  //return if nothing to do
57  if (container.empty()) return;
58 
59  typename SpecT::iterator first = container.begin();
60  typename SpecT::iterator last = container.end();
61 
62  double end_pos = (last - 1)->getMZ();
63  double start_pos = first->getMZ();
64  int number_resampled_points = (int)(ceil((end_pos - start_pos) / spacing_ + 1));
65 
66  std::vector<typename SpecT::PeakType> resampled_peak_container;
67  populate_raster_(resampled_peak_container, start_pos, end_pos, number_resampled_points);
68 
69  raster(container.begin(), container.end(), resampled_peak_container.begin(), resampled_peak_container.end());
70 
71  container.swap(resampled_peak_container);
72  }
73 
89  template <typename SpecT>
90  void raster_align(SpecT& container, double start_pos, double end_pos)
91  {
92  //return if nothing to do
93  if (container.empty()) return;
94 
95  if (end_pos < start_pos)
96  {
97  std::vector<typename SpecT::PeakType> empty;
98  container.swap(empty);
99  return;
100  }
101 
102  typename SpecT::iterator first = container.begin();
103  typename SpecT::iterator last = container.end();
104 
105  // get the iterators just before / after the two points start_pos / end_pos
106  while (first != container.end() && (first)->getMZ() < start_pos) {++first;}
107  while (last != first && (last - 1)->getMZ() > end_pos) {--last;}
108 
109  int number_resampled_points = (int)(ceil((end_pos - start_pos) / spacing_ + 1));
110 
111  std::vector<typename SpecT::PeakType> resampled_peak_container;
112  populate_raster_(resampled_peak_container, start_pos, end_pos, number_resampled_points);
113 
114  raster(first, last, resampled_peak_container.begin(), resampled_peak_container.end());
115 
116  container.swap(resampled_peak_container);
117  }
118 
140  template <typename PeakTypeIterator, typename ConstPeakTypeIterator>
141  void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resample_it, PeakTypeIterator resample_end)
142  {
143  OPENMS_PRECONDITION(resample_it != resample_end, "Output iterators cannot be identical") // as we use +1
144  // OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical")
145 
146  PeakTypeIterator resample_start = resample_it;
147 
148  // need to get the raw iterator between two resampled iterators of the raw data
149  while (raw_it != raw_end && raw_it->getMZ() < resample_it->getMZ())
150  {
151  resample_it->setIntensity(resample_it->getIntensity() + raw_it->getIntensity());
152  raw_it++;
153  }
154 
155  while (raw_it != raw_end)
156  {
157  //advance the resample iterator until our raw point is between two resampled iterators
158  while (resample_it != resample_end && resample_it->getMZ() < raw_it->getMZ()) {resample_it++;}
159  if (resample_it != resample_start) {resample_it--;}
160 
161  // if we have the last datapoint we break
162  if ((resample_it + 1) == resample_end) {break;}
163 
164  double dist_left = fabs(raw_it->getMZ() - resample_it->getMZ());
165  double dist_right = fabs(raw_it->getMZ() - (resample_it + 1)->getMZ());
166 
167  // distribute the intensity of the raw point according to the distance to resample_it and resample_it+1
168  resample_it->setIntensity(resample_it->getIntensity() + raw_it->getIntensity() * dist_right / (dist_left + dist_right));
169  (resample_it + 1)->setIntensity((resample_it + 1)->getIntensity() + raw_it->getIntensity() * dist_left / (dist_left + dist_right));
170 
171  raw_it++;
172  }
173 
174  // add the final intensity to the right
175  while (raw_it != raw_end)
176  {
177  resample_it->setIntensity(resample_it->getIntensity() + raw_it->getIntensity());
178  raw_it++;
179  }
180  }
181 
207  template <typename PeakTypeIterator, typename ConstPeakTypeIterator>
208 #ifdef OPENMS_ASSERTIONS
209  void raster(ConstPeakTypeIterator mz_raw_it, ConstPeakTypeIterator mz_raw_end,
210  ConstPeakTypeIterator int_raw_it, ConstPeakTypeIterator int_raw_end,
211  PeakTypeIterator mz_resample_it, PeakTypeIterator mz_resample_end,
212  PeakTypeIterator int_resample_it, PeakTypeIterator int_resample_end)
213 #else
214  void raster(ConstPeakTypeIterator mz_raw_it, ConstPeakTypeIterator mz_raw_end,
215  ConstPeakTypeIterator int_raw_it, ConstPeakTypeIterator /* int_raw_end */,
216  PeakTypeIterator mz_resample_it, PeakTypeIterator mz_resample_end,
217  PeakTypeIterator int_resample_it, PeakTypeIterator /* int_resample_end */)
218 #endif
219  {
220  OPENMS_PRECONDITION(mz_resample_it != mz_resample_end, "Output iterators cannot be identical") // as we use +1
221  OPENMS_PRECONDITION(std::distance(mz_resample_it, mz_resample_end) == std::distance(int_resample_it, int_resample_end),
222  "Resample m/z and intensity iterators need to cover the same distance")
223  OPENMS_PRECONDITION(std::distance(mz_raw_it, mz_raw_end) == std::distance(int_raw_it, int_raw_end),
224  "Raw m/z and intensity iterators need to cover the same distance")
225  // OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical")
226 
227  PeakTypeIterator mz_resample_start = mz_resample_it;
228 
229  // need to get the raw iterator between two resampled iterators of the raw data
230  while (mz_raw_it != mz_raw_end && (*mz_raw_it) < (*mz_resample_it) )
231  {
232  (*int_resample_it) = *int_resample_it + *int_raw_it;
233  ++mz_raw_it;
234  ++int_raw_it;
235  }
236 
237  while (mz_raw_it != mz_raw_end)
238  {
239  //advance the resample iterator until our raw point is between two resampled iterators
240  while (mz_resample_it != mz_resample_end && *mz_resample_it < *mz_raw_it)
241  {
242  ++mz_resample_it; ++int_resample_it;
243  }
244  if (mz_resample_it != mz_resample_start)
245  {
246  --mz_resample_it; --int_resample_it;
247  }
248 
249  // if we have the last datapoint we break
250  if ((mz_resample_it + 1) == mz_resample_end) {break;}
251 
252  double dist_left = fabs(*mz_raw_it - *mz_resample_it);
253  double dist_right = fabs(*mz_raw_it - *(mz_resample_it + 1));
254 
255  // distribute the intensity of the raw point according to the distance to resample_it and resample_it+1
256  *(int_resample_it) = *int_resample_it + (*int_raw_it) * dist_right / (dist_left + dist_right);
257  *(int_resample_it + 1) = *(int_resample_it + 1) + (*int_raw_it) * dist_left / (dist_left + dist_right);
258 
259  ++mz_raw_it;
260  ++int_raw_it;
261  }
262 
263  // add the final intensity to the right
264  while (mz_raw_it != mz_raw_end)
265  {
266  *int_resample_it = *int_resample_it + (*int_raw_it);
267  ++mz_raw_it;
268  ++int_raw_it;
269  }
270  }
271 
288  template <typename PeakTypeIterator>
289  void raster_interpolate(PeakTypeIterator raw_it, PeakTypeIterator raw_end, PeakTypeIterator resample_it, PeakTypeIterator resampled_end)
290  {
291  // OPENMS_PRECONDITION(resample_it != resampled_end, "Output iterators cannot be identical")
292  OPENMS_PRECONDITION(raw_it != raw_end, "Input iterators cannot be identical") // as we use +1
293 
294  PeakTypeIterator raw_start = raw_it;
295 
296  // need to get the resampled iterator between two iterators of the raw data
297  while (resample_it != resampled_end && resample_it->getMZ() < raw_it->getMZ()) {resample_it++;}
298 
299  while (resample_it != resampled_end)
300  {
301  //advance the raw_iterator until our current point we want to interpolate is between them
302  while (raw_it != raw_end && raw_it->getMZ() < resample_it->getMZ()) {raw_it++;}
303  if (raw_it != raw_start) {raw_it--;}
304 
305  // if we have the last datapoint we break
306  if ((raw_it + 1) == raw_end) {break;}
307 
308  // use a linear interpolation between raw_it and raw_it+1
309  double m = ((raw_it + 1)->getIntensity() - raw_it->getIntensity()) / ((raw_it + 1)->getMZ() - raw_it->getMZ());
310  resample_it->setIntensity(raw_it->getIntensity() + (resample_it->getMZ() - raw_it->getMZ()) * m);
311  resample_it++;
312  }
313 
314  }
315 
316 protected:
317 
319  bool ppm_;
320 
321  void updateMembers_() override
322  {
323  spacing_ = param_.getValue("spacing");
324  ppm_ = (bool)param_.getValue("ppm").toBool();
325  }
326 
328  template <typename PeakType>
329  void populate_raster_(std::vector<PeakType>& resampled_peak_container,
330  double start_pos, double end_pos, int number_resampled_points)
331  {
332  if (!ppm_)
333  {
334  // generate the resampled peaks at positions origin+i*spacing_
335  resampled_peak_container.resize(number_resampled_points);
336  typename std::vector<PeakType>::iterator it = resampled_peak_container.begin();
337  for (int i = 0; i < number_resampled_points; ++i)
338  {
339  it->setMZ(start_pos + i * spacing_);
340  ++it;
341  }
342  }
343  else
344  {
345  // generate resampled peaks with ppm distance (not fixed)
346  double current_mz = start_pos;
347  while (current_mz < end_pos)
348  {
349  PeakType p;
350  p.setIntensity(0);
351  p.setMZ(current_mz);
352  resampled_peak_container.push_back(p);
353 
354  // increment current_mz
355  current_mz += current_mz * (spacing_ / 1e6);
356  }
357  }
358  }
359  };
360 
361 }
362 
363 
Linear Resampling of raw data with alignment.
Definition: LinearResamplerAlign.h:33
void raster(SpecT &container)
Applies the resampling algorithm to a container (MSSpectrum or MSChromatogram).
Definition: LinearResamplerAlign.h:54
void raster_align(SpecT &container, double start_pos, double end_pos)
Applies the resampling algorithm to a container (MSSpectrum or MSChromatogram) with fixed coordinates...
Definition: LinearResamplerAlign.h:90
LinearResamplerAlign()
Definition: LinearResamplerAlign.h:37
void raster(ConstPeakTypeIterator mz_raw_it, ConstPeakTypeIterator mz_raw_end, ConstPeakTypeIterator int_raw_it, ConstPeakTypeIterator, PeakTypeIterator mz_resample_it, PeakTypeIterator mz_resample_end, PeakTypeIterator int_resample_it, PeakTypeIterator)
Applies the resampling algorithm.
Definition: LinearResamplerAlign.h:214
void raster(ConstPeakTypeIterator raw_it, ConstPeakTypeIterator raw_end, PeakTypeIterator resample_it, PeakTypeIterator resample_end)
Applies the resampling algorithm.
Definition: LinearResamplerAlign.h:141
bool ppm_
Spacing of the resampled data.
Definition: LinearResamplerAlign.h:319
void updateMembers_() override
This method is used to update extra member variables at the end of the setParameters() method.
Definition: LinearResamplerAlign.h:321
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:329
void raster_interpolate(PeakTypeIterator raw_it, PeakTypeIterator raw_end, PeakTypeIterator resample_it, PeakTypeIterator resampled_end)
Applies the resampling algorithm using a linear interpolation.
Definition: LinearResamplerAlign.h:289
Linear Resampling of raw data.
Definition: LinearResampler.h:38
A 2-dimensional raw data point or peak.
Definition: Peak2D.h:29
void setMZ(CoordinateType coordinate)
Mutable access to the m/z coordinate (index 1)
Definition: Peak2D.h:178
void setIntensity(IntensityType intensity)
Sets data point intensity (height)
Definition: Peak2D.h:148
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition: openms/include/OpenMS/CONCEPT/Macros.h:94
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22