00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_KERNEL_MSSPECTRUM_H
00036 #define OPENMS_KERNEL_MSSPECTRUM_H
00037
00038 #include <OpenMS/METADATA/SpectrumSettings.h>
00039 #include <OpenMS/METADATA/MetaInfoDescription.h>
00040 #include <OpenMS/FORMAT/DB/PersistentObject.h>
00041 #include <OpenMS/KERNEL/RangeManager.h>
00042 #include <OpenMS/KERNEL/ComparatorUtils.h>
00043
00044 namespace OpenMS
00045 {
00046 class Peak1D;
00047
00066 template <typename PeakT = Peak1D>
00067 class MSSpectrum :
00068 public std::vector<PeakT>,
00069 public RangeManager<1>,
00070 public SpectrumSettings,
00071 public PersistentObject
00072 {
00073 public:
00074
00076 class OPENMS_DLLAPI FloatDataArray :
00077 public MetaInfoDescription,
00078 public std::vector<Real>
00079 {};
00080
00082 class OPENMS_DLLAPI IntegerDataArray :
00083 public MetaInfoDescription,
00084 public std::vector<Int>
00085 {};
00086
00088 class OPENMS_DLLAPI StringDataArray :
00089 public MetaInfoDescription,
00090 public std::vector<String>
00091 {};
00092
00094 struct RTLess :
00095 public std::binary_function<MSSpectrum, MSSpectrum, bool>
00096 {
00097 inline bool operator()(const MSSpectrum & a, const MSSpectrum & b) const
00098 {
00099 return a.getRT() < b.getRT();
00100 }
00101
00102 };
00103
00105
00106
00107 typedef PeakT PeakType;
00109 typedef typename PeakType::CoordinateType CoordinateType;
00111 typedef std::vector<PeakType> ContainerType;
00113 typedef std::vector<FloatDataArray> FloatDataArrays;
00115 typedef std::vector<StringDataArray> StringDataArrays;
00117 typedef std::vector<IntegerDataArray> IntegerDataArrays;
00119
00121
00122
00123 typedef typename ContainerType::iterator Iterator;
00125 typedef typename ContainerType::const_iterator ConstIterator;
00127 typedef typename ContainerType::reverse_iterator ReverseIterator;
00129 typedef typename ContainerType::const_reverse_iterator ConstReverseIterator;
00131
00132
00134 MSSpectrum() :
00135 ContainerType(),
00136 RangeManager<1>(),
00137 SpectrumSettings(),
00138 PersistentObject(),
00139 retention_time_(-1),
00140 ms_level_(1),
00141 name_(),
00142 float_data_arrays_(),
00143 string_data_arrays_(),
00144 integer_data_arrays_()
00145 {}
00146
00148 MSSpectrum(const MSSpectrum & source) :
00149 ContainerType(source),
00150 RangeManager<1>(source),
00151 SpectrumSettings(source),
00152 PersistentObject(source),
00153 retention_time_(source.retention_time_),
00154 ms_level_(source.ms_level_),
00155 name_(source.name_),
00156 float_data_arrays_(source.float_data_arrays_),
00157 string_data_arrays_(source.string_data_arrays_),
00158 integer_data_arrays_(source.integer_data_arrays_)
00159 {}
00160
00162 ~MSSpectrum()
00163 {}
00164
00166 MSSpectrum & operator=(const MSSpectrum & source)
00167 {
00168 if (&source == this) return *this;
00169
00170 ContainerType::operator=(source);
00171 RangeManager<1>::operator=(source);
00172 SpectrumSettings::operator=(source);
00173 PersistentObject::operator=(source);
00174
00175 retention_time_ = source.retention_time_;
00176 ms_level_ = source.ms_level_;
00177 name_ = source.name_;
00178 float_data_arrays_ = source.float_data_arrays_;
00179 string_data_arrays_ = source.string_data_arrays_;
00180 integer_data_arrays_ = source.integer_data_arrays_;
00181
00182 return *this;
00183 }
00184
00186 bool operator==(const MSSpectrum & rhs) const
00187 {
00188
00189 return std::operator==(*this, rhs) &&
00190 RangeManager<1>::operator==(rhs) &&
00191 SpectrumSettings::operator==(rhs) &&
00192 retention_time_ == rhs.retention_time_ &&
00193 ms_level_ == rhs.ms_level_ &&
00194 float_data_arrays_ == rhs.float_data_arrays_ &&
00195 string_data_arrays_ == rhs.string_data_arrays_ &&
00196 integer_data_arrays_ == rhs.integer_data_arrays_;
00197 }
00198
00200 bool operator!=(const MSSpectrum & rhs) const
00201 {
00202 return !(operator==(rhs));
00203 }
00204
00205
00206 virtual void updateRanges()
00207 {
00208 this->clearRanges();
00209 updateRanges_(ContainerType::begin(), ContainerType::end());
00210 }
00211
00215 inline DoubleReal getRT() const
00216 {
00217 return retention_time_;
00218 }
00219
00221 inline void setRT(DoubleReal rt)
00222 {
00223 retention_time_ = rt;
00224 }
00225
00231 inline UInt getMSLevel() const
00232 {
00233 return ms_level_;
00234 }
00235
00237 inline void setMSLevel(UInt ms_level)
00238 {
00239 ms_level_ = ms_level;
00240 }
00241
00243 inline const String & getName() const
00244 {
00245 return name_;
00246 }
00247
00249 inline void setName(const String & name)
00250 {
00251 name_ = name;
00252 }
00253
00255
00269
00270 inline const FloatDataArrays & getFloatDataArrays() const
00271 {
00272 return float_data_arrays_;
00273 }
00274
00276 inline FloatDataArrays & getFloatDataArrays()
00277 {
00278 return float_data_arrays_;
00279 }
00280
00282 inline const StringDataArrays & getStringDataArrays() const
00283 {
00284 return string_data_arrays_;
00285 }
00286
00288 inline StringDataArrays & getStringDataArrays()
00289 {
00290 return string_data_arrays_;
00291 }
00292
00294 inline const IntegerDataArrays & getIntegerDataArrays() const
00295 {
00296 return integer_data_arrays_;
00297 }
00298
00300 inline IntegerDataArrays & getIntegerDataArrays()
00301 {
00302 return integer_data_arrays_;
00303 }
00304
00306
00308
00309
00314 void sortByIntensity(bool reverse = false)
00315 {
00316 if (float_data_arrays_.empty() && string_data_arrays_.empty() && integer_data_arrays_.empty())
00317 {
00318 if (reverse)
00319 {
00320 std::sort(ContainerType::begin(), ContainerType::end(), reverseComparator(typename PeakType::IntensityLess()));
00321 }
00322 else
00323 {
00324 std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::IntensityLess());
00325 }
00326 }
00327 else
00328 {
00329
00330 std::vector<std::pair<typename PeakType::IntensityType, Size> > sorted_indices;
00331 sorted_indices.reserve(ContainerType::size());
00332 for (Size i = 0; i < ContainerType::size(); ++i)
00333 {
00334 sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getIntensity(), i));
00335 }
00336
00337 if (reverse)
00338 {
00339 std::sort(sorted_indices.begin(), sorted_indices.end(), reverseComparator(PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >()));
00340 }
00341 else
00342 {
00343 std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >());
00344 }
00345
00346
00347 ContainerType tmp;
00348 for (Size i = 0; i < sorted_indices.size(); ++i)
00349 {
00350 tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
00351 }
00352 ContainerType::swap(tmp);
00353
00354 for (Size i = 0; i < float_data_arrays_.size(); ++i)
00355 {
00356 std::vector<Real> mda_tmp;
00357 for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
00358 {
00359 mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
00360 }
00361 float_data_arrays_[i].swap(mda_tmp);
00362 }
00363
00364 for (Size i = 0; i < string_data_arrays_.size(); ++i)
00365 {
00366 std::vector<String> mda_tmp;
00367 for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
00368 {
00369 mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
00370 }
00371 string_data_arrays_[i].swap(mda_tmp);
00372 }
00373
00374 for (Size i = 0; i < integer_data_arrays_.size(); ++i)
00375 {
00376 std::vector<Int> mda_tmp;
00377 for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
00378 {
00379 mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
00380 }
00381 integer_data_arrays_[i].swap(mda_tmp);
00382 }
00383 }
00384 }
00385
00391 void sortByPosition()
00392 {
00393 if (float_data_arrays_.empty())
00394 {
00395 std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::PositionLess());
00396 }
00397 else
00398 {
00399
00400 std::vector<std::pair<typename PeakType::PositionType, Size> > sorted_indices;
00401 sorted_indices.reserve(ContainerType::size());
00402 for (Size i = 0; i < ContainerType::size(); ++i)
00403 {
00404 sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getPosition(), i));
00405 }
00406 std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::PositionType, Size> >());
00407
00408
00409 ContainerType tmp;
00410 tmp.reserve(sorted_indices.size());
00411 for (Size i = 0; i < sorted_indices.size(); ++i)
00412 {
00413 tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
00414 }
00415 ContainerType::swap(tmp);
00416
00417 for (Size i = 0; i < float_data_arrays_.size(); ++i)
00418 {
00419 std::vector<Real> mda_tmp;
00420 mda_tmp.reserve(float_data_arrays_[i].size());
00421 for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
00422 {
00423 mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
00424 }
00425 std::swap(float_data_arrays_[i], mda_tmp);
00426 }
00427
00428 for (Size i = 0; i < string_data_arrays_.size(); ++i)
00429 {
00430 std::vector<String> mda_tmp;
00431 mda_tmp.reserve(string_data_arrays_[i].size());
00432 for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
00433 {
00434 mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
00435 }
00436 std::swap(string_data_arrays_[i], mda_tmp);
00437 }
00438
00439 for (Size i = 0; i < integer_data_arrays_.size(); ++i)
00440 {
00441 std::vector<Int> mda_tmp;
00442 mda_tmp.reserve(integer_data_arrays_[i].size());
00443 for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
00444 {
00445 mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
00446 }
00447 std::swap(integer_data_arrays_[i], mda_tmp);
00448 }
00449 }
00450 }
00451
00453 bool isSorted() const
00454 {
00455 for (Size i = 1; i < this->size(); ++i)
00456 {
00457 if (this->operator[](i - 1).getMZ() > this->operator[](i).getMZ()) return false;
00458 }
00459 return true;
00460 }
00461
00463
00466
00476 Size findNearest(CoordinateType mz) const
00477 {
00478
00479 if (ContainerType::size() == 0) throw Exception::Precondition(__FILE__, __LINE__, __PRETTY_FUNCTION__, "There must be at least one peak to determine the nearest peak!");
00480
00481
00482 ConstIterator it = MZBegin(mz);
00483
00484 if (it == ContainerType::begin()) return 0;
00485
00486 if (it == ContainerType::end()) return ContainerType::size() - 1;
00487
00488
00489 ConstIterator it2 = it;
00490 --it2;
00491 if (std::fabs(it->getMZ() - mz) < std::fabs(it2->getMZ() - mz))
00492 {
00493 return Size(it - ContainerType::begin());
00494 }
00495 else
00496 {
00497 return Size(it2 - ContainerType::begin());
00498 }
00499 }
00500
00506 Iterator MZBegin(CoordinateType mz)
00507 {
00508 PeakType p;
00509 p.setPosition(mz);
00510 return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00511 }
00512
00518 Iterator MZBegin(Iterator begin, CoordinateType mz, Iterator end)
00519 {
00520 PeakType p;
00521 p.setPosition(mz);
00522 return lower_bound(begin, end, p, typename PeakType::PositionLess());
00523 }
00524
00530 Iterator MZEnd(CoordinateType mz)
00531 {
00532 PeakType p;
00533 p.setPosition(mz);
00534 return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00535 }
00536
00542 Iterator MZEnd(Iterator begin, CoordinateType mz, Iterator end)
00543 {
00544 PeakType p;
00545 p.setPosition(mz);
00546 return upper_bound(begin, end, p, typename PeakType::PositionLess());
00547 }
00548
00554 ConstIterator MZBegin(CoordinateType mz) const
00555 {
00556 PeakType p;
00557 p.setPosition(mz);
00558 return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00559 }
00560
00566 ConstIterator MZBegin(ConstIterator begin, CoordinateType mz, ConstIterator end) const
00567 {
00568 PeakType p;
00569 p.setPosition(mz);
00570 return lower_bound(begin, end, p, typename PeakType::PositionLess());
00571 }
00572
00578 ConstIterator MZEnd(CoordinateType mz) const
00579 {
00580 PeakType p;
00581 p.setPosition(mz);
00582 return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00583 }
00584
00590 ConstIterator MZEnd(ConstIterator begin, CoordinateType mz, ConstIterator end) const
00591 {
00592 PeakType p;
00593 p.setPosition(mz);
00594 return upper_bound(begin, end, p, typename PeakType::PositionLess());
00595 }
00596
00598
00599
00605 void clear(bool clear_meta_data)
00606 {
00607 ContainerType::clear();
00608
00609 if (clear_meta_data)
00610 {
00611 clearRanges();
00612 clearId();
00613 this->SpectrumSettings::operator=(SpectrumSettings());
00614 retention_time_ = -1.0;
00615 ms_level_ = 1;
00616 name_.clear();
00617 float_data_arrays_.clear();
00618 string_data_arrays_.clear();
00619 integer_data_arrays_.clear();
00620 }
00621 }
00622
00623 protected:
00624
00625 virtual void clearChildIds_()
00626 {}
00627
00629 DoubleReal retention_time_;
00630
00632 UInt ms_level_;
00633
00635 String name_;
00636
00638 FloatDataArrays float_data_arrays_;
00639
00641 StringDataArrays string_data_arrays_;
00642
00644 IntegerDataArrays integer_data_arrays_;
00645 };
00646
00648 template <typename PeakT>
00649 std::ostream & operator<<(std::ostream & os, const MSSpectrum<PeakT> & spec)
00650 {
00651 os << "-- MSSPECTRUM BEGIN --" << std::endl;
00652
00653
00654 os << static_cast<const SpectrumSettings &>(spec);
00655
00656
00657 for (typename MSSpectrum<PeakT>::ConstIterator it = spec.begin(); it != spec.end(); ++it)
00658 {
00659 os << *it << std::endl;
00660 }
00661
00662 os << "-- MSSPECTRUM END --" << std::endl;
00663 return os;
00664 }
00665
00666 }
00667
00668 #endif // OPENMS_KERNEL_MSSPECTRUM_H