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

MSChromatogram.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: Andreas Bertsch $
00032 // $Authors: Andreas Bertsch $
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       //name_ can differ => it is not checked
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     // Docu in base class (RangeManager)
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         //sort index list
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         //apply sorting to ContainerType and to meta data arrays
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         //sort index list
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         //apply sorting to ContainerType and to metadataarrays
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       //no peak => no search
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       //search for position for inserting
00436       ConstIterator it = RTBegin(rt);
00437       //border cases
00438       if (it == ContainerType::begin()) return 0;
00439 
00440       if (it == ContainerType::end()) return ContainerType::size() - 1;
00441 
00442       //the peak before or the current peak are closest
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());   // no "clear" method
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     // Docu in base class
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     //chromatogram settings
00607     os << static_cast<const ChromatogramSettings &>(spec);
00608 
00609     //peaklist
00610     os << static_cast<const typename MSChromatogram<PeakT>::ContainerType &>(spec);
00611 
00612     os << "-- MSSPECTRUM END --" << std::endl;
00613 
00614     return os;
00615   }
00616 
00617 } // namespace OpenMS
00618 
00619 #endif // OPENMS_KERNEL_MSCHROMATOGRAM_H

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