OpenMS
MSExperiment.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: Timo Sachsenberg $
6 // $Authors: Marc Sturm, Tom Waschischeck $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
19 
20 #include <vector>
21 
22 
23 namespace OpenMS
24 {
25  class Peak1D;
26  class ChromatogramPeak;
27 
29 
48  class OPENMS_DLLAPI MSExperiment final : public ExperimentalSettings
49  {
50 
51 public:
52  typedef Peak1D PeakT;
54 
56 
57  typedef PeakT PeakType;
67 
70 
78  typedef std::vector<SpectrumType> Base;
80 
82 
83  typedef std::vector<SpectrumType>::iterator Iterator;
86  typedef std::vector<SpectrumType>::const_iterator ConstIterator;
92 
94  // Attention: these refer to the spectra vector only!
96  typedef Base::value_type value_type;
97  typedef Base::iterator iterator;
98  typedef Base::const_iterator const_iterator;
99 
102 
104  MSExperiment(const MSExperiment & source);
105 
108 
111 
114 
117 
119  ~MSExperiment() override;
120 
122  bool operator==(const MSExperiment & rhs) const;
123 
125  bool operator!=(const MSExperiment & rhs) const;
126 
128  Size size() const noexcept;
129 
131  void resize(Size n);
132 
134  bool empty() const noexcept;
135 
137  void reserve(Size n);
138 
140  SpectrumType& operator[](Size n);
141 
143  const SpectrumType& operator[](Size n) const;
144 
145  Iterator begin() noexcept;
146 
147  ConstIterator begin() const noexcept;
148 
149  ConstIterator cbegin() const noexcept;
150 
151  Iterator end();
152 
153  ConstIterator end() const noexcept;
154 
155  ConstIterator cend() const noexcept;
157 
158  // Aliases / chromatograms
159  void reserveSpaceSpectra(Size s);
160  void reserveSpaceChromatograms(Size s);
161 
163 
164 
170  template <class Container>
171  void get2DData(Container& cont) const
172  {
173  for (typename Base::const_iterator spec = spectra_.begin(); spec != spectra_.end(); ++spec)
174  {
175  if (spec->getMSLevel() != 1)
176  {
177  continue;
178  }
179  typename Container::value_type s; // explicit object here, since instantiation within push_back() fails on VS<12
180  for (typename SpectrumType::const_iterator it = spec->begin(); it != spec->end(); ++it)
181  {
182  cont.push_back(s);
183  cont.back().setRT(spec->getRT());
184  cont.back().setMZ(it->getMZ());
185  cont.back().setIntensity(it->getIntensity());
186  }
187  }
188  }
189 
201  template <class Container>
202  void set2DData(const Container& container)
203  {
204  set2DData<false, Container>(container);
205  }
206 
221  template <class Container>
222  void set2DData(const Container& container, const StringList& store_metadata_names)
223  {
224  // clean up the container first
225  clear(true);
226  SpectrumType* spectrum = nullptr;
227  typename PeakType::CoordinateType current_rt = -std::numeric_limits<typename PeakType::CoordinateType>::max();
228  for (typename Container::const_iterator iter = container.begin(); iter != container.end(); ++iter)
229  {
230  // check if the retention time has changed
231  if (current_rt != iter->getRT() || spectrum == nullptr)
232  {
233  // append new spectrum
234  if (current_rt > iter->getRT())
235  {
236  throw Exception::Precondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Input container is not sorted!");
237  }
238  current_rt = iter->getRT();
239  spectrum = createSpec_(current_rt, store_metadata_names);
240  }
241 
242  // add either data point or mass traces (depending on template argument value)
243  ContainerAdd_<typename Container::value_type, false>::addData_(spectrum, &(*iter), store_metadata_names);
244  }
245  }
246 
265  template <bool add_mass_traces, class Container>
266  void set2DData(const Container& container)
267  {
268  // clean up the container first
269  clear(true);
270  SpectrumType* spectrum = nullptr;
271  typename PeakType::CoordinateType current_rt = -std::numeric_limits<typename PeakType::CoordinateType>::max();
272  for (typename Container::const_iterator iter = container.begin(); iter != container.end(); ++iter)
273  {
274  // check if the retention time has changed
275  if (current_rt != iter->getRT() || spectrum == nullptr)
276  {
277  // append new spectrum
278  if (current_rt > iter->getRT())
279  {
280  throw Exception::Precondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Input container is not sorted!");
281  }
282  current_rt = iter->getRT();
283  spectrum = createSpec_(current_rt);
284  }
285 
286  // add either data point or mass traces (depending on template argument value)
288  }
289  }
290 
292 
293 
295 
296  AreaIterator areaBegin(CoordinateType min_rt, CoordinateType max_rt,
298  CoordinateType min_mz, CoordinateType max_mz, UInt ms_level = 1);
299 
301  AreaIterator areaBegin(const RangeManagerType& range, UInt ms_level = 1);
302 
305 
308 
310  ConstAreaIterator areaBeginConst(const RangeManagerType& range, UInt ms_level = 1) const;
311 
314 
315  /* @brief Retrieves the peak data in the given mz-rt range and store data spectrum-wise in separate arrays.
316  *
317  * For fast pyOpenMS access to peak data in format: [rt, [mz, intensity]]
318  *
319  * @param min_rt The minimum retention time.
320  * @param max_rt The maximum retention time.
321  * @param min_mz The minimum m/z value.
322  * @param max_mz The maximum m/z value.
323  * @param ms_level The MS level of the spectra to consider.
324  * @param rt The vector to store the retention times in.
325  * @param mz The vector to store the m/z values in.
326  * @param intensity The vector to store the intensities in.
327  */
329  CoordinateType min_rt,
330  CoordinateType max_rt,
331  CoordinateType min_mz,
332  CoordinateType max_mz,
333  Size ms_level,
334  std::vector<float>& rt,
335  std::vector<std::vector<float>>& mz,
336  std::vector<std::vector<float>>& intensity) const;
337 
338  /* @brief Retrieves the peak data in the given mz-rt range and store data spectrum-wise in separate arrays.
339  *
340  * For fast pyOpenMS access to MS1 peak data in format: [rt, [mz, intensity, ion mobility]]
341  *
342  * @param min_rt The minimum retention time.
343  * @param max_rt The maximum retention time.
344  * @param min_mz The minimum m/z value.
345  * @param max_mz The maximum m/z value.
346  * @param ms_level The MS level of the spectra to consider.
347  * @param rt The vector to store the retention times in.
348  * @param mz The vector to store the m/z values in.
349  * @param intensity The vector to store the intensities in.
350  * @param ion_mobility The vector to store the ion mobility values in.
351  */
353  CoordinateType min_rt,
354  CoordinateType max_rt,
355  CoordinateType min_mz,
356  CoordinateType max_mz,
357  Size ms_level,
358  std::vector<float>& rt,
359  std::vector<std::vector<float>>& mz,
360  std::vector<std::vector<float>>& intensity,
361  std::vector<std::vector<float>>& ion_mobility) const;
362 
363  /* @brief Retrieves the peak data in the given mz-rt range and store in separate arrays.
364  *
365  * For fast pyOpenMS access to MS1 peak data in format: [rt, mz, intensity]
366  *
367  * @param min_rt The minimum retention time.
368  * @param max_rt The maximum retention time.
369  * @param min_mz The minimum m/z value.
370  * @param max_mz The maximum m/z value.
371  * @param ms_level The MS level of the spectra to consider.
372  * @param rt The vector to store the retention times in.
373  * @param mz The vector to store the m/z values in.
374  * @param intensity The vector to store the intensities in.
375  */
377  CoordinateType min_rt,
378  CoordinateType max_rt,
379  CoordinateType min_mz,
380  CoordinateType max_mz,
381  Size ms_level,
382  std::vector<float>& rt,
383  std::vector<float>& mz,
384  std::vector<float>& intensity) const;
385 
386 
387  /* @brief Retrieves the peak data in the given mz-rt range and store in separate arrays.
388  *
389  * For fast pyOpenMS access to MS1 peak data in format: [rt, mz, intensity, ion mobility]
390  *
391  * @param min_rt The minimum retention time.
392  * @param max_rt The maximum retention time.
393  * @param min_mz The minimum m/z value.
394  * @param max_mz The maximum m/z value.
395  * @param ms_level The MS level of the spectra to consider.
396  * @param rt The vector to store the retention times in.
397  * @param mz The vector to store the m/z values in.
398  * @param intensity The vector to store the intensities in.
399  */
401  CoordinateType min_rt,
402  CoordinateType max_rt,
403  CoordinateType min_mz,
404  CoordinateType max_mz,
405  Size ms_level,
406  std::vector<float>& rt,
407  std::vector<float>& mz,
408  std::vector<float>& intensity,
409  std::vector<float>& ion_mobility) const;
410 
422 
423  template <typename Iterator>
424  auto operator()(Iterator begin, Iterator end) const {
425  // Static assert to verify iterator type has intensity accessor
426  using ValueType = typename std::iterator_traits<Iterator>::value_type;
427  using IntensityType = decltype(std::declval<ValueType>().getIntensity());
428  static_assert(std::is_member_function_pointer_v<decltype(&ValueType::getIntensity)>,
429  "Iterator value type must have getIntensity() member function");
430 
431  IntensityType sum{};
432  for (auto it = begin; it != end; ++it) {
433  sum += it->getIntensity();
434  }
435  return sum;
436  }
437 };
438 
487 template<class MzReductionFunctionType>
488 std::vector<std::vector<MSExperiment::CoordinateType>> aggregate(
489  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges,
490  unsigned int ms_level,
491  MzReductionFunctionType func_mz_reduction) const
492 {
493  // Early exit if there are no ranges
494  if (mz_rt_ranges.empty())
495  {
496  // likely an error, but we return an empty vector instead of throwing an exception for now
497  return {};
498  }
499 
500  // Create a view of the spectra with given MS level
501  std::vector<std::reference_wrapper<const MSSpectrum>> spectra_view;
502  spectra_view.reserve(spectra_.size());
503  std::copy_if(spectra_.begin(), spectra_.end(),
504  std::back_inserter(spectra_view),
505  [ms_level](const auto& spec) {
506  return spec.getMSLevel() == ms_level;
507  });
508 
509  // Early exit if there are no spectra with the given MS level
510  if (spectra_view.empty()) { // could be valid use or an error -> we return an empty vector
511  return {};
512  }
513 
514  // Get the indices of the spectra covered by the RT ranges by considering the MS level
515  // If start and stop are the same, the range is empty
516  auto getCoveredSpectra = [](
517  const std::vector<std::reference_wrapper<const MSSpectrum>>& spectra_view,
518  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges)
519  -> std::vector<std::pair<size_t, size_t>>
520  {
521  std::vector<std::pair<size_t, size_t>> res;
522  res.reserve(mz_rt_ranges.size());
523 
524  for (const auto & mz_rt : mz_rt_ranges)
525  {
526  // std::cout << "rt range: " << mz_rt.second.getMin() << " - " << mz_rt.second.getMax() << std::endl;
527  // std::cout << "specs start:" << spectra_view[0].get().getRT() << " specs end:" << spectra_view[spectra_view.size() - 1].get().getRT() << std::endl;
528  auto start_it = std::lower_bound(spectra_view.begin(), spectra_view.end(), mz_rt.second.getMin(),
529  [](const auto& spec, double rt)
530  { return spec.get().getRT() < rt; });
531 
532  auto stop_it = std::upper_bound(spectra_view.begin(), spectra_view.end(), mz_rt.second.getMax(),
533  [](double rt, const auto& spec)
534  { return rt < spec.get().getRT(); });
535 
536  res.emplace_back(
537  std::distance(spectra_view.begin(), start_it),
538  std::distance(spectra_view.begin(), stop_it)
539  );
540  // std::cout << "start: " << std::distance(spectra_view.begin(), start_it) << " stop: " << std::distance(spectra_view.begin(), stop_it) << std::endl;
541  }
542  return res;
543  };
544 
545  // For each range, gets (spectrum start index, spectrum stop index). The spectra covered by each RT range.
546  const std::vector<std::pair<size_t, size_t>> rt_ranges_idcs = getCoveredSpectra(spectra_view, mz_rt_ranges);
547 
548  // Initialize result vector
549  std::vector<std::vector<MSExperiment::CoordinateType>> result(mz_rt_ranges.size());
550 
551  // Initialize counts per spectrum index and total mappings
552  std::vector<std::vector<size_t>> spec_idx_to_range_idx(spectra_view.size());
553 
554  // Build spectrum to range index mapping
555  for (size_t i = 0; i < rt_ranges_idcs.size(); ++i)
556  {
557  const auto& [start, stop] = rt_ranges_idcs[i];
558  result[i].resize(stop - start);
559  // std::cout << "start: " << start << " stop: " << stop << std::endl;
560  for (size_t j = start; j < stop; ++j)
561  {
562  spec_idx_to_range_idx[j].push_back(i);
563  }
564  }
565 
566  #pragma omp parallel for schedule(dynamic)
567  for (Int64 i = 0; i < (Int64)spec_idx_to_range_idx.size(); ++i) // OpenMP on windows still requires signed loop variable
568  {
569  if (spec_idx_to_range_idx[i].empty()) continue; // no ranges for this spectrum? skip it
570 
571  const auto& spec = spectra_view[i].get();
572  auto spec_begin = spec.cbegin();
573  auto spec_end = spec.cend();
574 
575  for (size_t range_idx : spec_idx_to_range_idx[i])
576  {
577  const auto& mz_range = mz_rt_ranges[range_idx].first;
578 
579  // Find data points within MZ range
580  auto start_it = spec.PosBegin(spec_begin, mz_range.getMinMZ(), spec_end);
581  auto end_it = start_it;
582 
583  while (end_it != spec_end && end_it->getPosition() <= mz_range.getMaxMZ())
584  {
585  ++end_it;
586  }
587 
588  // std::cout << "calculating reduction on range: " << range_idx << " for spectrum: " << i << " and peaks " << std::distance(spec.begin(), start_it) << " - " << std::distance(spec.begin(), end_it) << std::endl;
589 
590  // Calculate result using provided reduction function
591  result[range_idx][i - rt_ranges_idcs[range_idx].first] =
592  func_mz_reduction(start_it, end_it);
593  }
594  }
595  return result;
596  }
597 
598 // Overload without func_mz_reduction parameter (default to SumIntensityReduction). Needed because of template deduction issues
599 std::vector<std::vector<MSExperiment::CoordinateType>> aggregate(
600  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges,
601  unsigned int ms_level) const
602 {
603  return aggregate(mz_rt_ranges, ms_level, SumIntensityReduction());
604 }
605 
618 template<class MzReductionFunctionType>
619 std::vector<MSChromatogram> extractXICs(
620  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges,
621  unsigned int ms_level,
622  MzReductionFunctionType func_mz_reduction) const
623 {
624  // Early exit if there are no ranges
625  if (mz_rt_ranges.empty())
626  {
627  // likely an error, but we return an empty vector instead of throwing an exception for now
628  return {};
629  }
630 
631  // Create a view of the spectra with given MS level
632  std::vector<std::reference_wrapper<const MSSpectrum>> spectra_view;
633  spectra_view.reserve(spectra_.size());
634  std::copy_if(spectra_.begin(), spectra_.end(),
635  std::back_inserter(spectra_view),
636  [ms_level](const auto& spec) {
637  return spec.getMSLevel() == ms_level;
638  });
639 
640  // Early exit if there are no spectra with the given MS level
641  if (spectra_view.empty()) { // could be valid use or an error -> we return an empty vector
642  return {};
643  }
644 
645  // Get the indices of the spectra covered by the RT ranges by considering the MS level
646  // If start and stop are the same, the range is empty
647  auto getCoveredSpectra = [](
648  const std::vector<std::reference_wrapper<const MSSpectrum>>& spectra_view,
649  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges)
650  -> std::vector<std::pair<size_t, size_t>>
651  {
652  std::vector<std::pair<size_t, size_t>> res;
653  res.reserve(mz_rt_ranges.size());
654 
655  for (const auto & mz_rt : mz_rt_ranges)
656  {
657  auto start_it = std::lower_bound(spectra_view.begin(), spectra_view.end(), mz_rt.second.getMin(),
658  [](const auto& spec, double rt)
659  { return spec.get().getRT() < rt; });
660 
661  auto stop_it = std::upper_bound(spectra_view.begin(), spectra_view.end(), mz_rt.second.getMax(),
662  [](double rt, const auto& spec)
663  { return rt < spec.get().getRT(); });
664 
665  res.emplace_back(
666  std::distance(spectra_view.begin(), start_it),
667  std::distance(spectra_view.begin(), stop_it)
668  );
669  }
670  return res;
671  };
672 
673  // For each range, gets (spectrum start index, spectrum stop index). The spectra covered by each RT range.
674  const std::vector<std::pair<size_t, size_t>> rt_ranges_idcs = getCoveredSpectra(spectra_view, mz_rt_ranges);
675 
676  // Initialize result vector
677  std::vector<MSChromatogram> result(mz_rt_ranges.size());
678 
679  // Initialize counts per spectrum index and total mappings
680  std::vector<std::vector<size_t>> spec_idx_to_range_idx(spectra_view.size());
681 
682  // Build spectrum to range index mapping
683  for (size_t i = 0; i < rt_ranges_idcs.size(); ++i)
684  {
685  const auto& [start, stop] = rt_ranges_idcs[i];
686  result[i].resize(stop - start);
687  result[i].getProduct().setMZ(
688  (mz_rt_ranges[i].first.getMinMZ() + mz_rt_ranges[i].first.getMaxMZ()) / 2.0);
689  for (size_t j = start; j < stop; ++j)
690  {
691  spec_idx_to_range_idx[j].push_back(i);
692  }
693  }
694 
695  #pragma omp parallel for schedule(dynamic)
696  for (Int64 i = 0; i < (Int64)spec_idx_to_range_idx.size(); ++i) // OpenMP on windows still requires signed loop variable
697  {
698  if (spec_idx_to_range_idx[i].empty()) continue; // no ranges for this spectrum? skip
699 
700  const auto& spec = spectra_view[i].get();
701  const double rt = spec.getRT();
702  auto spec_begin = spec.cbegin();
703  auto spec_end = spec.cend();
704 
705  for (size_t range_idx : spec_idx_to_range_idx[i])
706  {
707  const auto& mz_range = mz_rt_ranges[range_idx].first;
708 
709  // Find data points within MZ range
710  auto start_it = spec.PosBegin(spec_begin, mz_range.getMinMZ(), spec_end);
711  auto end_it = start_it;
712 
713  while (end_it != spec_end && end_it->getPosition() <= mz_range.getMaxMZ())
714  {
715  ++end_it;
716  }
717 
718  // Calculate result using provided reduction function
719  result[range_idx][i - rt_ranges_idcs[range_idx].first] =
720  ChromatogramPeak(rt, func_mz_reduction(start_it, end_it));
721  }
722  }
723 
724  for (auto& r : result) r.updateRanges(); // TODO: prob.. faster to look at first and last peaks as range is sorted
725 
726  return result;
727  }
728 
729 // Overload without func_mz_reduction parameter (needed because of template deduction issue)
730 std::vector<MSChromatogram> extractXICs(
731  const std::vector<std::pair<RangeMZ, RangeRT>>& mz_rt_ranges,
732  unsigned int ms_level) const
733 {
734  return extractXICs(mz_rt_ranges, ms_level, SumIntensityReduction());
735 }
736 
745  std::vector<std::vector<MSExperiment::CoordinateType>> aggregateFromMatrix(
746  const Matrix<double>& ranges,
747  unsigned int ms_level,
748  const std::string& mz_agg) const
749  {
750  // Check matrix dimensions
751  if (ranges.cols() != 4)
752  {
753  throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
754  "Range matrix must have 4 columns [mz_min, mz_max, rt_min, rt_max]");
755  }
756 
757  // Convert matrix rows to vector of pairs
758  std::vector<std::pair<RangeMZ, RangeRT>> mz_rt_ranges;
759  mz_rt_ranges.reserve((Size)ranges.rows());
760 
761  for (Size i = 0; i < (Size)ranges.rows(); ++i)
762  {
763  mz_rt_ranges.emplace_back(
764  RangeMZ(ranges(i, 0), ranges(i, 1)), // min max mz
765  RangeRT(ranges(i, 2), ranges(i, 3)) // min max rt
766  );
767  // std::cout << "mz: " << ranges(i, 0) << " - " << ranges(i, 1) << " rt: " << ranges(i, 2) << " - " << ranges(i, 3) << std::endl;
768  }
769 
770  // Call appropriate aggregation function based on mz_agg parameter
771  if (mz_agg == "sum")
772  {
773  return aggregate(mz_rt_ranges, ms_level,
774  [](auto begin_it, auto end_it)
775  {
776  return std::accumulate(begin_it, end_it, 0.0,
777  [](double a, const Peak1D& b) { return a + b.getIntensity(); });
778  });
779  }
780  else if (mz_agg == "max")
781  {
782  return aggregate(mz_rt_ranges, ms_level,
783  [](auto begin_it, auto end_it)->double
784  {
785  if (begin_it == end_it) return 0.0;
786  return std::max_element(begin_it, end_it,
787  [](const Peak1D& a, const Peak1D& b) { return a.getIntensity() < b.getIntensity(); }
788  )->getIntensity();
789  });
790  }
791  else if (mz_agg == "min")
792  {
793  return aggregate(mz_rt_ranges, ms_level,
794  [](auto begin_it, auto end_it)->double
795  {
796  if (begin_it == end_it) return 0.0;
797  return std::min_element(begin_it, end_it,
798  [](const Peak1D& a, const Peak1D& b) { return a.getIntensity() < b.getIntensity(); }
799  )->getIntensity();
800  });
801  }
802  else if (mz_agg == "mean")
803  {
804  return aggregate(mz_rt_ranges, ms_level,
805  [](auto begin_it, auto end_it)
806  {
807  if (begin_it == end_it) return 0.0;
808  double sum = std::accumulate(begin_it, end_it, 0.0,
809  [](double a, const Peak1D& b) { return a + b.getIntensity(); });
810  return sum / static_cast<double>(std::distance(begin_it, end_it));
811  });
812  }
813  else
814  {
815  throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
816  "Invalid aggregation function", mz_agg);
817  }
818  }
819 
828  std::vector<MSChromatogram> extractXICsFromMatrix(
829  const Matrix<double>& ranges,
830  unsigned int ms_level,
831  const std::string& mz_agg) const
832  {
833  // Check matrix dimensions
834  if (ranges.cols() != 4)
835  {
836  throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
837  "Range matrix must have 4 columns [mz_min, mz_max, rt_min, rt_max]");
838  }
839 
840  // Convert matrix rows to vector of pairs
841  std::vector<std::pair<RangeMZ, RangeRT>> mz_rt_ranges;
842  mz_rt_ranges.reserve((Size)ranges.rows());
843 
844  for (Size i = 0; i < (Size)ranges.rows(); ++i)
845  {
846  mz_rt_ranges.emplace_back(
847  RangeMZ(ranges(i, 0), ranges(i, 1)),
848  RangeRT(ranges(i, 2), ranges(i, 3))
849  );
850  }
851 
852  // Call appropriate extractXICs function based on mz_agg parameter
853  if (mz_agg == "sum")
854  {
855  return extractXICs(mz_rt_ranges, ms_level,
856  [](auto begin_it, auto end_it)
857  {
858  return std::accumulate(begin_it, end_it, 0.0,
859  [](double a, const Peak1D& b) { return a + b.getIntensity(); });
860  });
861  }
862  else if (mz_agg == "max")
863  {
864  return extractXICs(mz_rt_ranges, ms_level,
865  [](auto begin_it, auto end_it)->double
866  {
867  if (begin_it == end_it) return 0.0;
868  return std::max_element(begin_it, end_it,
869  [](const Peak1D& a, const Peak1D& b) { return a.getIntensity() < b.getIntensity(); }
870  )->getIntensity();
871  });
872  }
873  else if (mz_agg == "min")
874  {
875  return extractXICs(mz_rt_ranges, ms_level,
876  [](auto begin_it, auto end_it)->double
877  {
878  if (begin_it == end_it) return 0.0;
879  return std::min_element(begin_it, end_it,
880  [](const Peak1D& a, const Peak1D& b) { return a.getIntensity() < b.getIntensity(); }
881  )->getIntensity();
882  });
883  }
884  else if (mz_agg == "mean")
885  {
886  return extractXICs(mz_rt_ranges, ms_level,
887  [](auto begin_it, auto end_it)
888  {
889  if (begin_it == end_it) return 0.0;
890  double sum = std::accumulate(begin_it, end_it, 0.0,
891  [](double a, const Peak1D& b) { return a + b.getIntensity(); });
892  return sum / static_cast<double>(std::distance(begin_it, end_it));
893  });
894  }
895  else
896  {
897  throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
898  "Invalid aggregation function", mz_agg);
899  }
900  }
901 
910 
919 
926 
933 
934 
943 
953 
961 
968  void clearRanges()
969  {
970  combined_ranges_.clearRanges();
971  spectrum_ranges_.clearRanges();
972  chromatogram_ranges_.clearRanges();
973  }
974 
976  double getMinRT() const { return combined_ranges_.getMinRT(); }
977 
979  double getMaxRT() const { return combined_ranges_.getMaxRT(); }
980 
982  double getMinMZ() const { return combined_ranges_.getMinMZ(); }
983 
985  double getMaxMZ() const { return combined_ranges_.getMaxMZ(); }
986 
988  double getMinIntensity() const { return combined_ranges_.getMinIntensity(); }
989 
991  double getMaxIntensity() const { return combined_ranges_.getMaxIntensity(); }
992 
994  double getMinMobility() const { return combined_ranges_.getMinMobility(); }
995 
997  double getMaxMobility() const { return combined_ranges_.getMaxMobility(); }
998 
1010 
1012  UInt64 getSize() const;
1013 
1015  std::vector<UInt> getMSLevels() const;
1016 
1018 
1022 
1025 
1028 
1033  void sortSpectra(bool sort_mz = true);
1034 
1040  void sortChromatograms(bool sort_rt = true);
1041 
1047  bool isSorted(bool check_mz = true) const;
1048 
1050 
1052  void reset();
1053 
1060 
1063 
1066 
1068  void getPrimaryMSRunPath(StringList& toFill) const;
1069 
1086 
1092  int getPrecursorSpectrum(int zero_based_index) const;
1093 
1121 
1129  int getFirstProductSpectrum(int zero_based_index) const;
1130 
1132  void swap(MSExperiment& from);
1133 
1135  void setSpectra(const std::vector<MSSpectrum>& spectra);
1136  void setSpectra(std::vector<MSSpectrum>&& spectra);
1137 
1139  void addSpectrum(const MSSpectrum& spectrum);
1140  void addSpectrum(MSSpectrum&& spectrum);
1141 
1143  const std::vector<MSSpectrum>& getSpectra() const;
1144 
1146  std::vector<MSSpectrum>& getSpectra();
1147 
1149  ConstIterator getClosestSpectrumInRT(const double RT) const;
1151 
1153  ConstIterator getClosestSpectrumInRT(const double RT, UInt ms_level) const;
1154  Iterator getClosestSpectrumInRT(const double RT, UInt ms_level);
1155 
1157  void setChromatograms(const std::vector<MSChromatogram>& chromatograms);
1158  void setChromatograms(std::vector<MSChromatogram>&& chromatograms);
1159 
1161  void addChromatogram(const MSChromatogram& chromatogram);
1163 
1165  const std::vector<MSChromatogram>& getChromatograms() const;
1166 
1168  std::vector<MSChromatogram>& getChromatograms();
1169 
1171 
1172  MSChromatogram& getChromatogram(Size id);
1174 
1177 
1180 
1184 
1195  const MSChromatogram calculateTIC(float rt_bin_size = 0, UInt ms_level = 1) const;
1196 
1202  void clear(bool clear_meta_data);
1203 
1205  bool containsScanOfLevel(size_t ms_level) const;
1206 
1208  bool hasZeroIntensities(size_t ms_level) const;
1209 
1211  bool isIMFrame() const;
1212 
1213  protected:
1215  std::vector<MSChromatogram > chromatograms_;
1217  std::vector<SpectrumType> spectra_;
1220 
1223 
1226 
1227  public:
1237  const SpectrumRangeManagerType& spectrumRanges() const { return spectrum_ranges_; }
1238 
1248  const ChromatogramRangeManagerType& chromatogramRanges() const { return chromatogram_ranges_; }
1249 
1258  const RangeManagerType& combinedRanges() const { return combined_ranges_; }
1259 
1260  private:
1261 
1263  template<typename ContainerValueType, bool addMassTraces>
1265  {
1266  static void addData_(SpectrumType* spectrum, const ContainerValueType* item);
1267  static void addData_(SpectrumType* spectrum, const ContainerValueType* item, const StringList& store_metadata_names);
1268  };
1269 
1270  template<typename ContainerValueType>
1271  struct ContainerAdd_<ContainerValueType, false>
1272  {
1274  static void addData_(SpectrumType* spectrum, const ContainerValueType* item)
1275  {
1276  // create temporary peak and insert it into spectrum
1277  spectrum->insert(spectrum->end(), PeakType());
1278  spectrum->back().setIntensity(item->getIntensity());
1279  spectrum->back().setPosition(item->getMZ());
1280  }
1282  static void addData_(SpectrumType* spectrum, const ContainerValueType* item, const StringList& store_metadata_names)
1283  {
1284  addData_(spectrum, item);
1285  for (StringList::const_iterator itm = store_metadata_names.begin(); itm != store_metadata_names.end(); ++itm)
1286  {
1287  float val = std::numeric_limits<float>::quiet_NaN();
1288  if (item->metaValueExists(*itm)) val = item->getMetaValue(*itm);
1289  spectrum->getFloatDataArrays()[itm - store_metadata_names.begin()].push_back(val);
1290  }
1291  }
1292  };
1293 
1294  template<typename ContainerValueType>
1295  struct ContainerAdd_<ContainerValueType, true>
1296  {
1298  static void addData_(SpectrumType* spectrum, const ContainerValueType* item)
1299  {
1300  if (item->metaValueExists("num_of_masstraces"))
1301  {
1302  Size mts = item->getMetaValue("num_of_masstraces");
1303  int charge = (item->getCharge()==0 ? 1 : item->getCharge()); // set to 1 if charge is 0, otherwise div/0 below
1304  for (Size i = 0; i < mts; ++i)
1305  {
1306  String meta_name = String("masstrace_intensity_") + i;
1307  if (!item->metaValueExists(meta_name))
1308  {
1309  throw Exception::Precondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, String("Meta value '") + meta_name + "' expected but not found in container.");
1310  }
1311  ContainerValueType p;
1312  p.setIntensity(item->getMetaValue(meta_name));
1313  p.setPosition(item->getMZ() + Constants::C13C12_MASSDIFF_U / charge * i);
1315  }
1316  }
1318  }
1319  };
1320 
1321 
1322  /*
1323  @brief Append a spectrum to current MSExperiment
1324 
1325  @param rt RT of new spectrum
1326  @return Pointer to newly created spectrum
1327  */
1329 
1330  /*
1331  @brief Append a spectrum including floatdata arrays to current MSExperiment
1332 
1333  @param rt RT of new spectrum
1334  @param metadata_names Names of floatdata arrays attached to this spectrum
1335  @return Pointer to newly created spectrum
1336  */
1338 
1339  };
1340 
1342  OPENMS_DLLAPI std::ostream& operator<<(std::ostream& os, const MSExperiment& exp);
1343 
1344 } // namespace OpenMS
1345 
1347 
1348 
A 1-dimensional raw data point or peak for chromatograms.
Definition: ChromatogramPeak.h:28
Range manager for chromatograms.
Definition: ChromatogramRangeManager.h:31
Exception indicating that an invalid parameter was handed over to an algorithm.
Definition: Exception.h:316
Invalid value exception.
Definition: Exception.h:305
Precondition failed exception.
Definition: Exception.h:128
Description of the experimental settings.
Definition: ExperimentalSettings.h:36
Forward iterator for an area of peaks in an experiment.
Definition: AreaIterator.h:36
The representation of a chromatogram.
Definition: MSChromatogram.h:30
In-Memory representation of a mass spectrometry run.
Definition: MSExperiment.h:49
const ExperimentalSettings & getExperimentalSettings() const
returns the meta information of this experiment (const access)
MSExperiment(MSExperiment &&)=default
Move constructor.
ConstIterator IMBegin(CoordinateType im) const
Fast search for spectrum range begin.
RangeManagerType combined_ranges_
Combined range manager that provides overall ranges across both spectra and chromatograms (maintained...
Definition: MSExperiment.h:1225
ConstIterator getClosestSpectrumInRT(const double RT, UInt ms_level) const
Returns the closest(=nearest) spectrum in retention time to the given RT of a certain MS level.
std::vector< SpectrumType > spectra_
spectra
Definition: MSExperiment.h:1217
const std::vector< MSChromatogram > & getChromatograms() const
returns the chromatogram list
std::vector< SpectrumType > Base
STL base class type.
Definition: MSExperiment.h:78
void setChromatograms(std::vector< MSChromatogram > &&chromatograms)
Base::iterator iterator
Definition: MSExperiment.h:97
bool containsScanOfLevel(size_t ms_level) const
returns true if at least one of the spectra has the specified level
ConstAreaIterator areaBeginConst(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz, UInt ms_level=1) const
Returns a non-mutable area iterator for area.
double getMaxRT() const
Get the maximum RT value from the combined ranges (includes both chromatogram and spectra ranges)
Definition: MSExperiment.h:979
~MSExperiment() override
D'tor.
PeakType::CoordinateType CoordinateType
Coordinate type of peak positions.
Definition: MSExperiment.h:62
void swap(MSExperiment &from)
Swaps the content of this map with the content of from.
MSChromatogram ChromatogramType
Chromatogram type.
Definition: MSExperiment.h:76
void addSpectrum(const MSSpectrum &spectrum)
adds a spectrum to the list
PeakType::IntensityType IntensityType
Intensity type of peaks.
Definition: MSExperiment.h:64
void set2DData(const Container &container, const StringList &store_metadata_names)
Assignment of a data container with RT and MZ to an MSExperiment.
Definition: MSExperiment.h:222
std::vector< SpectrumType >::iterator Iterator
Mutable iterator.
Definition: MSExperiment.h:84
bool clearMetaDataArrays()
Clears the meta data arrays of all contained spectra (float, integer and string arrays)
SpectrumType * createSpec_(PeakType::CoordinateType rt)
ConstAreaIterator areaBeginConst(const RangeManagerType &range, UInt ms_level=1) const
Returns a non-mutable area iterator for all peaks in range. If a dimension is empty(),...
ConstIterator RTBegin(CoordinateType rt) const
Fast search for spectrum range begin.
Size getNrSpectra() const
get the total number of spectra available
std::vector< MSChromatogram > extractXICs(const std::vector< std::pair< RangeMZ, RangeRT >> &mz_rt_ranges, unsigned int ms_level, MzReductionFunctionType func_mz_reduction) const
Extracts extracted ion chromatograms (XICs) from the MSExperiment.
Definition: MSExperiment.h:619
UInt64 getSize() const
returns the total number of peaks (spectra and chromatograms included)
std::vector< MSChromatogram > extractXICs(const std::vector< std::pair< RangeMZ, RangeRT >> &mz_rt_ranges, unsigned int ms_level) const
Definition: MSExperiment.h:730
double getMaxMZ() const
Get the maximum m/z value from the combined ranges (includes both chromatogram and spectra ranges)
Definition: MSExperiment.h:985
MSExperiment & operator=(MSExperiment &&) &=default
Move assignment operator.
ConstIterator RTEnd(CoordinateType rt) const
Fast search for spectrum range end (returns the past-the-end iterator)
void addChromatogram(MSChromatogram &&chrom)
ExperimentalSettings & getExperimentalSettings()
returns the meta information of this experiment (mutable access)
Iterator getClosestSpectrumInRT(const double RT, UInt ms_level)
double getMinMobility() const
Get the minimum mobility value from the combined ranges (includes both chromatogram and spectra range...
Definition: MSExperiment.h:994
SpectrumRangeManager SpectrumRangeManagerType
Spectrum range manager type for tracking ranges with MS level separation.
Definition: MSExperiment.h:69
double getMinIntensity() const
Get the minimum intensity value from the combined ranges (includes both chromatogram and spectra rang...
Definition: MSExperiment.h:988
SpectrumType * createSpec_(PeakType::CoordinateType rt, const StringList &metadata_names)
ChromatogramPeakT ChromatogramPeakType
Chromatogram peak type.
Definition: MSExperiment.h:60
MSSpectrum & getSpectrum(Size id)
returns a single spectrum
AreaIterator areaBegin(const RangeManagerType &range, UInt ms_level=1)
Returns an area iterator for all peaks in range. If a dimension is empty(), it is ignored (i....
Iterator RTEnd(CoordinateType rt)
Fast search for spectrum range end (returns the past-the-end iterator)
MSExperiment & operator=(const MSExperiment &source)
Assignment operator.
MSSpectrum SpectrumType
Spectrum Type.
Definition: MSExperiment.h:74
double getMinMZ() const
Get the minimum m/z value from the combined ranges (includes both chromatogram and spectra ranges)
Definition: MSExperiment.h:982
Size getNrChromatograms() const
get the total number of chromatograms available
Iterator getClosestSpectrumInRT(const double RT)
Base::value_type value_type
Definition: MSExperiment.h:96
Size size() const noexcept
The number of spectra.
MSExperiment()
Constructor.
bool operator!=(const MSExperiment &rhs) const
Equality operator.
Peak1D PeakT
Definition: MSExperiment.h:52
ConstAreaIterator areaEndConst() const
Returns a non-mutable invalid area iterator marking the end of an area.
const RangeManagerType & combinedRanges() const
Returns a const reference to the combined range manager.
Definition: MSExperiment.h:1258
void get2DPeakDataIMPerSpectrum(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz, Size ms_level, std::vector< float > &rt, std::vector< std::vector< float >> &mz, std::vector< std::vector< float >> &intensity, std::vector< std::vector< float >> &ion_mobility) const
void set2DData(const Container &container)
Assignment of a data container with RT and MZ to an MSExperiment.
Definition: MSExperiment.h:202
void setSpectra(std::vector< MSSpectrum > &&spectra)
void getPrimaryMSRunPath(StringList &toFill) const
get the file path to the first MS run
double getMaxMobility() const
Get the maximum mobility value from the combined ranges (includes both chromatogram and spectra range...
Definition: MSExperiment.h:997
void get2DPeakData(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz, Size ms_level, std::vector< float > &rt, std::vector< float > &mz, std::vector< float > &intensity) const
std::vector< MSChromatogram > & getChromatograms()
returns the chromatogram list (mutable)
void setSpectra(const std::vector< MSSpectrum > &spectra)
sets the spectrum list
void get2DPeakDataIM(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz, Size ms_level, std::vector< float > &rt, std::vector< float > &mz, std::vector< float > &intensity, std::vector< float > &ion_mobility) const
void sortChromatograms(bool sort_rt=true)
Sorts the data points of the chromatograms by m/z.
double getMaxIntensity() const
Get the maximum intensity value from the combined ranges (includes both chromatogram and spectra rang...
Definition: MSExperiment.h:991
int getFirstProductSpectrum(int zero_based_index) const
Returns the index of the first product spectrum given an index.
Iterator RTBegin(CoordinateType rt)
Fast search for spectrum range begin.
void clearRanges()
Clear all ranges in all range managers.
Definition: MSExperiment.h:968
std::vector< std::vector< MSExperiment::CoordinateType > > aggregateFromMatrix(const Matrix< double > &ranges, unsigned int ms_level, const std::string &mz_agg) const
Wrapper for aggregate function that takes a matrix of m/z and RT ranges.
Definition: MSExperiment.h:745
Internal::AreaIterator< const PeakT, const PeakT &, const PeakT *, ConstIterator, SpectrumType::ConstIterator > ConstAreaIterator
Immutable area iterator type (for traversal of a rectangular subset of the peaks)
Definition: MSExperiment.h:90
void setChromatograms(const std::vector< MSChromatogram > &chromatograms)
sets the chromatogram list
Internal::AreaIterator< PeakT, PeakT &, PeakT *, Iterator, SpectrumType::Iterator > AreaIterator
Mutable area iterator type (for traversal of a rectangular subset of the peaks)
Definition: MSExperiment.h:88
double getMinRT() const
Get the minimum RT value from the combined ranges (includes both chromatogram and spectra ranges)
Definition: MSExperiment.h:976
const MSChromatogram calculateTIC(float rt_bin_size=0, UInt ms_level=1) const
Computes the total ion chromatogram (TIC) for a given MS level (use ms_level = 0 for all levels).
const std::vector< MSSpectrum > & getSpectra() const
returns the spectrum list
std::vector< MSChromatogram > extractXICsFromMatrix(const Matrix< double > &ranges, unsigned int ms_level, const std::string &mz_agg) const
Wrapper for extractXICs function that takes a matrix of m/z and RT ranges.
Definition: MSExperiment.h:828
std::vector< std::vector< MSExperiment::CoordinateType > > aggregate(const std::vector< std::pair< RangeMZ, RangeRT >> &mz_rt_ranges, unsigned int ms_level) const
Definition: MSExperiment.h:599
bool isSorted(bool check_mz=true) const
Checks if all spectra are sorted with respect to ascending RT.
MSExperiment(const MSExperiment &source)
Copy constructor.
RangeManager< RangeRT, RangeMZ, RangeIntensity, RangeMobility > RangeManagerType
Combined RangeManager type to store the overall range of all spectra and chromatograms (for backward ...
Definition: MSExperiment.h:66
std::vector< MSSpectrum > & getSpectra()
returns the spectrum list (mutable)
ConstIterator getClosestSpectrumInRT(const double RT) const
Returns the closest(=nearest) spectrum in retention time to the given RT.
ChromatogramRangeManager ChromatogramRangeManagerType
Chromatogram range manager type for tracking chromatogram-specific ranges.
Definition: MSExperiment.h:72
void set2DData(const Container &container)
Assignment of a data container with RT and MZ to an MSExperiment.
Definition: MSExperiment.h:266
ChromatogramPeak ChromatogramPeakT
Definition: MSExperiment.h:53
void sortSpectra(bool sort_mz=true)
Sorts the data points by retention time.
std::vector< UInt > getMSLevels() const
returns a sorted array of MS levels (calculated on demand)
void reset()
Clear all internal data (spectra, ranges, metadata)
const ChromatogramRangeManagerType & chromatogramRanges() const
Returns a const reference to the chromatogram range manager.
Definition: MSExperiment.h:1248
void addSpectrum(MSSpectrum &&spectrum)
void updateRanges()
Updates the m/z, intensity, mobility, and retention time ranges of all spectra and chromatograms.
bool hasZeroIntensities(size_t ms_level) const
returns true if any MS spectra of trthe specified level contain at least one peak with intensity of 0...
bool operator==(const MSExperiment &rhs) const
Equality operator.
ConstIterator IMEnd(CoordinateType im) const
Fast search for spectrum range end (returns the past-the-end iterator)
SpectrumRangeManagerType spectrum_ranges_
Spectrum range manager for tracking m/z, intensity, RT, and ion mobility ranges of spectra with MS le...
Definition: MSExperiment.h:1219
void get2DPeakDataPerSpectrum(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz, Size ms_level, std::vector< float > &rt, std::vector< std::vector< float >> &mz, std::vector< std::vector< float >> &intensity) const
ConstIterator getPrecursorSpectrum(ConstIterator iterator) const
Returns the precursor spectrum of the scan pointed to by iterator.
Base::const_iterator const_iterator
Definition: MSExperiment.h:98
std::vector< std::vector< MSExperiment::CoordinateType > > aggregate(const std::vector< std::pair< RangeMZ, RangeRT >> &mz_rt_ranges, unsigned int ms_level, MzReductionFunctionType func_mz_reduction) const
Aggregates data over specified m/z and RT ranges at a given MS level using a custom reduction functio...
Definition: MSExperiment.h:488
void setSqlRunID(UInt64 id)
sets the run-ID which is used when storing an sqMass file
MSExperiment & operator=(const ExperimentalSettings &source)
Assignment operator.
UInt64 getSqlRunID() const
void addChromatogram(const MSChromatogram &chromatogram)
adds a chromatogram to the list
std::vector< SpectrumType >::const_iterator ConstIterator
Non-mutable iterator.
Definition: MSExperiment.h:86
void clear(bool clear_meta_data)
Clears all data and meta data.
ConstIterator getFirstProductSpectrum(ConstIterator iterator) const
const SpectrumRangeManagerType & spectrumRanges() const
Returns a const reference to the spectrum range manager.
Definition: MSExperiment.h:1237
int getPrecursorSpectrum(int zero_based_index) const
Returns the index of the precursor spectrum for spectrum at index zero_based_index.
std::vector< MSChromatogram > chromatograms_
chromatograms
Definition: MSExperiment.h:1215
ChromatogramRangeManagerType chromatogram_ranges_
Chromatogram range manager for tracking RT, intensity, and m/z ranges of chromatograms.
Definition: MSExperiment.h:1222
AreaIterator areaEnd()
Returns an invalid area iterator marking the end of an area.
bool isIMFrame() const
Are all MSSpectra in this experiment part of an IM Frame? I.e. they all have the same RT,...
The representation of a 1D spectrum.
Definition: MSSpectrum.h:44
const FloatDataArrays & getFloatDataArrays() const
Returns a const reference to the float meta data arrays.
void setRT(double rt)
Sets the absolute retention time (in seconds)
A 1-dimensional raw data point or peak.
Definition: Peak1D.h:28
double CoordinateType
Coordinate type.
Definition: Peak1D.h:40
IntensityType getIntensity() const
Definition: Peak1D.h:82
float IntensityType
Intensity type.
Definition: Peak1D.h:36
Advanced range manager for MS spectra with separate ranges for each MS level.
Definition: SpectrumRangeManager.h:44
A more convenient string class.
Definition: String.h:34
int64_t Int64
Signed integer type (64bit)
Definition: Types.h:40
uint64_t UInt64
Unsigned integer type (64bit)
Definition: Types.h:47
unsigned int UInt
Unsigned integer type.
Definition: Types.h:64
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:97
std::vector< String > StringList
Vector of String.
Definition: ListUtils.h:44
static double sum(IteratorType begin, IteratorType end)
Calculates the sum of a range of values.
Definition: StatisticFunctions.h:103
const double C13C12_MASSDIFF_U
Definition: Constants.h:95
Main OpenMS namespace.
Definition: openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
Peak2D PeakType
Definition: MassTrace.h:21
std::ostream & operator<<(std::ostream &os, const AccurateMassSearchResult &amsr)
static void addData_(SpectrumType *spectrum, const ContainerValueType *item)
general method for adding data points
Definition: MSExperiment.h:1274
static void addData_(SpectrumType *spectrum, const ContainerValueType *item, const StringList &store_metadata_names)
general method for adding data points, including metadata arrays (populated from metainfointerface)
Definition: MSExperiment.h:1282
static void addData_(SpectrumType *spectrum, const ContainerValueType *item)
specialization for adding feature mass traces (does not support metadata_names currently)
Definition: MSExperiment.h:1298
Helper class to add either general data points in set2DData or use mass traces from meta values.
Definition: MSExperiment.h:1265
static void addData_(SpectrumType *spectrum, const ContainerValueType *item)
static void addData_(SpectrumType *spectrum, const ContainerValueType *item, const StringList &store_metadata_names)
Calculates the sum of intensities for a range of elements.
Definition: MSExperiment.h:421
auto operator()(Iterator begin, Iterator end) const
Definition: MSExperiment.h:424
Definition: RangeManager.h:358
Definition: RangeManager.h:295