OpenMS
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-2023.
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 {
65  class OPENMS_DLLAPI DTA2DFile :
66  public ProgressLogger
67  {
68 private:
70 
71 public:
72 
78  ~DTA2DFile() override;
80 
83 
85  const PeakFileOptions& getOptions() const;
86 
96  template <typename MapType>
97  void load(const String& filename, MapType& map)
98  {
99  startProgress(0, 0, "loading DTA2D file");
100 
101  //try to open file
102  std::ifstream is(filename.c_str());
103  if (!is)
104  {
105  throw Exception::FileNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
106  }
107 
108  map.reset();
109 
110  //set DocumentIdentifier
111  map.setLoadedFileType(filename);
112  map.setLoadedFilePath(filename);
113 
114  // temporary variables to store the data in
115  std::vector<String> strings(3);
116  typename MapType::SpectrumType spec;
117  spec.setRT(-1.0); //to make sure the first RT is different from the the initialized value
119  double rt(0.0);
120  char delimiter;
121 
122  // default dimension of the data
123  Size rt_dim = 0;
124  Size mz_dim = 1;
125  Size int_dim = 2;
126 
127  //RT unit (default is seconds)
128  bool time_in_minutes = false;
129 
130  // string to store the current line in
131  String line;
132 
133  // native ID (numbers from 0)
134  UInt native_id = 0;
135 
136  // line number counter
137  Size line_number = 0;
138 
139  while (getline(is, line, '\n'))
140  {
141  ++line_number;
142  line.trim();
143 
144  if (line.empty()) continue;
145 
146  //test which delimiter is used in the line
147  if (line.has('\t'))
148  {
149  delimiter = '\t';
150  }
151  else
152  {
153  delimiter = ' ';
154  }
155 
156  //is header line
157  if (line.hasPrefix("#"))
158  {
159  line = line.substr(1).trim().toUpper();
160  line.split(delimiter, strings);
161 
162  // flags to check if dimension is set correctly
163  bool rt_set = false;
164  bool mz_set = false;
165  bool int_set = false;
166 
167  //assign new order
168  for (Size i = 0; i < 3; ++i)
169  {
170  if (strings[i] == "RT" || strings[i] == "RETENTION_TIME" || strings[i] == "MASS-TO-CHARGE" || strings[i] == "IT" || strings[i] == "INTENSITY")
171  {
172  std::cerr << "Warning: This file contains the deprecated keyword '" << strings[i] << "'." << "\n";
173  std::cerr << " Please use only the new keywords SEC/MIN, MZ, INT." << "\n";
174  }
175  if ((strings[i] == "SEC" || strings[i] == "RT" || strings[i] == "RETENTION_TIME") && rt_set == false)
176  {
177  rt_dim = i;
178  rt_set = true;
179  }
180  else if ((strings[i] == "MIN") && rt_set == false)
181  {
182  rt_dim = i;
183  rt_set = true;
184  time_in_minutes = true;
185  }
186  else if ((strings[i] == "MZ" || strings[i] == "MASS-TO-CHARGE") && mz_set == false)
187  {
188  mz_dim = i;
189  mz_set = true;
190  }
191  else if ((strings[i] == "INT" || strings[i] == "IT" || strings[i] == "INTENSITY") && int_set == false)
192  {
193  int_dim = i;
194  int_set = true;
195  }
196  else
197  {
198  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Misformatted header line!", filename);
199  }
200  }
201  continue;
202  }
203 
204  try
205  {
206  line.split(delimiter, strings);
207  if (strings.size() != 3)
208  {
209  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);
210  }
211  p.setIntensity(strings[int_dim].toFloat());
212  p.setMZ(strings[mz_dim].toDouble());
213  rt = (strings[rt_dim].toDouble()) * (time_in_minutes ? 60.0 : 1.0);
214  }
215  // conversion to double or something else could have gone wrong
216  catch (Exception::BaseException& /*e*/)
217  {
218  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\"", filename);
219  }
220 
221  // Retention time changed -> new Spectrum
222  if (fabs(rt - spec.getRT()) > 0.0001)
223  {
224  if (spec.size() != 0
225  &&
226  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT())))) // RT restriction fulfilled
227  {
228  map.addSpectrum(spec);
229  }
230  setProgress(0);
231  spec.clear(true);
232  spec.setRT(rt);
233  spec.setNativeID(String("index=") + native_id);
234  ++native_id;
235  }
236 
237  //Skip peaks with invalid m/z or intensity value
238  if (
239  (!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(p.getMZ())))
240  &&
241  (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(p.getIntensity())))
242  )
243  {
244  spec.push_back(p);
245  }
246  }
247 
248  // add last Spectrum
249  if (
250  spec.size() != 0
251  &&
252  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT()))) // RT restriction fulfilled
253  )
254  {
255  map.addSpectrum(spec);
256  }
257 
258  is.close();
259  endProgress();
260  }
261 
270  template <typename MapType>
271  void store(const String& filename, const MapType& map) const
272  {
273  startProgress(0, map.size(), "storing DTA2D file");
274 
275  std::ofstream os(filename.c_str());
276  if (!os)
277  {
278  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
279  }
280 
281  // write header
282  os << "#SEC\tMZ\tINT\n";
283 
284  // Iterate over all peaks of each spectrum and
285  // write one line for each peak of the spectrum.
286  UInt count = 0;
287  for (typename MapType::const_iterator spec = map.begin(); spec != map.end(); ++spec)
288  {
289  setProgress(count++);
290  for (typename MapType::SpectrumType::ConstIterator it = spec->begin(); it != spec->end(); ++it)
291  {
292  // Write rt, m/z and intensity.
293  os << precisionWrapper(spec->getRT()) << "\t" << precisionWrapper(it->getPos()) << "\t" << precisionWrapper(it->getIntensity()) << "\n";
294  }
295 
296  }
297  os.close();
298  endProgress();
299  }
300 
309  template <typename MapType>
310  void storeTIC(const String& filename, const MapType& map) const
311  {
312  startProgress(0, map.size(), "storing DTA2D file");
313 
314  std::ofstream os(filename.c_str());
315  if (!os)
316  {
317  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
318  }
319 
320  // write header (Always MZ=0 for chromatograms in DTA2D.)
321  os << "#SEC\tMZ\tINT\n";
322 
323  typename MapType::ChromatogramType TIC = map.calculateTIC();
324  for (typename MapType::ChromatogramType::ConstIterator it = TIC.begin(); it != TIC.end(); ++it)
325  {
326  // write rt, (mz=0) and intensity.
327  os << precisionWrapper(it->getRT()) << "\t0\t" << precisionWrapper(it->getIntensity()) << "\n";
328  }
329 
330  os.close();
331  endProgress();
332  }
333 
334  };
335 
336 } // namespace OpenMS
337 
bool encloses(const PositionType &position) const
Checks whether this range contains a certain point.
Definition: DRange.h:175
DTA2D File adapter.
Definition: DTA2DFile.h:67
~DTA2DFile() override
Destructor.
DTA2DFile()
Default constructor.
const PeakFileOptions & getOptions() const
Non-mutable access to the options for loading/storing.
PeakFileOptions options_
Definition: DTA2DFile.h:69
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:271
void load(const String &filename, MapType &map)
Loads a map from a DTA2D file.
Definition: DTA2DFile.h:97
void storeTIC(const String &filename, const MapType &map) const
Stores the TIC of a map in a DTA2D file.
Definition: DTA2DFile.h:310
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:72
void addSpectrum(const MSSpectrum &spectrum)
adds a spectrum to the list
Iterator begin()
Definition: MSExperiment.h:182
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:192
Size size() const
The number of spectra.
Definition: MSExperiment.h:147
void reset()
Clear all internal data (spectra, ranges, metadata)
Base::const_iterator const_iterator
Definition: MSExperiment.h:117
std::vector< SpectrumType >::const_iterator ConstIterator
Non-mutable iterator.
Definition: MSExperiment.h:105
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:113
IntensityType getIntensity() const
Definition: Peak1D.h:108
void setIntensity(IntensityType intensity)
Mutable access to the data point intensity (height)
Definition: Peak1D.h:110
void setMZ(CoordinateType mz)
Mutable access to m/z.
Definition: Peak1D.h:119
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...
String & toUpper()
Converts the string to uppercase.
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:242
static float toFloat(const String &this_s)
Definition: StringUtils.h:237
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:48
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