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

MSSpectrum.h

Go to the documentation of this file.
00001 // --------------------------------------------------------------------------
00002 //                   OpenMS -- Open-Source Mass Spectrometry
00003 // --------------------------------------------------------------------------
00004 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
00005 // ETH Zurich, and Freie Universitaet Berlin 2002-2012.
00006 //
00007 // This software is released under a three-clause BSD license:
00008 //  * Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 //  * Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //  * Neither the name of any author or any participating institution
00014 //    may be used to endorse or promote products derived from this software
00015 //    without specific prior written permission.
00016 // For a full list of authors, refer to the file AUTHORS.
00017 // --------------------------------------------------------------------------
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
00022 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // --------------------------------------------------------------------------
00031 // $Maintainer: Stephan Aiche$
00032 // $Authors: Marc Sturm $
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       //name_ can differ => it is not checked
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     // Docu in base class (RangeManager)
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         //sort index list
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         //apply sorting to ContainerType and to meta data arrays
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         //sort index list
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         //apply sorting to ContainerType and to metadataarrays
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       // no peak => no search
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       // search for position for inserting
00482       ConstIterator it = MZBegin(mz);
00483       // border cases
00484       if (it == ContainerType::begin()) return 0;
00485 
00486       if (it == ContainerType::end()) return ContainerType::size() - 1;
00487 
00488       // the peak before or the current peak are closest
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()); // no "clear" method
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     // Docu in base class
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     //spectrum settings
00654     os << static_cast<const SpectrumSettings &>(spec);
00655 
00656     //peaklist
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 } // namespace OpenMS
00667 
00668 #endif // OPENMS_KERNEL_MSSPECTRUM_H

OpenMS / TOPP release 1.10.0 Documentation generated on Thu Mar 7 2013 09:42:42 using doxygen 1.7.1