OpenMS
DTA2DFile.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Timo Sachsenberg $
6 // $Authors: Marc Sturm $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
15 
16 #include <fstream>
17 #include <iostream>
18 
19 namespace OpenMS
20 {
39  class OPENMS_DLLAPI DTA2DFile :
40  public ProgressLogger
41  {
42 private:
44 
45 public:
46 
52  ~DTA2DFile() override;
54 
57 
59  const PeakFileOptions& getOptions() const;
60 
70  template <typename MapType>
71  void load(const String& filename, MapType& map)
72  {
73  startProgress(0, 0, "loading DTA2D file");
74 
75  //try to open file
76  std::ifstream is(filename.c_str());
77  if (!is)
78  {
79  throw Exception::FileNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
80  }
81 
82  map.reset();
83 
84  //set DocumentIdentifier
85  map.setLoadedFileType(filename);
86  map.setLoadedFilePath(filename);
87 
88  // temporary variables to store the data in
89  std::vector<String> strings(3);
90  typename MapType::SpectrumType spec;
91  spec.setRT(-1.0); //to make sure the first RT is different from the the initialized value
93  double rt(0.0);
94  char delimiter;
95 
96  // default dimension of the data
97  Size rt_dim = 0;
98  Size mz_dim = 1;
99  Size int_dim = 2;
100 
101  //RT unit (default is seconds)
102  bool time_in_minutes = false;
103 
104  // string to store the current line in
105  String line;
106 
107  // native ID (numbers from 0)
108  UInt native_id = 0;
109 
110  // line number counter
111  Size line_number = 0;
112 
113  while (getline(is, line, '\n'))
114  {
115  ++line_number;
116  line.trim();
117 
118  if (line.empty()) continue;
119 
120  //test which delimiter is used in the line
121  if (line.has('\t'))
122  {
123  delimiter = '\t';
124  }
125  else
126  {
127  delimiter = ' ';
128  }
129 
130  //is header line
131  if (line.hasPrefix("#"))
132  {
133  line = line.substr(1).trim().toUpper();
134  line.split(delimiter, strings);
135 
136  // flags to check if dimension is set correctly
137  bool rt_set = false;
138  bool mz_set = false;
139  bool int_set = false;
140 
141  //assign new order
142  for (Size i = 0; i < 3; ++i)
143  {
144  if (strings[i] == "RT" || strings[i] == "RETENTION_TIME" || strings[i] == "MASS-TO-CHARGE" || strings[i] == "IT" || strings[i] == "INTENSITY")
145  {
146  std::cerr << "Warning: This file contains the deprecated keyword '" << strings[i] << "'." << "\n";
147  std::cerr << " Please use only the new keywords SEC/MIN, MZ, INT." << "\n";
148  }
149  if ((strings[i] == "SEC" || strings[i] == "RT" || strings[i] == "RETENTION_TIME") && rt_set == false)
150  {
151  rt_dim = i;
152  rt_set = true;
153  }
154  else if ((strings[i] == "MIN") && rt_set == false)
155  {
156  rt_dim = i;
157  rt_set = true;
158  time_in_minutes = true;
159  }
160  else if ((strings[i] == "MZ" || strings[i] == "MASS-TO-CHARGE") && mz_set == false)
161  {
162  mz_dim = i;
163  mz_set = true;
164  }
165  else if ((strings[i] == "INT" || strings[i] == "IT" || strings[i] == "INTENSITY") && int_set == false)
166  {
167  int_dim = i;
168  int_set = true;
169  }
170  else
171  {
172  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Misformatted header line!", filename);
173  }
174  }
175  continue;
176  }
177 
178  try
179  {
180  line.split(delimiter, strings);
181  if (strings.size() != 3)
182  {
183  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);
184  }
185  p.setIntensity(strings[int_dim].toFloat());
186  p.setMZ(strings[mz_dim].toDouble());
187  rt = (strings[rt_dim].toDouble()) * (time_in_minutes ? 60.0 : 1.0);
188  }
189  // conversion to double or something else could have gone wrong
190  catch (Exception::BaseException& /*e*/)
191  {
192  throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, std::string("Bad data line (" + String(line_number) + "): \"") + line + "\"", filename);
193  }
194 
195  // Retention time changed -> new Spectrum
196  if (fabs(rt - spec.getRT()) > 0.0001)
197  {
198  if (spec.size() != 0
199  &&
200  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT())))) // RT restriction fulfilled
201  {
202  map.addSpectrum(spec);
203  }
204  setProgress(0);
205  spec.clear(true);
206  spec.setRT(rt);
207  spec.setNativeID(String("index=") + native_id);
208  ++native_id;
209  }
210 
211  //Skip peaks with invalid m/z or intensity value
212  if (
213  (!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(p.getMZ())))
214  &&
215  (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(p.getIntensity())))
216  )
217  {
218  spec.push_back(p);
219  }
220  }
221 
222  // add last Spectrum
223  if (
224  spec.size() != 0
225  &&
226  (!options_.hasRTRange() || options_.getRTRange().encloses(DPosition<1>(spec.getRT()))) // RT restriction fulfilled
227  )
228  {
229  map.addSpectrum(spec);
230  }
231 
232  is.close();
233  endProgress();
234  }
235 
244  template <typename MapType>
245  void store(const String& filename, const MapType& map) const
246  {
247  startProgress(0, map.size(), "storing DTA2D file");
248 
249  std::ofstream os(filename.c_str());
250  if (!os)
251  {
252  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
253  }
254 
255  // write header
256  os << "#SEC\tMZ\tINT\n";
257 
258  // Iterate over all peaks of each spectrum and
259  // write one line for each peak of the spectrum.
260  UInt count = 0;
261  for (typename MapType::const_iterator spec = map.begin(); spec != map.end(); ++spec)
262  {
263  setProgress(count++);
264  for (typename MapType::SpectrumType::ConstIterator it = spec->begin(); it != spec->end(); ++it)
265  {
266  // Write rt, m/z and intensity.
267  os << precisionWrapper(spec->getRT()) << "\t" << precisionWrapper(it->getPos()) << "\t" << precisionWrapper(it->getIntensity()) << "\n";
268  }
269 
270  }
271  os.close();
272  endProgress();
273  }
274 
283  template <typename MapType>
284  void storeTIC(const String& filename, const MapType& map) const
285  {
286  startProgress(0, map.size(), "storing DTA2D file");
287 
288  std::ofstream os(filename.c_str());
289  if (!os)
290  {
291  throw Exception::UnableToCreateFile(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename);
292  }
293 
294  // write header (Always MZ=0 for chromatograms in DTA2D.)
295  os << "#SEC\tMZ\tINT\n";
296 
297  typename MapType::ChromatogramType TIC = map.calculateTIC();
298  for (typename MapType::ChromatogramType::ConstIterator it = TIC.begin(); it != TIC.end(); ++it)
299  {
300  // write rt, (mz=0) and intensity.
301  os << precisionWrapper(it->getRT()) << "\t0\t" << precisionWrapper(it->getIntensity()) << "\n";
302  }
303 
304  os.close();
305  endProgress();
306  }
307 
308  };
309 
310 } // namespace OpenMS
311 
bool encloses(const PositionType &position) const
Checks whether this range contains a certain point.
Definition: DRange.h:149
DTA2D File adapter.
Definition: DTA2DFile.h:41
~DTA2DFile() override
Destructor.
DTA2DFile()
Default constructor.
const PeakFileOptions & getOptions() const
Non-mutable access to the options for loading/storing.
PeakFileOptions options_
Definition: DTA2DFile.h:43
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:245
void load(const String &filename, MapType &map)
Loads a map from a DTA2D file.
Definition: DTA2DFile.h:71
void storeTIC(const String &filename, const MapType &map) const
Stores the TIC of a map in a DTA2D file.
Definition: DTA2DFile.h:284
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:65
File not found exception.
Definition: Exception.h:485
Parse Error exception.
Definition: Exception.h:598
Unable to create file exception.
Definition: Exception.h:612
The representation of a chromatogram.
Definition: MSChromatogram.h:31
In-Memory representation of a mass spectrometry run.
Definition: MSExperiment.h:46
void addSpectrum(const MSSpectrum &spectrum)
adds a spectrum to the list
Iterator begin()
Definition: MSExperiment.h:156
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:166
Size size() const
The number of spectra.
Definition: MSExperiment.h:121
void reset()
Clear all internal data (spectra, ranges, metadata)
Base::const_iterator const_iterator
Definition: MSExperiment.h:91
std::vector< SpectrumType >::const_iterator ConstIterator
Non-mutable iterator.
Definition: MSExperiment.h:79
The representation of a 1D spectrum.
Definition: MSSpectrum.h:44
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:28
CoordinateType getMZ() const
Non-mutable access to m/z.
Definition: Peak1D.h:87
IntensityType getIntensity() const
Definition: Peak1D.h:82
void setIntensity(IntensityType intensity)
Mutable access to the data point intensity (height)
Definition: Peak1D.h:84
void setMZ(CoordinateType mz)
Mutable access to m/z.
Definition: Peak1D.h:93
Options for loading files containing peak data.
Definition: PeakFileOptions.h:22
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:27
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:34
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:30
unsigned int UInt
Unsigned integer type.
Definition: Types.h:68
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:101
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:22
const PrecisionWrapper< FloatingPointType > precisionWrapper(const FloatingPointType rhs)
Wrapper function that sets the appropriate precision for output temporarily. The original precision i...
Definition: PrecisionWrapper.h:69