Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
MSSpectrum.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2015.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Stephan Aiche$
32 // $Authors: Marc Sturm $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_KERNEL_MSSPECTRUM_H
36 #define OPENMS_KERNEL_MSSPECTRUM_H
37 
42 
43 namespace OpenMS
44 {
45  class Peak1D;
46 
65  template <typename PeakT = Peak1D>
66  class MSSpectrum :
67  private std::vector<PeakT>,
68  public RangeManager<1>,
69  public SpectrumSettings
70  {
71 public:
72 
75  public MetaInfoDescription,
76  public std::vector<float>
77  {};
78 
81  public MetaInfoDescription,
82  public std::vector<Int>
83  {};
84 
87  public MetaInfoDescription,
88  public std::vector<String>
89  {};
90 
92  struct RTLess :
93  public std::binary_function<MSSpectrum, MSSpectrum, bool>
94  {
95  inline bool operator()(const MSSpectrum& a, const MSSpectrum& b) const
96  {
97  return a.getRT() < b.getRT();
98  }
99 
100  };
101 
103 
104  typedef PeakT PeakType;
109  typedef std::vector<PeakType> ContainerType;
111  typedef std::vector<FloatDataArray> FloatDataArrays;
113  typedef std::vector<StringDataArray> StringDataArrays;
115  typedef std::vector<IntegerDataArray> IntegerDataArrays;
117 
119 
120  typedef typename ContainerType::iterator Iterator;
123  typedef typename ContainerType::const_iterator ConstIterator;
125  typedef typename ContainerType::reverse_iterator ReverseIterator;
127  typedef typename ContainerType::const_reverse_iterator ConstReverseIterator;
129 
131 
132  using ContainerType::operator[];
133  using ContainerType::begin;
134  using ContainerType::rbegin;
135  using ContainerType::end;
136  using ContainerType::rend;
137  using ContainerType::resize;
138  using ContainerType::size;
139  using ContainerType::push_back;
140  using ContainerType::pop_back;
141  using ContainerType::empty;
142  using ContainerType::front;
143  using ContainerType::back;
144  using ContainerType::reserve;
145  using ContainerType::insert;
146  using ContainerType::erase;
147  using ContainerType::swap;
148 
149  using typename ContainerType::iterator;
150  using typename ContainerType::const_iterator;
151  using typename ContainerType::size_type;
152  using typename ContainerType::value_type;
153  using typename ContainerType::reference;
154  using typename ContainerType::const_reference;
155  using typename ContainerType::pointer;
156  using typename ContainerType::difference_type;
158 
159 
162  ContainerType(),
163  RangeManager<1>(),
165  retention_time_(-1),
166  ms_level_(1),
167  name_(),
171  {}
172 
174  MSSpectrum(const MSSpectrum& source) :
175  ContainerType(source),
176  RangeManager<1>(source),
177  SpectrumSettings(source),
179  ms_level_(source.ms_level_),
180  name_(source.name_),
184  {}
185 
188  {}
189 
192  {
193  if (&source == this) return *this;
194 
195  ContainerType::operator=(source);
198 
200  ms_level_ = source.ms_level_;
201  name_ = source.name_;
205 
206  return *this;
207  }
208 
210  bool operator==(const MSSpectrum& rhs) const
211  {
212  //name_ can differ => it is not checked
213 #pragma clang diagnostic push
214 #pragma clang diagnostic ignored "-Wfloat-equal"
215  return std::operator==(*this, rhs) &&
219  ms_level_ == rhs.ms_level_ &&
223 
224 #pragma clang diagnostic pop
225  }
226 
228  bool operator!=(const MSSpectrum& rhs) const
229  {
230  return !(operator==(rhs));
231  }
232 
233  // Docu in base class (RangeManager)
234  virtual void updateRanges()
235  {
236  this->clearRanges();
237  updateRanges_(ContainerType::begin(), ContainerType::end());
238  }
239 
243  inline double getRT() const
244  {
245  return retention_time_;
246  }
247 
249  inline void setRT(double rt)
250  {
251  retention_time_ = rt;
252  }
253 
259  inline UInt getMSLevel() const
260  {
261  return ms_level_;
262  }
263 
265  inline void setMSLevel(UInt ms_level)
266  {
267  ms_level_ = ms_level;
268  }
269 
271  inline const String& getName() const
272  {
273  return name_;
274  }
275 
277  inline void setName(const String& name)
278  {
279  name_ = name;
280  }
281 
283 
297  inline const FloatDataArrays& getFloatDataArrays() const
299  {
300  return float_data_arrays_;
301  }
302 
304  inline FloatDataArrays& getFloatDataArrays()
305  {
306  return float_data_arrays_;
307  }
308 
310  inline const StringDataArrays& getStringDataArrays() const
311  {
312  return string_data_arrays_;
313  }
314 
316  inline StringDataArrays& getStringDataArrays()
317  {
318  return string_data_arrays_;
319  }
320 
322  inline const IntegerDataArrays& getIntegerDataArrays() const
323  {
324  return integer_data_arrays_;
325  }
326 
328  inline IntegerDataArrays& getIntegerDataArrays()
329  {
330  return integer_data_arrays_;
331  }
332 
334 
336 
337 
342  void sortByIntensity(bool reverse = false)
343  {
344  if (float_data_arrays_.empty() && string_data_arrays_.empty() && integer_data_arrays_.empty())
345  {
346  if (reverse)
347  {
348  std::sort(ContainerType::begin(), ContainerType::end(), reverseComparator(typename PeakType::IntensityLess()));
349  }
350  else
351  {
352  std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::IntensityLess());
353  }
354  }
355  else
356  {
357  //sort index list
358  std::vector<std::pair<typename PeakType::IntensityType, Size> > sorted_indices;
359  sorted_indices.reserve(ContainerType::size());
360  for (Size i = 0; i < ContainerType::size(); ++i)
361  {
362  sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getIntensity(), i));
363  }
364 
365  if (reverse)
366  {
367  std::sort(sorted_indices.begin(), sorted_indices.end(), reverseComparator(PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >()));
368  }
369  else
370  {
371  std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >());
372  }
373 
374  //apply sorting to ContainerType and to meta data arrays
375  ContainerType tmp;
376  for (Size i = 0; i < sorted_indices.size(); ++i)
377  {
378  tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
379  }
380  ContainerType::swap(tmp);
381 
382  for (Size i = 0; i < float_data_arrays_.size(); ++i)
383  {
384  std::vector<float> mda_tmp;
385  for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
386  {
387  mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
388  }
389  float_data_arrays_[i].swap(mda_tmp);
390  }
391 
392  for (Size i = 0; i < string_data_arrays_.size(); ++i)
393  {
394  std::vector<String> mda_tmp;
395  for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
396  {
397  mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
398  }
399  string_data_arrays_[i].swap(mda_tmp);
400  }
401 
402  for (Size i = 0; i < integer_data_arrays_.size(); ++i)
403  {
404  std::vector<Int> mda_tmp;
405  for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
406  {
407  mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
408  }
409  integer_data_arrays_[i].swap(mda_tmp);
410  }
411  }
412  }
413 
420  {
421  if (float_data_arrays_.empty())
422  {
423  std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::PositionLess());
424  }
425  else
426  {
427  //sort index list
428  std::vector<std::pair<typename PeakType::PositionType, Size> > sorted_indices;
429  sorted_indices.reserve(ContainerType::size());
430  for (Size i = 0; i < ContainerType::size(); ++i)
431  {
432  sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getPosition(), i));
433  }
434  std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::PositionType, Size> >());
435 
436  //apply sorting to ContainerType and to metadataarrays
437  ContainerType tmp;
438  tmp.reserve(sorted_indices.size());
439  for (Size i = 0; i < sorted_indices.size(); ++i)
440  {
441  tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
442  }
443  ContainerType::swap(tmp);
444 
445  for (Size i = 0; i < float_data_arrays_.size(); ++i)
446  {
447  std::vector<float> mda_tmp;
448  mda_tmp.reserve(float_data_arrays_[i].size());
449  for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
450  {
451  mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
452  }
453  std::swap(float_data_arrays_[i], mda_tmp);
454  }
455 
456  for (Size i = 0; i < string_data_arrays_.size(); ++i)
457  {
458  std::vector<String> mda_tmp;
459  mda_tmp.reserve(string_data_arrays_[i].size());
460  for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
461  {
462  mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
463  }
464  std::swap(string_data_arrays_[i], mda_tmp);
465  }
466 
467  for (Size i = 0; i < integer_data_arrays_.size(); ++i)
468  {
469  std::vector<Int> mda_tmp;
470  mda_tmp.reserve(integer_data_arrays_[i].size());
471  for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
472  {
473  mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
474  }
475  std::swap(integer_data_arrays_[i], mda_tmp);
476  }
477  }
478  }
479 
481  bool isSorted() const
482  {
483  if (this->size() < 2) return true;
484 
485  for (Size i = 1; i < this->size(); ++i)
486  {
487  if (this->operator[](i - 1).getMZ() > this->operator[](i).getMZ()) return false;
488  }
489  return true;
490  }
491 
493 
496 
506  Size findNearest(CoordinateType mz) const
507  {
508  // no peak => no search
509  if (ContainerType::size() == 0) throw Exception::Precondition(__FILE__, __LINE__, __PRETTY_FUNCTION__, "There must be at least one peak to determine the nearest peak!");
510 
511  // search for position for inserting
512  ConstIterator it = MZBegin(mz);
513  // border cases
514  if (it == ContainerType::begin()) return 0;
515 
516  if (it == ContainerType::end()) return ContainerType::size() - 1;
517 
518  // the peak before or the current peak are closest
519  ConstIterator it2 = it;
520  --it2;
521  if (std::fabs(it->getMZ() - mz) < std::fabs(it2->getMZ() - mz))
522  {
523  return Size(it - ContainerType::begin());
524  }
525  else
526  {
527  return Size(it2 - ContainerType::begin());
528  }
529  }
530 
536  Iterator MZBegin(CoordinateType mz)
537  {
538  PeakType p;
539  p.setPosition(mz);
540  return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
541  }
542 
548  Iterator MZBegin(Iterator begin, CoordinateType mz, Iterator end)
549  {
550  PeakType p;
551  p.setPosition(mz);
552  return lower_bound(begin, end, p, typename PeakType::PositionLess());
553  }
554 
560  Iterator MZEnd(CoordinateType mz)
561  {
562  PeakType p;
563  p.setPosition(mz);
564  return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
565  }
566 
572  Iterator MZEnd(Iterator begin, CoordinateType mz, Iterator end)
573  {
574  PeakType p;
575  p.setPosition(mz);
576  return upper_bound(begin, end, p, typename PeakType::PositionLess());
577  }
578 
584  ConstIterator MZBegin(CoordinateType mz) const
585  {
586  PeakType p;
587  p.setPosition(mz);
588  return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
589  }
590 
596  ConstIterator MZBegin(ConstIterator begin, CoordinateType mz, ConstIterator end) const
597  {
598  PeakType p;
599  p.setPosition(mz);
600  return lower_bound(begin, end, p, typename PeakType::PositionLess());
601  }
602 
608  ConstIterator MZEnd(CoordinateType mz) const
609  {
610  PeakType p;
611  p.setPosition(mz);
612  return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
613  }
614 
620  ConstIterator MZEnd(ConstIterator begin, CoordinateType mz, ConstIterator end) const
621  {
622  PeakType p;
623  p.setPosition(mz);
624  return upper_bound(begin, end, p, typename PeakType::PositionLess());
625  }
626 
628 
629 
635  void clear(bool clear_meta_data)
636  {
637  ContainerType::clear();
638 
639  if (clear_meta_data)
640  {
641  clearRanges();
642  this->SpectrumSettings::operator=(SpectrumSettings()); // no "clear" method
643  retention_time_ = -1.0;
644  ms_level_ = 1;
645  name_.clear();
646  float_data_arrays_.clear();
647  string_data_arrays_.clear();
648  integer_data_arrays_.clear();
649  }
650  }
651 
652 protected:
653 
656 
659 
662 
664  FloatDataArrays float_data_arrays_;
665 
667  StringDataArrays string_data_arrays_;
668 
670  IntegerDataArrays integer_data_arrays_;
671  };
672 
674  template <typename PeakT>
675  std::ostream& operator<<(std::ostream& os, const MSSpectrum<PeakT>& spec)
676  {
677  os << "-- MSSPECTRUM BEGIN --" << std::endl;
678 
679  //spectrum settings
680  os << static_cast<const SpectrumSettings&>(spec);
681 
682  //peaklist
683  for (typename MSSpectrum<PeakT>::ConstIterator it = spec.begin(); it != spec.end(); ++it)
684  {
685  os << *it << std::endl;
686  }
687 
688  os << "-- MSSPECTRUM END --" << std::endl;
689  return os;
690  }
691 
692 } // namespace OpenMS
693 
694 #endif // OPENMS_KERNEL_MSSPECTRUM_H
String data array class.
Definition: MSSpectrum.h:86
MSSpectrum & operator=(const MSSpectrum &source)
Assignment operator.
Definition: MSSpectrum.h:191
PeakType::CoordinateType CoordinateType
Coordinate (m/z) type.
Definition: MSSpectrum.h:107
ConstIterator MZEnd(ConstIterator begin, CoordinateType mz, ConstIterator end) const
Binary search for peak range end (returns the past-the-end iterator)
Definition: MSSpectrum.h:620
A more convenient string class.
Definition: String.h:57
IntegerDataArrays integer_data_arrays_
Integer data arrays.
Definition: MSSpectrum.h:670
UInt getMSLevel() const
Returns the MS level.
Definition: MSSpectrum.h:259
void sortByPosition()
Lexicographically sorts the peaks by their position.
Definition: MSSpectrum.h:419
Size findNearest(CoordinateType mz) const
Binary search for the peak nearest to a specific m/z.
Definition: MSSpectrum.h:506
Iterator MZEnd(Iterator begin, CoordinateType mz, Iterator end)
Binary search for peak range end (returns the past-the-end iterator)
Definition: MSSpectrum.h:572
StringDataArrays string_data_arrays_
String data arrays.
Definition: MSSpectrum.h:667
bool isSorted() const
Checks if all peaks are sorted with respect to ascending m/z.
Definition: MSSpectrum.h:481
Comparator for the retention time.
Definition: MSSpectrum.h:92
ContainerType::reverse_iterator ReverseIterator
Mutable reverse iterator.
Definition: MSSpectrum.h:125
Iterator MZBegin(Iterator begin, CoordinateType mz, Iterator end)
Binary search for peak range begin.
Definition: MSSpectrum.h:548
ContainerType::const_iterator ConstIterator
Non-mutable iterator.
Definition: MSSpectrum.h:123
bool operator==(const MSSpectrum &rhs) const
Equality operator.
Definition: MSSpectrum.h:210
ReverseComparator< Cmp > reverseComparator(Cmp const &cmp)
Make-function to create a ReverseComparator from another comparator without the need to specify the t...
Definition: ComparatorUtils.h:261
Iterator MZEnd(CoordinateType mz)
Binary search for peak range end (returns the past-the-end iterator)
Definition: MSSpectrum.h:560
Integer data array class.
Definition: MSSpectrum.h:80
SpectrumSettings()
Constructor.
const String & getName() const
Returns the name.
Definition: MSSpectrum.h:271
Representation of 1D spectrum settings.
Definition: SpectrumSettings.h:64
void setName(const String &name)
Sets the name.
Definition: MSSpectrum.h:277
String name_
Name.
Definition: MSSpectrum.h:661
MSSpectrum(const MSSpectrum &source)
Copy constructor.
Definition: MSSpectrum.h:174
StringDataArrays & getStringDataArrays()
Returns a mutable reference to the string meta data arrays.
Definition: MSSpectrum.h:316
bool operator==(const RangeManager &rhs) const
Equality operator.
Definition: RangeManager.h:88
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
const IntegerDataArrays & getIntegerDataArrays() const
Returns a const reference to the integer meta data arrays.
Definition: MSSpectrum.h:322
ContainerType::iterator Iterator
Mutable iterator.
Definition: MSSpectrum.h:121
Precondition failed exception.
Definition: Exception.h:167
IntegerDataArrays & getIntegerDataArrays()
Returns a mutable reference to the integer meta data arrays.
Definition: MSSpectrum.h:328
Description of the meta data arrays of MSSpectrum.
Definition: MetaInfoDescription.h:49
Comparator by position. As this class has dimension 1, this is basically an alias for MZLess...
Definition: Peak1D.h:241
Iterator MZBegin(CoordinateType mz)
Binary search for peak range begin.
Definition: MSSpectrum.h:536
bool operator!=(const MSSpectrum &rhs) const
Equality operator.
Definition: MSSpectrum.h:228
std::vector< FloatDataArray > FloatDataArrays
Float data array vector type.
Definition: MSSpectrum.h:111
virtual void updateRanges()
Updates minimum and maximum position/intensity.
Definition: MSSpectrum.h:234
FloatDataArrays float_data_arrays_
Float data arrays.
Definition: MSSpectrum.h:664
MSSpectrum()
Constructor.
Definition: MSSpectrum.h:161
The representation of a 1D spectrum.
Definition: MSSpectrum.h:66
SpectrumSettings & operator=(const SpectrumSettings &source)
RangeManager & operator=(const RangeManager &rhs)
Assignment operator.
Definition: RangeManager.h:77
void sortByIntensity(bool reverse=false)
Lexicographically sorts the peaks by their intensity.
Definition: MSSpectrum.h:342
void setPosition(PositionType const &position)
Mutable access to the position.
Definition: Peak1D.h:150
void clearRanges()
Resets the ranges.
Definition: RangeManager.h:140
double getRT() const
Definition: MSSpectrum.h:243
void setMSLevel(UInt ms_level)
Sets the MS level.
Definition: MSSpectrum.h:265
ConstIterator MZBegin(CoordinateType mz) const
Binary search for peak range begin.
Definition: MSSpectrum.h:584
std::vector< StringDataArray > StringDataArrays
String data array vector type.
Definition: MSSpectrum.h:113
ConstIterator MZBegin(ConstIterator begin, CoordinateType mz, ConstIterator end) const
Binary search for peak range begin.
Definition: MSSpectrum.h:596
FloatDataArrays & getFloatDataArrays()
Returns a mutable reference to the float meta data arrays.
Definition: MSSpectrum.h:304
std::vector< PeakType > ContainerType
Spectrum base type.
Definition: MSSpectrum.h:109
Definition: Peak1D.h:189
void clear(bool clear_meta_data)
Clears all data and meta data.
Definition: MSSpectrum.h:635
void setRT(double rt)
Sets the absolute retention time (is seconds)
Definition: MSSpectrum.h:249
PeakT PeakType
Peak type.
Definition: MSSpectrum.h:105
std::vector< IntegerDataArray > IntegerDataArrays
Integer data array vector type.
Definition: MSSpectrum.h:115
Float data array class.
Definition: MSSpectrum.h:74
const StringDataArrays & getStringDataArrays() const
Returns a const reference to the string meta data arrays.
Definition: MSSpectrum.h:310
bool operator()(const MSSpectrum &a, const MSSpectrum &b) const
Definition: MSSpectrum.h:95
double retention_time_
Retention time.
Definition: MSSpectrum.h:655
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:121
UInt ms_level_
MS level.
Definition: MSSpectrum.h:658
ConstIterator MZEnd(CoordinateType mz) const
Binary search for peak range end (returns the past-the-end iterator)
Definition: MSSpectrum.h:608
void updateRanges_(const PeakIteratorType &begin, const PeakIteratorType &end)
Updates the range using data points in the iterator range.
Definition: RangeManager.h:155
Handles the management of a position and intensity range.
Definition: RangeManager.h:48
Class for comparison of std::pair using first ONLY e.g. for use with std::sort.
Definition: ComparatorUtils.h:326
const FloatDataArrays & getFloatDataArrays() const
Returns a const reference to the float meta data arrays.
Definition: MSSpectrum.h:298
bool operator==(const SpectrumSettings &rhs) const
Equality operator.
ContainerType::const_reverse_iterator ConstReverseIterator
Non-mutable reverse iterator.
Definition: MSSpectrum.h:127
~MSSpectrum()
Destructor.
Definition: MSSpectrum.h:187

OpenMS / TOPP release 2.0.0 Documentation generated on Fri May 29 2015 17:20:27 using doxygen 1.8.9.1