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

DTA2DFile.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: Marc Sturm $
00033 // --------------------------------------------------------------------------
00034 
00035 #ifndef OPENMS_FORMAT_DTA2DFILE_H
00036 #define OPENMS_FORMAT_DTA2DFILE_H
00037 
00038 #include <OpenMS/DATASTRUCTURES/String.h>
00039 #include <OpenMS/FORMAT/OPTIONS/PeakFileOptions.h>
00040 #include <OpenMS/CONCEPT/ProgressLogger.h>
00041 
00042 #include <fstream>
00043 #include <iostream>
00044 
00045 namespace OpenMS
00046 {
00047   class String;
00064   class OPENMS_DLLAPI DTA2DFile :
00065     public ProgressLogger
00066   {
00067 private:
00068     PeakFileOptions options_;
00069 
00070 public:
00071 
00074 
00075     DTA2DFile();
00077     ~DTA2DFile();
00079 
00081     PeakFileOptions & getOptions();
00082 
00084     const PeakFileOptions & getOptions() const;
00085 
00094     template <typename MapType>
00095     void load(const String & filename, MapType & map)
00096     {
00097       startProgress(0, 0, "loading DTA2D file");
00098 
00099       //try to open file
00100       std::ifstream is(filename.c_str());
00101       if (!is)
00102       {
00103         throw Exception::FileNotFound(__FILE__, __LINE__, __PRETTY_FUNCTION__, filename);
00104       }
00105 
00106       map.reset();
00107 
00108       //set DocumentIdentifier
00109       map.setLoadedFileType(filename);
00110       map.setLoadedFilePath(filename);
00111 
00112       // temporary variables to store the data in
00113       std::vector<String> strings(3);
00114       typename MapType::SpectrumType spec;
00115       spec.setRT(-1.0);       //to make sure the first RT is different from the the initialized value
00116       typename MapType::SpectrumType::PeakType p;
00117       DoubleReal rt(0.0);
00118       char delimiter;
00119 
00120       // default dimension of the data
00121       Size rt_dim = 0;
00122       Size mz_dim = 1;
00123       Size int_dim = 2;
00124 
00125       //RT unit (default is seconds)
00126       bool time_in_minutes = false;
00127 
00128       // string to store the current line in
00129       String line;
00130 
00131       // native ID (numbers from 0)
00132       UInt native_id = 0;
00133 
00134       // line number counter
00135       Size line_number = 0;
00136 
00137       while (getline(is, line, '\n'))
00138       {
00139         ++line_number;
00140         line.trim();
00141 
00142         if (line.empty()) continue;
00143 
00144         //test which delimiter is used in the line
00145         if (line.has('\t'))
00146         {
00147           delimiter = '\t';
00148         }
00149         else
00150         {
00151           delimiter = ' ';
00152         }
00153 
00154         //is header line
00155         if (line.hasPrefix("#"))
00156         {
00157           line = line.substr(1).trim();
00158           line.split(delimiter, strings);
00159 
00160           // flags to check if dimension is set correctly
00161           bool rt_set = false;
00162           bool mz_set = false;
00163           bool int_set = false;
00164 
00165           //assign new order
00166           for (Size i = 0; i < 3; ++i)
00167           {
00168             if (strings[i] == "RT" || strings[i] == "RETENTION_TIME" || strings[i] == "MASS-TO-CHARGE" || strings[i] == "IT" || strings[i] == "INTENSITY")
00169             {
00170               std::cerr << "Warning: This file contains the deprecated keyword '" << strings[i] << "'." << "\n";
00171               std::cerr << "         Please use only the new keywords SEC/MIN, MZ, INT." << "\n";
00172             }
00173             if ((strings[i] == "SEC" || strings[i] == "RT" || strings[i] == "RETENTION_TIME") && rt_set == false)
00174             {
00175               rt_dim = i;
00176               rt_set = true;
00177             }
00178             else if ((strings[i] == "MIN") && rt_set == false)
00179             {
00180               rt_dim = i;
00181               rt_set = true;
00182               time_in_minutes = true;
00183             }
00184             else if ((strings[i] == "MZ" || strings[i] == "MASS-TO-CHARGE") && mz_set == false)
00185             {
00186               mz_dim = i;
00187               mz_set = true;
00188             }
00189             else if ((strings[i] == "INT" || strings[i] == "IT" || strings[i] == "INTENSITY") && int_set == false)
00190             {
00191               int_dim = i;
00192               int_set = true;
00193             }
00194             else
00195             {
00196               throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Misformatted header line!", filename);
00197             }
00198           }
00199           continue;
00200         }
00201 
00202         try
00203         {
00204           line.split(delimiter, strings);
00205           if (strings.size() != 3)
00206           {
00207             throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\" (got  " + String(strings.size()) + ", expected 3 entries)", filename);
00208           }
00209           p.setIntensity(strings[int_dim].toFloat());
00210           p.setMZ(strings[mz_dim].toDouble());
00211           rt = (strings[rt_dim].toDouble()) * (time_in_minutes ? 60.0 : 1.0);
00212         }
00213         // conversion to double or something else could have gone wrong
00214         catch (Exception::BaseException & /*e*/)
00215         {
00216           throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\"", filename);
00217         }
00218 
00219         // Retention time changed -> new Spectrum
00220         if (fabs(rt - spec.getRT()) > 0.0001)
00221         {
00222           if (spec.size() != 0
00223              &&
00224               (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT()))))                // RT restriction fulfilled
00225           {
00226             map.push_back(spec);
00227           }
00228           setProgress(0);
00229           spec.clear(true);
00230           spec.setRT(rt);
00231           spec.setNativeID(String("index=") + native_id);
00232           ++native_id;
00233         }
00234 
00235         //Skip peaks with invalid m/z or intensity value
00236         if (
00237           (!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(p.getMZ())))
00238            &&
00239           (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(p.getIntensity())))
00240           )
00241         {
00242           spec.push_back(p);
00243         }
00244       }
00245 
00246       // add last Spectrum
00247       if (
00248         spec.size() != 0
00249          &&
00250         (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT())))             // RT restriction fulfilled
00251         )
00252       {
00253         map.push_back(spec);
00254       }
00255 
00256       is.close();
00257       endProgress();
00258     }
00259 
00267     template <typename MapType>
00268     void store(const String & filename, const MapType & map) const
00269     {
00270       startProgress(0, map.size(), "storing DTA2D file");
00271 
00272       std::ofstream os(filename.c_str());
00273       if (!os)
00274       {
00275         throw Exception::UnableToCreateFile(__FILE__, __LINE__, __PRETTY_FUNCTION__, filename);
00276       }
00277 
00278       // write header
00279       os << "#SEC\tMZ\tINT\n";
00280 
00281       // Iterate over all peaks of each spectrum and
00282       // write one line for each peak of the spectrum.
00283       UInt count = 0;
00284       for (typename MapType::const_iterator spec = map.begin(); spec != map.end(); ++spec)
00285       {
00286         setProgress(count++);
00287         for (typename MapType::SpectrumType::ConstIterator it = spec->begin(); it != spec->end(); ++it)
00288         {
00289           // Write rt, m/z and intensity.
00290           os << precisionWrapper(spec->getRT()) << "\t" << precisionWrapper(it->getPos()) << "\t" << precisionWrapper(it->getIntensity()) << "\n";
00291         }
00292 
00293       }
00294       os.close();
00295       endProgress();
00296     }
00297 
00305     template <typename MapType>
00306     void storeTIC(const String & filename, const MapType & map) const
00307     {
00308       startProgress(0, map.size(), "storing DTA2D file");
00309 
00310       std::ofstream os(filename.c_str());
00311       if (!os)
00312       {
00313         throw Exception::UnableToCreateFile(__FILE__, __LINE__, __PRETTY_FUNCTION__, filename);
00314       }
00315 
00316       // write header (Always MZ=0 for chromatograms in DTA2D.)
00317       os << "#SEC\tMZ\tINT\n";
00318 
00319       typename MapType::ChromatogramType TIC = map.getTIC();
00320       for (typename MapType::ChromatogramType::ConstIterator it = TIC.begin(); it != TIC.end(); ++it)
00321       {
00322         // write rt and intensity.
00323         os << precisionWrapper(it->getRT()) << "\t" << precisionWrapper(0) << "\t" << precisionWrapper(it->getIntensity()) << "\n";
00324       }
00325 
00326       os.close();
00327       endProgress();
00328     }
00329 
00330   };
00331 
00332 } // namespace OpenMS
00333 
00334 #endif // OPENMS_FORMAT_DTA2DFILE_H

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