Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

MSExperiment.h (Maintainer: Marc Sturm)

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // --------------------------------------------------------------------------
00005 //                   OpenMS Mass Spectrometry Framework
00006 // --------------------------------------------------------------------------
00007 //  Copyright (C) 2003-2008 -- Oliver Kohlbacher, Knut Reinert
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Lesser General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //  This library is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //  Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with this library; if not, write to the Free Software
00021 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // --------------------------------------------------------------------------
00024 // $Maintainer: Marc Sturm $
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 > // @@ ExternalAllocator<PeakT> >  @@ std::allocator<PeakT> >
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_() //TODO use factory
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) //TODO use factory
00121       {
00122       }      
00123       
00124       /* allow templated ctors to access private members */
00125       //template < typename Ua, typename Ub > friend class MSExperiment;
00126       
00128       //template <class U2>
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_) //keep the same alloc (and externalFile)
00137       {
00138       }
00139 
00141       //template <class U2>
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         //no need to copy the alloc?!
00155         //alloc_
00156         
00157         return *this;
00158       }
00159 
00160       // overridden base class members
00161       
00162       void push_back(const SpectrumType& spec)
00163       {
00164         push_back<>(spec);      
00165       }
00166       
00167       /* see std::vector documentation */
00168       // we will copy the data, but change the allocator
00169       template <typename A>
00170       void push_back(const MSSpectrum<PeakT, A>& spec)
00171       {
00172         // create new spectrum with local allocator
00173         SpectrumType newSpec(spec, alloc_);
00174         // add it to our spectrum
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           // If the container is empty, nothing will happen
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             // check if the retention time time has changed
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             // create temporary peak and insert it into spectrum
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           //std::cout << "areaBegin: " << min_rt << " " << max_rt << " " << min_mz << " " << max_mz << std::endl;
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           //std::cout << "areaBeginConst: " << min_rt << " " << max_rt << " " << min_mz << " " << max_mz << std::endl;
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       // Docu in base class
00361       virtual void updateRanges()
00362       {
00363         updateRanges(-1);
00364       }
00365 
00371       void updateRanges(Int ms_level)
00372       {
00373         //clear MS levels
00374         ms_levels_.clear();
00375 
00376         //reset mz/rt/int range
00377         this->clearRanges();
00378         //reset point count
00379         total_size_ = 0;
00380 
00381         //empty
00382         if (this->size()==0)
00383         {
00384           return;
00385         }
00386 
00387         //update
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             //ms levels
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             // calculate size
00399             total_size_ += it->size();
00400 
00401             //rt
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             //do not update mz and int when the spectrum is empty
00406             if (it->size()==0) continue;
00407 
00408             it->updateRanges();
00409 
00410             //mz
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             //int
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           // sort each spectrum by m/z
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(); //remove data
00493         RangeManagerType::clearRanges(); //reset range manager
00494         ExperimentalSettings::operator=(ExperimentalSettings()); //reset meta info
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       // Docu in base class
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       //experimental settings
00556       os <<static_cast<const ExperimentalSettings&>(exp);
00557   
00558       //spectra
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 } // namespace OpenMS
00570 
00571 #endif // OPENMS_KERNEL_MSEXPERIMENT_H

Generated Tue Apr 1 15:36:36 2008 -- using doxygen 1.5.4 OpenMS / TOPP 1.1