OpenMS
MatchedIterator.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: Chris Bielow $
6 // $Authors: Chris Bielow $
7 // --------------------------------------------------------------------------
8 //
9 #pragma once
10 
11 #include <OpenMS/CONCEPT/Macros.h>
14 
15 #include <iterator>
16 #include <type_traits>
17 
18 namespace OpenMS
19 {
20 
44  template <typename CONT_T, typename TRAIT, bool CONST_T = true >
46  {
47  public:
48  // define the 5 types required for an iterator. Deriving from std::iterator is deprecated in C++17.
49  using iterator_category = std::forward_iterator_tag;
50  using value_type = typename CONT_T::value_type; //< dereferences to an element in the target container
51  using difference_type = std::ptrdiff_t;
52  using pointer = typename std::conditional<CONST_T, typename CONT_T::value_type const*, typename CONT_T::value_type*>::type;
53  using reference = typename std::conditional<CONST_T, typename CONT_T::value_type const&, typename CONT_T::value_type&>::type;
54 
55  using CONT_IT = typename std::conditional<CONST_T, typename CONT_T::const_iterator, typename CONT_T::iterator>::type; // for dereferencing etc
56  using CONST_CONT_IT = typename CONT_T::const_iterator; // for input containers
57 
67  explicit MatchedIterator(const CONT_T& ref, const CONT_T& target, float tolerance)
68  : MatchedIterator(ref.begin(), ref.end(), target.begin(), target.end(), tolerance)
69  {
70  }
71 
83  explicit MatchedIterator(const CONST_CONT_IT ref_begin, const CONST_CONT_IT ref_end,
84  const CONST_CONT_IT tgt_begin, const CONST_CONT_IT tgt_end,
85  float tolerance)
86  : ref_begin_(ref_begin), ref_end_(ref_end), tgt_begin_(tgt_begin), tgt_end_(tgt_end), it_ref_(ref_begin), it_tgt_(tgt_begin), tol_(tolerance), is_end_(false)
87  {
88  if (tgt_begin_ == tgt_end_)
89  { // nothing to iterate over in target (if ref_ were empty, isEnd_() is automatically true)
90  setToEnd_();
91  return;
92  }
94  }
95 
99  explicit MatchedIterator()
100  : ref_begin_(), ref_end_(), tgt_begin_(), tgt_end_(), it_ref_(), it_tgt_(), tol_(), is_end_(false)
101  {
102  }
103 
105  MatchedIterator(const MatchedIterator& rhs) = default;
106 
108  MatchedIterator& operator=(const MatchedIterator& rhs) = default;
109 
110  bool operator==(const MatchedIterator& rhs) const
111  {
112  if (this == &rhs) return true;
113 
114  if (isEnd_() || rhs.isEnd_())
115  {
116  return isEnd_() == rhs.isEnd_();
117  }
118 
119  return (it_ref_ == rhs.it_ref_ &&
120  it_tgt_ == rhs.it_tgt_ &&
121  ref_begin_ == rhs.ref_begin_ &&
122  ref_end_ == rhs.ref_end_ &&
123  tgt_begin_ == rhs.tgt_begin_ &&
124  tgt_end_ == rhs.tgt_end_);
125  }
126  bool operator!=(const MatchedIterator& rhs) const
127  {
128  return !(*this == rhs);
129  }
130 
132  template< bool _CONST = CONST_T >
133  typename std::enable_if< _CONST, reference >::type operator*() const
134  {
135  return *it_tgt_;
136  }
137  template< bool _CONST = CONST_T >
138  typename std::enable_if< !_CONST, reference >::type operator*()
139  {
140  return *it_tgt_;
141  }
142 
144  template< bool _CONST = CONST_T >
145  typename std::enable_if< _CONST, pointer >::type operator->() const
146  {
147  return &(*it_tgt_);
148  }
149  template< bool _CONST = CONST_T >
150  typename std::enable_if< !_CONST, pointer >::type operator->()
151  {
152  return &(*it_tgt_);
153  }
154 
156  const value_type& ref() const
157  {
158  return *it_ref_;
159  }
160 
162  size_t refIdx() const
163  {
164  return it_ref_ - ref_begin_;
165  }
166 
168  size_t tgtIdx() const
169  {
170  return it_tgt_ - tgt_begin_;
171  }
172 
179  {
180  // are we at end already? --> wrong usage
181  OPENMS_PRECONDITION(!isEnd_(), "Tried to advance beyond end iterator!");
182  ++it_ref_;
183  advanceTarget_();
184  return *this;
185  }
186 
189  {
190  MatchedIterator n(*this);
191  ++(*this);
192  return n;
193  }
194 
197  {
198  return MatchedIterator(true);
199  }
200 
201  protected:
202 
205  MatchedIterator(bool /*is_end*/)
206  : ref_begin_(), ref_end_(), tgt_begin_(), tgt_end_(), it_ref_(), it_tgt_(), tol_(), is_end_(true)
207  {
208  }
209 
210  void setToEnd_()
211  {
212  is_end_ = true;
213  }
214 
215  bool isEnd_() const
216  {
217  return is_end_;
218  }
219 
221  {
222  while (it_ref_ != ref_end_)
223  { // note: it_tgt_ always points to a valid element (unless the whole container was empty -- see CTor)
224 
225  double max_dist = TRAIT::allowedTol(tol_, *it_ref_);
226 
227  // forward iterate over elements in target data until distance gets worse
228  float diff = std::numeric_limits<float>::max();
229  do
230  {
231  auto d = TRAIT::getDiffAbsolute(*it_ref_, *it_tgt_);
232  if (diff > d) // getting better
233  {
234  diff = d;
235  }
236  else // getting worse (overshot)
237  {
238  --it_tgt_;
239  break;
240  }
241  ++it_tgt_;
242  } while (it_tgt_ != tgt_end_);
243 
244  if (it_tgt_ == tgt_end_)
245  { // reset to last valid entry
246  --it_tgt_;
247  }
248  if (diff <= max_dist) return; // ok, found match
249 
250  // try next ref peak
251  ++it_ref_;
252  }
253  // reached end of ref container
254  setToEnd_();
255  // i.e. isEnd() is true now
256  }
257 
261  float tol_;
262  bool is_end_ = false;
263  };
264 
266  struct ValueTrait
267  {
268  template <typename T>
269  static float allowedTol(float tol, const T& /*mz_ref*/)
270  {
271  return tol;
272  }
274  template <typename T>
275  static T getDiffAbsolute(const T& elem_ref, const T& elem_tgt)
276  {
277  return fabs(elem_ref - elem_tgt);
278  }
279  };
280 
283  struct PpmTrait
284  {
285  template <typename T>
286  static float allowedTol(float tol, const T& elem_ref)
287  {
288  return Math::ppmToMass(tol, (float)elem_ref.getMZ());
289  }
291  template <typename T>
292  static float getDiffAbsolute(const T& elem_ref, const T& elem_tgt)
293  {
294  return fabs(elem_ref.getMZ() - elem_tgt.getMZ());
295  }
296  };
297 
300  struct DaTrait
301  {
302  template <typename T>
303  static float allowedTol(float tol, const T& /*mz_ref*/)
304  {
305  return tol;
306  }
308  template <typename T>
309  static float getDiffAbsolute(const T& elem_ref, const T& elem_tgt)
310  {
311  return fabs(elem_ref.getMZ() - elem_tgt.getMZ());
312  }
313  };
314 
315 } // namespace OpenMS
For each element in the reference container the closest peak in the target will be searched....
Definition: MatchedIterator.h:46
CONT_IT it_ref_
Definition: MatchedIterator.h:260
bool operator!=(const MatchedIterator &rhs) const
Definition: MatchedIterator.h:126
CONST_CONT_IT ref_end_
Definition: MatchedIterator.h:258
MatchedIterator & operator++()
Advances to the next valid pair.
Definition: MatchedIterator.h:178
MatchedIterator(const MatchedIterator &rhs)=default
Copy CTor (default)
CONST_CONT_IT tgt_end_
Definition: MatchedIterator.h:259
typename std::conditional< CONST_T, typename CONT_T::value_type const &, typename CONT_T::value_type & >::type reference
Definition: MatchedIterator.h:53
CONT_IT it_tgt_
Definition: MatchedIterator.h:260
MatchedIterator(const CONST_CONT_IT ref_begin, const CONST_CONT_IT ref_end, const CONST_CONT_IT tgt_begin, const CONST_CONT_IT tgt_end, float tolerance)
Constructs a MatchedIterator on two containers. The way a match is found, depends on the TRAIT type (...
Definition: MatchedIterator.h:83
MatchedIterator & operator=(const MatchedIterator &rhs)=default
Assignment operator (default)
MatchedIterator(bool)
Definition: MatchedIterator.h:205
size_t refIdx() const
index into reference container
Definition: MatchedIterator.h:162
bool isEnd_() const
Definition: MatchedIterator.h:215
MatchedIterator(const CONT_T &ref, const CONT_T &target, float tolerance)
Constructs a MatchedIterator on two containers. The way a match is found, depends on the TRAIT type (...
Definition: MatchedIterator.h:67
std::forward_iterator_tag iterator_category
Definition: MatchedIterator.h:49
typename CONT_T::const_iterator CONST_CONT_IT
Definition: MatchedIterator.h:56
void advanceTarget_()
Definition: MatchedIterator.h:220
bool operator==(const MatchedIterator &rhs) const
Definition: MatchedIterator.h:110
size_t tgtIdx() const
index into target container
Definition: MatchedIterator.h:168
MatchedIterator operator++(int)
post-increment
Definition: MatchedIterator.h:188
bool is_end_
Definition: MatchedIterator.h:262
typename CONT_T::value_type value_type
Definition: MatchedIterator.h:50
std::enable_if< _CONST, reference >::type operator*() const
dereference current target element
Definition: MatchedIterator.h:133
typename std::conditional< CONST_T, typename CONT_T::value_type const *, typename CONT_T::value_type * >::type pointer
Definition: MatchedIterator.h:52
static MatchedIterator end()
the end iterator
Definition: MatchedIterator.h:196
CONST_CONT_IT tgt_begin_
Definition: MatchedIterator.h:259
const value_type & ref() const
current element in reference container
Definition: MatchedIterator.h:156
std::enable_if< _CONST, pointer >::type operator->() const
pointer to current target element
Definition: MatchedIterator.h:145
std::enable_if< !_CONST, reference >::type operator*()
Definition: MatchedIterator.h:138
std::ptrdiff_t difference_type
Definition: MatchedIterator.h:51
MatchedIterator()
Default CTor; do not use this for anything other than assigning to it;.
Definition: MatchedIterator.h:99
CONST_CONT_IT ref_begin_
Definition: MatchedIterator.h:258
void setToEnd_()
Definition: MatchedIterator.h:210
float tol_
Definition: MatchedIterator.h:261
std::enable_if< !_CONST, pointer >::type operator->()
Definition: MatchedIterator.h:150
typename std::conditional< CONST_T, typename CONT_T::const_iterator, typename CONT_T::iterator >::type CONT_IT
Definition: MatchedIterator.h:55
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition: openms/include/OpenMS/CONCEPT/Macros.h:94
T ppmToMass(T ppm, T mz_ref)
Compute the mass diff in [Th], given a ppm value and a reference point.
Definition: MathFunctions.h:309
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22
Definition: MatchedIterator.h:301
static float getDiffAbsolute(const T &elem_ref, const T &elem_tgt)
for Peak1D & Co
Definition: MatchedIterator.h:309
static float allowedTol(float tol, const T &)
Definition: MatchedIterator.h:303
Definition: MatchedIterator.h:284
static float getDiffAbsolute(const T &elem_ref, const T &elem_tgt)
for Peak1D & Co
Definition: MatchedIterator.h:292
static float allowedTol(float tol, const T &elem_ref)
Definition: MatchedIterator.h:286
Trait for MatchedIterator to find pairs with a certain distance, which is computed directly on the va...
Definition: MatchedIterator.h:267
static T getDiffAbsolute(const T &elem_ref, const T &elem_tgt)
just use fabs on the value directly
Definition: MatchedIterator.h:275
static float allowedTol(float tol, const T &)
Definition: MatchedIterator.h:269