OpenMS  2.8.0
DTA2DFile.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2021.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg $
32 // $Authors: Marc Sturm $
33 // --------------------------------------------------------------------------
34 
35 #pragma once
36 
41 
42 #include <fstream>
43 #include <iostream>
44 
45 namespace OpenMS
46 {
63  class OPENMS_DLLAPI DTA2DFile :
64  public ProgressLogger
65  {
66 private:
68 
69 public:
70 
76  ~DTA2DFile() override;
78 
81 
83  const PeakFileOptions& getOptions() const;
84 
94  template <typename MapType>
95  void load(const String& filename, MapType& map)
96  {
97  startProgress(0, 0, "loading DTA2D file");
98 
99  //try to open file
100  std::ifstream is(filename.c_str());
101  if (!is)
102  {
103  throw Exception::FileNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
104  }
105 
106  map.reset();
107 
108  //set DocumentIdentifier
109  map.setLoadedFileType(filename);
110  map.setLoadedFilePath(filename);
111 
112  // temporary variables to store the data in
113  std::vector<String> strings(3);
114  typename MapType::SpectrumType spec;
115  spec.setRT(-1.0); //to make sure the first RT is different from the the initialized value
117  double rt(0.0);
118  char delimiter;
119 
120  // default dimension of the data
121  Size rt_dim = 0;
122  Size mz_dim = 1;
123  Size int_dim = 2;
124 
125  //RT unit (default is seconds)
126  bool time_in_minutes = false;
127 
128  // string to store the current line in
129  String line;
130 
131  // native ID (numbers from 0)
132  UInt native_id = 0;
133 
134  // line number counter
135  Size line_number = 0;
136 
137  while (getline(is, line, '\n'))
138  {
139  ++line_number;
140  line.trim();
141 
142  if (line.empty()) continue;
143 
144  //test which delimiter is used in the line
145  if (line.has('\t'))
146  {
147  delimiter = '\t';
148  }
149  else
150  {
151  delimiter = ' ';
152  }
153 
154  //is header line
155  if (line.hasPrefix("#"))
156  {
157  line = line.substr(1).trim();
158  line.split(delimiter, strings);
159 
160  // flags to check if dimension is set correctly
161  bool rt_set = false;
162  bool mz_set = false;
163  bool int_set = false;
164 
165  //assign new order
166  for (Size i = 0; i < 3; ++i)
167  {
168  if (strings[i] == "RT" || strings[i] == "RETENTION_TIME" || strings[i] == "MASS-TO-CHARGE" || strings[i] == "IT" || strings[i] == "INTENSITY")
169  {
170  std::cerr << "Warning: This file contains the deprecated keyword '" << strings[i] << "'." << "\n";
171  std::cerr << " Please use only the new keywords SEC/MIN, MZ, INT." << "\n";
172  }
173  if ((strings[i] == "SEC" || strings[i] == "RT" || strings[i] == "RETENTION_TIME") && rt_set == false)
174  {
175  rt_dim = i;
176  rt_set = true;
177  }
178  else if ((strings[i] == "MIN") && rt_set == false)
179  {
180  rt_dim = i;
181  rt_set = true;
182  time_in_minutes = true;
183  }
184  else if ((strings[i] == "MZ" || strings[i] == "MASS-TO-CHARGE") && mz_set == false)
185  {
186  mz_dim = i;
187  mz_set = true;
188  }
189  else if ((strings[i] == "INT" || strings[i] == "IT" || strings[i] == "INTENSITY") && int_set == false)
190  {
191  int_dim = i;
192  int_set = true;
193  }
194  else
195  {
196  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Misformatted header line!", filename);
197  }
198  }
199  continue;
200  }
201 
202  try
203  {
204  line.split(delimiter, strings);
205  if (strings.size() != 3)
206  {
207  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\" (got " + String(strings.size()) + ", expected 3 entries)", filename);
208  }
209  p.setIntensity(strings[int_dim].toFloat());
210  p.setMZ(strings[mz_dim].toDouble());
211  rt = (strings[rt_dim].toDouble()) * (time_in_minutes ? 60.0 : 1.0);
212  }
213  // conversion to double or something else could have gone wrong
214  catch (Exception::BaseException& /*e*/)
215  {
216  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\"", filename);
217  }
218 
219  // Retention time changed -> new Spectrum
220  if (fabs(rt - spec.getRT()) > 0.0001)
221  {
222  if (spec.size() != 0
223  &&
224  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT())))) // RT restriction fulfilled
225  {
226  map.addSpectrum(spec);
227  }
228  setProgress(0);
229  spec.clear(true);
230  spec.setRT(rt);
231  spec.setNativeID(String("index=") + native_id);
232  ++native_id;
233  }
234 
235  //Skip peaks with invalid m/z or intensity value
236  if (
237  (!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(p.getMZ())))
238  &&
239  (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(p.getIntensity())))
240  )
241  {
242  spec.push_back(p);
243  }
244  }
245 
246  // add last Spectrum
247  if (
248  spec.size() != 0
249  &&
250  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT()))) // RT restriction fulfilled
251  )
252  {
253  map.addSpectrum(spec);
254  }
255 
256  is.close();
257  endProgress();
258  }
259 
268  template <typename MapType>
269  void store(const String& filename, const MapType& map) const
270  {
271  startProgress(0, map.size(), "storing DTA2D file");
272 
273  std::ofstream os(filename.c_str());
274  if (!os)
275  {
276  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
277  }
278 
279  // write header
280  os << "#SEC\tMZ\tINT\n";
281 
282  // Iterate over all peaks of each spectrum and
283  // write one line for each peak of the spectrum.
284  UInt count = 0;
285  for (typename MapType::const_iterator spec = map.begin(); spec != map.end(); ++spec)
286  {
287  setProgress(count++);
288  for (typename MapType::SpectrumType::ConstIterator it = spec->begin(); it != spec->end(); ++it)
289  {
290  // Write rt, m/z and intensity.
291  os << precisionWrapper(spec->getRT()) << "\t" << precisionWrapper(it->getPos()) << "\t" << precisionWrapper(it->getIntensity()) << "\n";
292  }
293 
294  }
295  os.close();
296  endProgress();
297  }
298 
307  template <typename MapType>
308  void storeTIC(const String& filename, const MapType& map) const
309  {
310  startProgress(0, map.size(), "storing DTA2D file");
311 
312  std::ofstream os(filename.c_str());
313  if (!os)
314  {
315  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
316  }
317 
318  // write header (Always MZ=0 for chromatograms in DTA2D.)
319  os << "#SEC\tMZ\tINT\n";
320 
321  typename MapType::ChromatogramType TIC = map.calculateTIC();
322  for (typename MapType::ChromatogramType::ConstIterator it = TIC.begin(); it != TIC.end(); ++it)
323  {
324  // write rt, (mz=0) and intensity.
325  os << precisionWrapper(it->getRT()) << "\t0\t" << precisionWrapper(it->getIntensity()) << "\n";
326  }
327 
328  os.close();
329  endProgress();
330  }
331 
332  };
333 
334 } // namespace OpenMS
335 
bool encloses(const PositionType &position) const
Checks whether this range contains a certain point.
Definition: DRange.h:174
DTA2D File adapter.
Definition: DTA2DFile.h:65
~DTA2DFile() override
Destructor.
DTA2DFile()
Default constructor.
const PeakFileOptions & getOptions() const
Non-mutable access to the options for loading/storing.
PeakFileOptions options_
Definition: DTA2DFile.h:67
PeakFileOptions & getOptions()
Mutable access to the options for loading/storing.
void store(const String &filename, const MapType &map) const
Stores a map in a DTA2D file.
Definition: DTA2DFile.h:269
void load(const String &filename, MapType &map)
Loads a map from a DTA2D file.
Definition: DTA2DFile.h:95
void storeTIC(const String &filename, const MapType &map) const
Stores the TIC of a map in a DTA2D file.
Definition: DTA2DFile.h:308
void setLoadedFilePath(const String &file_name)
set the file_name_ according to absolute path of the file loaded from preferably done whilst loading
void setLoadedFileType(const String &file_name)
set the file_type according to the type of the file loaded from (see FileHandler::Type) preferably do...
Exception base class.
Definition: Exception.h:91
File not found exception.
Definition: Exception.h:511
Parse Error exception.
Definition: Exception.h:624
Unable to create file exception.
Definition: Exception.h:638
The representation of a chromatogram.
Definition: MSChromatogram.h:57
In-Memory representation of a mass spectrometry run.
Definition: MSExperiment.h:73
void addSpectrum(const MSSpectrum &spectrum)
adds a spectrum to the list
Iterator begin()
Definition: MSExperiment.h:150
const MSChromatogram calculateTIC(float rt_bin_size=0, UInt ms_level=1) const
Computes the total ion chromatogram (TIC) for a given MS level (use ms_level = 0 for all levels).
Iterator end()
Definition: MSExperiment.h:160
Size size() const
Definition: MSExperiment.h:120
void reset()
Clear all internal data (spectra, ranges, metadata)
Base::const_iterator const_iterator
Definition: MSExperiment.h:118
std::vector< SpectrumType >::const_iterator ConstIterator
Non-mutable iterator.
Definition: MSExperiment.h:106
The representation of a 1D spectrum.
Definition: MSSpectrum.h:70
double getRT() const
void clear(bool clear_meta_data)
Clears all data and meta data.
void setRT(double rt)
Sets the absolute retention time (in seconds)
A 1-dimensional raw data point or peak.
Definition: Peak1D.h:54
CoordinateType getMZ() const
Non-mutable access to m/z.
Definition: Peak1D.h:107
IntensityType getIntensity() const
Definition: Peak1D.h:102
void setIntensity(IntensityType intensity)
Mutable access to the data point intensity (height)
Definition: Peak1D.h:104
void setMZ(CoordinateType mz)
Mutable access to m/z.
Definition: Peak1D.h:113
Options for loading files containing peak data.
Definition: PeakFileOptions.h:48
const DRange< 1 > & getMZRange() const
returns the MZ range
const DRange< 1 > & getIntensityRange() const
returns the intensity range
bool hasRTRange() const
returns true if an RT range has been set
bool hasMZRange() const
returns true if an MZ range has been set
bool hasIntensityRange() const
returns true if an intensity range has been set
const DRange< 1 > & getRTRange() const
returns the RT range
Base class for all classes that want to report their progress.
Definition: ProgressLogger.h:53
void setNativeID(const String &native_id)
sets the native identifier for the spectrum, used by the acquisition software.
A more convenient string class.
Definition: String.h:60
String substr(size_t pos=0, size_t n=npos) const
Wrapper for the STL substr() method. Returns a String object with its contents initialized to a subst...
bool hasPrefix(const String &string) const
true if String begins with string, false otherwise
bool has(Byte byte) const
true if String contains the byte, false otherwise
bool split(const char splitter, std::vector< String > &substrings, bool quote_protect=false) const
Splits a string into substrings using splitter as delimiter.
String & trim()
removes whitespaces (space, tab, line feed, carriage return) at the beginning and the end of the stri...
Definition: TIC.h:56
unsigned int UInt
Unsigned integer type.
Definition: Types.h:94
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:127
static double toDouble(const String &this_s)
Definition: StringUtils.h:216
static float toFloat(const String &this_s)
Definition: StringUtils.h:211
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
const PrecisionWrapper< FloatingPointType > precisionWrapper(const FloatingPointType rhs)
Wrapper function that sets the appropriate precision for output temporarily. The original precision i...
Definition: PrecisionWrapper.h:95