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_MSCHROMATOGRAM_H
00036 #define OPENMS_KERNEL_MSCHROMATOGRAM_H
00037
00038 #include <OpenMS/METADATA/ChromatogramSettings.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 #include <OpenMS/KERNEL/ChromatogramPeak.h>
00044
00045
00046 namespace OpenMS
00047 {
00052 template <typename PeakT = ChromatogramPeak>
00053 class MSChromatogram :
00054 public std::vector<PeakT>,
00055 public RangeManager<1>,
00056 public ChromatogramSettings,
00057 public PersistentObject
00058 {
00059
00060 public:
00061
00063 class OPENMS_DLLAPI FloatDataArray :
00064 public MetaInfoDescription,
00065 public std::vector<Real>
00066 {};
00067
00069 class OPENMS_DLLAPI StringDataArray :
00070 public MetaInfoDescription,
00071 public std::vector<String>
00072 {};
00073
00075 class OPENMS_DLLAPI IntegerDataArray :
00076 public MetaInfoDescription,
00077 public std::vector<Int>
00078 {};
00079
00081 struct MZLess :
00082 public std::binary_function<MSChromatogram, MSChromatogram, bool>
00083 {
00084 inline bool operator()(const MSChromatogram & a, const MSChromatogram & b) const
00085 {
00086 return a.getMZ() < b.getMZ();
00087 }
00088
00089 };
00090
00094 typedef PeakT PeakType;
00096 typedef typename PeakType::CoordinateType CoordinateType;
00098 typedef std::vector<PeakType> ContainerType;
00100 typedef std::vector<FloatDataArray> FloatDataArrays;
00102 typedef std::vector<StringDataArray> StringDataArrays;
00104 typedef std::vector<IntegerDataArray> IntegerDataArrays;
00106
00108
00109
00110 typedef typename ContainerType::iterator Iterator;
00112 typedef typename ContainerType::const_iterator ConstIterator;
00114 typedef typename ContainerType::reverse_iterator ReverseIterator;
00116 typedef typename ContainerType::const_reverse_iterator ConstReverseIterator;
00118
00119
00121 MSChromatogram() :
00122 ContainerType(),
00123 RangeManager<1>(),
00124 ChromatogramSettings(),
00125 PersistentObject(),
00126 name_(),
00127 float_data_arrays_(),
00128 string_data_arrays_(),
00129 integer_data_arrays_()
00130 {}
00131
00133 MSChromatogram(const MSChromatogram & source) :
00134 ContainerType(source),
00135 RangeManager<1>(source),
00136 ChromatogramSettings(source),
00137 PersistentObject(source),
00138 name_(source.name_),
00139 float_data_arrays_(source.float_data_arrays_),
00140 string_data_arrays_(source.string_data_arrays_),
00141 integer_data_arrays_(source.integer_data_arrays_)
00142 {}
00143
00145 virtual ~MSChromatogram()
00146 {}
00147
00149 MSChromatogram & operator=(const MSChromatogram & source)
00150 {
00151 if (&source == this) return *this;
00152
00153 ContainerType::operator=(source);
00154 RangeManager<1>::operator=(source);
00155 ChromatogramSettings::operator=(source);
00156 PersistentObject::operator=(source);
00157
00158 name_ = source.name_;
00159 float_data_arrays_ = source.float_data_arrays_;
00160 string_data_arrays_ = source.string_data_arrays_;
00161 integer_data_arrays_ = source.integer_data_arrays_;
00162
00163 return *this;
00164 }
00165
00167 bool operator==(const MSChromatogram & rhs) const
00168 {
00169
00170 return std::operator==(*this, rhs) &&
00171 RangeManager<1>::operator==(rhs) &&
00172 ChromatogramSettings::operator==(rhs) &&
00173 float_data_arrays_ == rhs.float_data_arrays_ &&
00174 string_data_arrays_ == rhs.string_data_arrays_ &&
00175 integer_data_arrays_ == rhs.integer_data_arrays_;
00176 }
00177
00179 bool operator!=(const MSChromatogram & rhs) const
00180 {
00181 return !(operator==(rhs));
00182 }
00183
00184
00185 virtual void updateRanges()
00186 {
00187 this->clearRanges();
00188 updateRanges_(ContainerType::begin(), ContainerType::end());
00189 }
00190
00194 inline const String & getName() const
00195 {
00196 return name_;
00197 }
00198
00200 inline void setName(const String & name)
00201 {
00202 name_ = name;
00203 }
00204
00206
00208 inline DoubleReal getMZ() const
00209 {
00210 return getProduct().getMZ();
00211 }
00212
00225
00226
00227 inline const FloatDataArrays & getFloatDataArrays() const
00228 {
00229 return float_data_arrays_;
00230 }
00231
00233 inline FloatDataArrays & getFloatDataArrays()
00234 {
00235 return float_data_arrays_;
00236 }
00237
00239 inline const StringDataArrays & getStringDataArrays() const
00240 {
00241 return string_data_arrays_;
00242 }
00243
00245 inline StringDataArrays & getStringDataArrays()
00246 {
00247 return string_data_arrays_;
00248 }
00249
00251 inline const IntegerDataArrays & getIntegerDataArrays() const
00252 {
00253 return integer_data_arrays_;
00254 }
00255
00257 inline IntegerDataArrays & getIntegerDataArrays()
00258 {
00259 return integer_data_arrays_;
00260 }
00261
00263
00266
00271 void sortByIntensity(bool reverse = false)
00272 {
00273 if (float_data_arrays_.empty() && string_data_arrays_.size() && integer_data_arrays_.size())
00274 {
00275 if (reverse)
00276 {
00277 std::sort(ContainerType::begin(), ContainerType::end(), reverseComparator(typename PeakType::IntensityLess()));
00278 }
00279 else
00280 {
00281 std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::IntensityLess());
00282 }
00283 }
00284 else
00285 {
00286
00287 std::vector<std::pair<typename PeakType::IntensityType, Size> > sorted_indices;
00288 sorted_indices.reserve(ContainerType::size());
00289 for (Size i = 0; i < ContainerType::size(); ++i)
00290 {
00291 sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getIntensity(), i));
00292 }
00293
00294 if (reverse)
00295 {
00296 std::sort(sorted_indices.begin(), sorted_indices.end(), reverseComparator(PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >()));
00297 }
00298 else
00299 {
00300 std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::IntensityType, Size> >());
00301 }
00302
00303
00304 ContainerType tmp;
00305 for (Size i = 0; i < sorted_indices.size(); ++i)
00306 {
00307 tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
00308 }
00309 ContainerType::swap(tmp);
00310
00311 for (Size i = 0; i < float_data_arrays_.size(); ++i)
00312 {
00313 std::vector<Real> mda_tmp;
00314 for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
00315 {
00316 mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
00317 }
00318 float_data_arrays_[i].swap(mda_tmp);
00319 }
00320
00321 for (Size i = 0; i < string_data_arrays_.size(); ++i)
00322 {
00323 std::vector<String> mda_tmp;
00324 for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
00325 {
00326 mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
00327 }
00328 string_data_arrays_[i].swap(mda_tmp);
00329 }
00330
00331 for (Size i = 0; i < integer_data_arrays_.size(); ++i)
00332 {
00333 std::vector<Int> mda_tmp;
00334 for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
00335 {
00336 mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
00337 }
00338 integer_data_arrays_[i].swap(mda_tmp);
00339 }
00340 }
00341 }
00342
00349 void sortByPosition()
00350 {
00351 if (float_data_arrays_.empty())
00352 {
00353 std::sort(ContainerType::begin(), ContainerType::end(), typename PeakType::PositionLess());
00354 }
00355 else
00356 {
00357
00358 std::vector<std::pair<typename PeakType::PositionType, Size> > sorted_indices;
00359 sorted_indices.reserve(ContainerType::size());
00360 for (Size i = 0; i < ContainerType::size(); ++i)
00361 {
00362 sorted_indices.push_back(std::make_pair(ContainerType::operator[](i).getPosition(), i));
00363 }
00364 std::sort(sorted_indices.begin(), sorted_indices.end(), PairComparatorFirstElement<std::pair<typename PeakType::PositionType, Size> >());
00365
00366
00367 ContainerType tmp;
00368 for (Size i = 0; i < sorted_indices.size(); ++i)
00369 {
00370 tmp.push_back(*(ContainerType::begin() + (sorted_indices[i].second)));
00371 }
00372 ContainerType::swap(tmp);
00373
00374 for (Size i = 0; i < float_data_arrays_.size(); ++i)
00375 {
00376 std::vector<Real> mda_tmp;
00377 for (Size j = 0; j < float_data_arrays_[i].size(); ++j)
00378 {
00379 mda_tmp.push_back(*(float_data_arrays_[i].begin() + (sorted_indices[j].second)));
00380 }
00381 std::swap(float_data_arrays_[i], mda_tmp);
00382 }
00383
00384 for (Size i = 0; i < string_data_arrays_.size(); ++i)
00385 {
00386 std::vector<String> mda_tmp;
00387 for (Size j = 0; j < string_data_arrays_[i].size(); ++j)
00388 {
00389 mda_tmp.push_back(*(string_data_arrays_[i].begin() + (sorted_indices[j].second)));
00390 }
00391 std::swap(string_data_arrays_[i], mda_tmp);
00392 }
00393
00394 for (Size i = 0; i < integer_data_arrays_.size(); ++i)
00395 {
00396 std::vector<Int> mda_tmp;
00397 for (Size j = 0; j < integer_data_arrays_[i].size(); ++j)
00398 {
00399 mda_tmp.push_back(*(integer_data_arrays_[i].begin() + (sorted_indices[j].second)));
00400 }
00401 std::swap(integer_data_arrays_[i], mda_tmp);
00402 }
00403 }
00404 }
00405
00407 bool isSorted() const
00408 {
00409 for (Size i = 1; i < this->size(); ++i)
00410 {
00411 if (this->operator[](i - 1).getRT() > this->operator[](i).getRT()) return false;
00412 }
00413 return true;
00414 }
00415
00417
00420
00430 Size findNearest(CoordinateType rt) const
00431 {
00432
00433 if (ContainerType::size() == 0) throw Exception::Precondition(__FILE__, __LINE__, __PRETTY_FUNCTION__, "There must be at least one peak to determine the nearest peak!");
00434
00435
00436 ConstIterator it = RTBegin(rt);
00437
00438 if (it == ContainerType::begin()) return 0;
00439
00440 if (it == ContainerType::end()) return ContainerType::size() - 1;
00441
00442
00443 ConstIterator it2 = it;
00444 --it2;
00445 if (std::fabs(it->getRT() - rt) < std::fabs(it2->getRT() - rt))
00446 {
00447 return Size(it - ContainerType::begin());
00448 }
00449 else
00450 {
00451 return Size(it2 - ContainerType::begin());
00452 }
00453 }
00454
00461 Iterator RTBegin(CoordinateType rt)
00462 {
00463 PeakType p;
00464 p.setPosition(rt);
00465 return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00466 }
00467
00474 Iterator RTBegin(Iterator begin, CoordinateType rt, Iterator end)
00475 {
00476 PeakType p;
00477 p.setPosition(rt);
00478 return lower_bound(begin, end, p, typename PeakType::PositionLess());
00479 }
00480
00487 Iterator RTEnd(CoordinateType rt)
00488 {
00489 PeakType p;
00490 p.setPosition(rt);
00491 return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00492 }
00493
00500 Iterator RTEnd(Iterator begin, CoordinateType rt, Iterator end)
00501 {
00502 PeakType p;
00503 p.setPosition(rt);
00504 return upper_bound(begin, end, p, typename PeakType::PositionLess());
00505 }
00506
00513 ConstIterator RTBegin(CoordinateType rt) const
00514 {
00515 PeakType p;
00516 p.setPosition(rt);
00517 return lower_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00518 }
00519
00526 ConstIterator RTBegin(ConstIterator begin, CoordinateType rt, ConstIterator end) const
00527 {
00528 PeakType p;
00529 p.setPosition(rt);
00530 return lower_bound(begin, end, p, typename PeakType::PositionLess());
00531 }
00532
00539 ConstIterator RTEnd(CoordinateType rt) const
00540 {
00541 PeakType p;
00542 p.setPosition(rt);
00543 return upper_bound(ContainerType::begin(), ContainerType::end(), p, typename PeakType::PositionLess());
00544 }
00545
00552 ConstIterator RTEnd(ConstIterator begin, CoordinateType rt, ConstIterator end) const
00553 {
00554 PeakType p;
00555 p.setPosition(rt);
00556 return upper_bound(begin, end, p, typename PeakType::PositionLess());
00557 }
00558
00564 void clear(bool clear_meta_data)
00565 {
00566 ContainerType::clear();
00567
00568 if (clear_meta_data)
00569 {
00570 clearRanges();
00571 clearId();
00572 this->ChromatogramSettings::operator=(ChromatogramSettings());
00573 name_.clear();
00574 float_data_arrays_.clear();
00575 string_data_arrays_.clear();
00576 integer_data_arrays_.clear();
00577 }
00578 }
00579
00581
00582 protected:
00583
00584 virtual void clearChildIds_()
00585 {}
00586
00588 String name_;
00589
00591 FloatDataArrays float_data_arrays_;
00592
00594 StringDataArrays string_data_arrays_;
00595
00597 IntegerDataArrays integer_data_arrays_;
00598 };
00599
00601 template <typename PeakT>
00602 std::ostream & operator<<(std::ostream & os, const MSChromatogram<PeakT> & spec)
00603 {
00604 os << "-- MSSPECTRUM BEGIN --" << std::endl;
00605
00606
00607 os << static_cast<const ChromatogramSettings &>(spec);
00608
00609
00610 os << static_cast<const typename MSChromatogram<PeakT>::ContainerType &>(spec);
00611
00612 os << "-- MSSPECTRUM END --" << std::endl;
00613
00614 return os;
00615 }
00616
00617 }
00618
00619 #endif // OPENMS_KERNEL_MSCHROMATOGRAM_H