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 #ifndef OPENMS_KERNEL_MSEXPERIMENT_H
00028 #define OPENMS_KERNEL_MSEXPERIMENT_H
00029
00030 #include <OpenMS/KERNEL/MSSpectrum.h>
00031 #include <OpenMS/METADATA/ExperimentalSettings.h>
00032 #include <OpenMS/DATASTRUCTURES/DRange.h>
00033 #include <OpenMS/FORMAT/PersistentObject.h>
00034 #include <OpenMS/CONCEPT/Exception.h>
00035 #include <OpenMS/KERNEL/AreaIterator.h>
00036 #include <OpenMS/SYSTEM/ExternalAllocator.h>
00037
00038 #include<vector>
00039 #include<algorithm>
00040 #include<limits>
00041
00042 #ifdef OPENMS_ENABLE_EXTERNALMEMORY
00043 #define OPENMS_DEFAULT_ALLOC ExternalAllocator<PeakT>
00044 #else
00045 #define OPENMS_DEFAULT_ALLOC std::allocator<PeakT>
00046 #endif
00047
00048 namespace OpenMS
00049 {
00063 template <typename PeakT = Peak1D, typename AllocT = OPENMS_DEFAULT_ALLOC >
00064 class MSExperiment :
00065 public std::vector<MSSpectrum<PeakT, AllocT> >,
00066 public RangeManager<2>,
00067 public ExperimentalSettings,
00068 public PersistentObject
00069 {
00070 public:
00072 typedef MSSpectrum<PeakT, AllocT> SpectrumType;
00074 typedef std::vector<SpectrumType> Base;
00076 typedef typename std::vector<SpectrumType>::iterator Iterator;
00078 typedef typename std::vector<SpectrumType>::const_iterator ConstIterator;
00079
00081 typedef Internal::AreaIterator<PeakT, PeakT&, PeakT*, Iterator, typename SpectrumType::Iterator> AreaIterator;
00083 typedef Internal::AreaIterator<const PeakT, const PeakT&, const PeakT*, ConstIterator, typename SpectrumType::ConstIterator> ConstAreaIterator;
00084
00086 typedef PeakT PeakType;
00088 typedef DRange<2> AreaType;
00090 typedef DoubleReal CoordinateType;
00092 typedef DoubleReal IntensityType;
00094 typedef RangeManager<2> RangeManagerType;
00096 typedef typename SpectrumType::const_reference ConstPeakReference;
00098 typedef typename SpectrumType::reference PeakReference;
00099
00100
00102 MSExperiment() :
00103 Base(),
00104 RangeManagerType(),
00105 ExperimentalSettings(),
00106 PersistentObject(),
00107 ms_levels_(),
00108 total_size_(0),
00109 alloc_()
00110 {
00111 }
00112
00113 MSExperiment(const AllocT& alloc) :
00114 Base(),
00115 RangeManagerType(),
00116 ExperimentalSettings(),
00117 PersistentObject(),
00118 ms_levels_(),
00119 total_size_(0),
00120 alloc_(alloc)
00121 {
00122 }
00123
00124
00125
00126
00128
00129 MSExperiment(const MSExperiment& source) :
00130 std::vector<MSSpectrum<PeakT, AllocT> >(source),
00131 RangeManagerType(source),
00132 ExperimentalSettings(source),
00133 PersistentObject(source),
00134 ms_levels_(source.ms_levels_),
00135 total_size_(source.total_size_),
00136 alloc_(source.alloc_)
00137 {
00138 }
00139
00141
00142 MSExperiment& operator= (const MSExperiment& source)
00143 {
00144 if (&source == this) return *this;
00145
00146 Base::operator=(source);
00147 RangeManagerType::operator=(source);
00148 ExperimentalSettings::operator=(source);
00149 PersistentObject::operator=(source);
00150
00151 ms_levels_ = source.ms_levels_;
00152 total_size_ = source.total_size_;
00153
00154
00155
00156
00157 return *this;
00158 }
00159
00160
00161
00162 void push_back(const SpectrumType& spec)
00163 {
00164 push_back<>(spec);
00165 }
00166
00167
00168
00169 template <typename A>
00170 void push_back(const MSSpectrum<PeakT, A>& spec)
00171 {
00172
00173 SpectrumType newSpec(spec, alloc_);
00174
00175 Base::push_back(newSpec);
00176
00177 if (spec.size() != this->back().getContainer().size())
00178 {
00179 std::cout << "ERROR in MSExperiment::push_back() : given size (" << spec.size() << ") <=> pushed size (" << this->back().getContainer().size() << ")" << std::endl;
00180 }
00181 }
00182
00184 void resize(const typename Base::size_type& size)
00185 {
00186 Base::resize(size, alloc_);
00187 }
00188
00190 MSExperiment& operator= (const ExperimentalSettings& source)
00191 {
00192 ExperimentalSettings::operator=(source);
00193
00194 return *this;
00195 }
00196
00198 bool operator== (const MSExperiment& rhs) const
00199 {
00200 return ExperimentalSettings::operator==(rhs) && std::operator==(rhs,*this);
00201 }
00203 bool operator!= (const MSExperiment& rhs) const
00204 {
00205 return !(operator==(rhs));
00206 }
00207
00214 template <class Container>
00215 void get2DData(Container& cont) const
00216 {
00217 for (typename Base_::const_iterator spec = Base_::begin(); spec != Base_::end(); ++spec)
00218 {
00219 if (spec->getMSLevel()!=1)
00220 {
00221 continue;
00222 }
00223 for (typename SpectrumType::const_iterator it = spec->
00224 begin();
00225 it!=spec->end();
00226 ++it)
00227 {
00228 cont.insert(cont.end(), typename Container::value_type());
00229 cont.back().setRT(spec->getRT());
00230 cont.back().setIntensity(it->getIntensity());
00231 cont.back().setMZ(it->getMZ());
00232 }
00233 }
00234 }
00235
00243 template <class Container>
00244 void set2DData(const Container& cont) throw (Exception::Precondition)
00245 {
00246 SpectrumType* spectrum = 0;
00247
00248 if (cont.size() == 0) return;
00249
00250 typename PeakType::CoordinateType current_rt = - std::numeric_limits<typename PeakType::CoordinateType>::max();
00251
00252 for (typename Container::const_iterator iter = cont.begin(); iter != cont.end(); ++iter)
00253 {
00254
00255 if (current_rt != iter->getRT() || spectrum == 0)
00256 {
00257 if (current_rt > iter->getRT())
00258 {
00259 throw Exception::Precondition(__FILE__, __LINE__, __PRETTY_FUNCTION__,"Input container is not sorted!");
00260 }
00261 current_rt = iter->getRT();
00262 Base_::insert(Base_::end(),SpectrumType());
00263 spectrum = &(Base_::back());
00264 spectrum->setRT(current_rt);
00265 spectrum->setMSLevel(1);
00266 }
00267
00268
00269 spectrum->insert(spectrum->end(), PeakType());
00270 spectrum->back().setIntensity(iter->getIntensity());
00271 spectrum->back().setPosition(iter->getMZ());
00272 }
00273 }
00274
00276 AreaIterator areaBegin(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz)
00277 {
00278 OPENMS_PRECONDITION(min_rt<=max_rt, "Swapped RT range boundaries!")
00279 OPENMS_PRECONDITION(min_mz<=max_mz, "Swapped MZ range boundaries!")
00280
00281 return AreaIterator(RTBegin(min_rt), RTEnd(max_rt), min_mz, max_mz);
00282 }
00283
00285 AreaIterator areaEnd()
00286 {
00287 return AreaIterator(Base_::end(),Base_::back().end());
00288 }
00289
00291 ConstAreaIterator areaBeginConst(CoordinateType min_rt, CoordinateType max_rt, CoordinateType min_mz, CoordinateType max_mz) const
00292 {
00293 OPENMS_PRECONDITION(min_rt<=max_rt, "Swapped RT range boundaries!")
00294 OPENMS_PRECONDITION(min_mz<=max_mz, "Swapped MZ range boundaries!")
00295
00296 return ConstAreaIterator(RTBegin(min_rt), RTEnd(max_rt), min_mz, max_mz);
00297 }
00298
00300 ConstAreaIterator areaEndConst() const
00301 {
00302 return ConstAreaIterator(Base_::end(),Base_::back().end());
00303 }
00304
00310 ConstIterator RTBegin(CoordinateType rt) const
00311 {
00312 SpectrumType s;
00313 s.setRT(rt);
00314 return lower_bound(Base_::begin(), Base_::end(), s, typename SpectrumType::RTLess());
00315 }
00316
00322 ConstIterator RTEnd(CoordinateType rt) const
00323 {
00324 SpectrumType s;
00325 s.setRT(rt);
00326 return upper_bound(Base_::begin(),Base_::end(), s, typename SpectrumType::RTLess());
00327 }
00328
00334 Iterator RTBegin(CoordinateType rt)
00335 {
00336 SpectrumType s;
00337 s.setRT(rt);
00338 return lower_bound(Base_::begin(), Base_::end(), s, typename SpectrumType::RTLess());
00339 }
00340
00346 Iterator RTEnd(CoordinateType rt)
00347 {
00348 SpectrumType s;
00349 s.setRT(rt);
00350 return upper_bound(Base_::begin(),Base_::end(), s, typename SpectrumType::RTLess());
00351 }
00352
00353
00360
00361 virtual void updateRanges()
00362 {
00363 updateRanges(-1);
00364 }
00365
00371 void updateRanges(Int ms_level)
00372 {
00373
00374 ms_levels_.clear();
00375
00376
00377 this->clearRanges();
00378
00379 total_size_ = 0;
00380
00381
00382 if (this->size()==0)
00383 {
00384 return;
00385 }
00386
00387
00388 for (typename Base::iterator it = this-> begin(); it!=this->end(); ++it)
00389 {
00390 if (ms_level < Int(0) || Int(it->getMSLevel())==ms_level)
00391 {
00392
00393 if (std::find(ms_levels_.begin(),ms_levels_.end(),it->getMSLevel())==ms_levels_.end())
00394 {
00395 ms_levels_.push_back(it->getMSLevel());
00396 }
00397
00398
00399 total_size_ += it->size();
00400
00401
00402 if (it->getRT() < RangeManagerType::pos_range_.minX()) RangeManagerType::pos_range_.setMinX(it->getRT());
00403 if (it->getRT() > RangeManagerType::pos_range_.maxX()) RangeManagerType::pos_range_.setMaxX(it->getRT());
00404
00405
00406 if (it->size()==0) continue;
00407
00408 it->updateRanges();
00409
00410
00411 if (it->getMin()[0] < RangeManagerType::pos_range_.minY()) RangeManagerType::pos_range_.setMinY(it->getMin()[0]);
00412 if (it->getMax()[0] > RangeManagerType::pos_range_.maxY()) RangeManagerType::pos_range_.setMaxY(it->getMax()[0]);
00413
00414
00415 if (it->getMinInt() < RangeManagerType::int_range_.minX()) RangeManagerType::int_range_.setMinX(it->getMinInt());
00416 if (it->getMaxInt() > RangeManagerType::int_range_.maxX()) RangeManagerType::int_range_.setMaxX(it->getMaxInt());
00417
00418 }
00419 }
00420 std::sort(ms_levels_.begin(), ms_levels_.end());
00421 }
00422
00424 CoordinateType getMinMZ() const
00425 {
00426 return RangeManagerType::pos_range_.min()[1];
00427 }
00428
00430 CoordinateType getMaxMZ() const
00431 {
00432 return RangeManagerType::pos_range_.max()[1];
00433 }
00434
00436 CoordinateType getMinRT() const
00437 {
00438 return RangeManagerType::pos_range_.min()[0];
00439 }
00440
00442 CoordinateType getMaxRT() const
00443 {
00444 return RangeManagerType::pos_range_.max()[0];
00445 }
00446
00452 const AreaType& getDataRange() const
00453 {
00454 return RangeManagerType::pos_range_;
00455 }
00456
00458 UInt getSize() const
00459 {
00460 return total_size_;
00461 }
00462
00464 const std::vector<UInt>& getMSLevels() const
00465 {
00466 return ms_levels_;
00467 }
00469
00475 void sortSpectra(bool sort_mz = true)
00476 {
00477 std::sort(this->begin(),this->end(),typename SpectrumType::RTLess());
00478
00479 if (sort_mz)
00480 {
00481
00482 for (Iterator iter = this->begin(); iter != this->end(); ++iter)
00483 {
00484 iter->getContainer().sortByPosition();
00485 }
00486 }
00487 }
00488
00490 void reset()
00491 {
00492 Base::clear();
00493 RangeManagerType::clearRanges();
00494 ExperimentalSettings::operator=(ExperimentalSettings());
00495 }
00496
00498 const ExperimentalSettings& getExperimentalSettings() const { return *this; }
00500 ExperimentalSettings& getExperimentalSettings() { return *this; }
00501
00507 ConstIterator getPrecursorSpectrum(ConstIterator iterator) const
00508 {
00509 if (iterator==this->end() || iterator==this->begin())
00510 {
00511 return this->end();
00512 }
00513 UInt ms_level = iterator->getMSLevel();
00514 do
00515 {
00516 --iterator;
00517 if (iterator->getMSLevel() < ms_level)
00518 {
00519 return iterator;
00520 }
00521 }
00522 while (iterator!=this->begin());
00523
00524 return this->end();
00525 }
00526
00527 protected:
00528
00529
00530 virtual void clearChildIds_()
00531 {
00532 for (UInt i=0; i<this->size(); ++i)
00533 {
00534 this->operator[](i).clearId(true);
00535 }
00536 }
00537
00539 typedef typename std::vector<MSSpectrum<PeakT, AllocT> > Base_;
00540
00542 std::vector<UInt> ms_levels_;
00544 UInt total_size_;
00546 AllocT alloc_;
00547 };
00548
00550 template <typename PeakT, typename AllocT>
00551 std::ostream& operator << (std::ostream& os, const MSExperiment<PeakT, AllocT>& exp)
00552 {
00553 os << "-- MSEXPERIMENT BEGIN --"<<std::endl;
00554
00555
00556 os <<static_cast<const ExperimentalSettings&>(exp);
00557
00558
00559 for (typename MSExperiment<PeakT, AllocT>::const_iterator it=exp.begin(); it!=exp.end(); ++it)
00560 {
00561 os << *it;
00562 }
00563
00564 os << "-- MSEXPERIMENT END --"<<std::endl;
00565
00566 return os;
00567 }
00568
00569 }
00570
00571 #endif // OPENMS_KERNEL_MSEXPERIMENT_H