Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
MzMLHandler.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-2015.
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: Andreas Bertsch $
32 // $Authors: Marc Sturm $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_FORMAT_HANDLERS_MZMLHANDLER_H
36 #define OPENMS_FORMAT_HANDLERS_MZMLHANDLER_H
37 
41 
43 
45 
47 
52 #include <OpenMS/FORMAT/Base64.h>
58 
59 #include <OpenMS/SYSTEM/File.h>
60 
61 #include <sstream>
62 #include <iostream>
63 
64 #include <QRegExp>
65 
66 //MISSING:
67 // - more than one selected ion per precursor (warning if more than one)
68 // - scanWindowList for each acquisition separately (currently for the whole spectrum only)
69 // - instrumentConfigurationRef attribute for scan (why should the instrument change between scans? - warning if used)
70 // - scanSettingsRef attribute for instrumentConfiguration tag (currently no information there because of missing mapping file entry - warning if used)
71 
72 // xs:id/xs:idref prefix list
73 // - sf_ru : sourceFile (run)
74 // - sf_sp : sourceFile (spectrum)
75 // - sf_pr : sourceFile (precursor)
76 // - sf_ac : sourceFile (acquisition)
77 // - sa : sample
78 // - ic : instrumentConfiguration
79 // - so_dp : software (data processing)
80 // - so_in : software (instrument)
81 // - dp_sp : dataProcessing (spectrum)
82 // - dp_bi : dataProcessing (binary data array)
83 // - dp_ch : dataProcessing (chromatogram)
84 
85 namespace OpenMS
86 {
87  class ControlledVocabulary;
88  namespace Internal
89  {
90 
107  template <typename MapType>
108  class MzMLHandler :
109  public XMLHandler
110  {
111 public:
114 
116  MzMLHandler(MapType& exp, const String& filename, const String& version, ProgressLogger& logger) :
117  XMLHandler(filename, version),
118  exp_(&exp),
119  cexp_(0),
120  options_(),
121  spec_(),
122  chromatogram_(),
123  data_(),
125  in_spectrum_list_(false),
126  decoder_(),
127  logger_(logger),
128  consumer_(NULL),
129  scan_count(0),
131  skip_chromatogram_(false),
132  skip_spectrum_(false),
133  rt_set_(false) /* ,
134  validator_(mapping_, cv_) */
135  {
136  cv_.loadFromOBO("MS", File::find("/CV/psi-ms.obo"));
137  cv_.loadFromOBO("PATO", File::find("/CV/quality.obo"));
138  cv_.loadFromOBO("UO", File::find("/CV/unit.obo"));
139  cv_.loadFromOBO("BTO", File::find("/CV/brenda.obo"));
140  cv_.loadFromOBO("GO", File::find("/CV/goslim_goa.obo"));
141 
142  CVMappingFile().load(File::find("/MAPPING/ms-mapping.xml"), mapping_);
143  //~ validator_ = Internal::MzMLValidator(mapping_, cv_);
144 
145  // check the version number of the mzML handler
147  {
148  LOG_ERROR << "MzMLHandler was initialized with an invalid version number: " << version_ << std::endl;
149  }
150  }
151 
153  MzMLHandler(const MapType& exp, const String& filename, const String& version, const ProgressLogger& logger) :
154  XMLHandler(filename, version),
155  exp_(0),
156  cexp_(&exp),
157  options_(),
158  spec_(),
159  chromatogram_(),
160  data_(),
162  in_spectrum_list_(false),
163  decoder_(),
164  logger_(logger),
165  consumer_(NULL),
166  scan_count(0),
168  skip_chromatogram_(false),
169  skip_spectrum_(false),
170  rt_set_(false) /* ,
171  validator_(mapping_, cv_) */
172  {
173  cv_.loadFromOBO("MS", File::find("/CV/psi-ms.obo"));
174  cv_.loadFromOBO("PATO", File::find("/CV/quality.obo"));
175  cv_.loadFromOBO("UO", File::find("/CV/unit.obo"));
176  cv_.loadFromOBO("BTO", File::find("/CV/brenda.obo"));
177  cv_.loadFromOBO("GO", File::find("/CV/goslim_goa.obo"));
178 
179  CVMappingFile().load(File::find("/MAPPING/ms-mapping.xml"), mapping_);
180  //~ validator_ = Internal::MzMLValidator(mapping_, cv_);
181 
182  // check the version number of the mzML handler
184  {
185  LOG_ERROR << "MzMLHandler was initialized with an invalid version number: " << version_ << std::endl;
186  }
187  }
188 
190  virtual ~MzMLHandler() {}
192 
195 
196  // Docu in base class
197  virtual void endElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname);
198 
199  // Docu in base class
200  virtual void startElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname, const xercesc::Attributes& attributes);
201 
202  // Docu in base class
203  virtual void characters(const XMLCh* const chars, const XMLSize_t length);
204 
205  //Docu in base class
206  virtual void writeTo(std::ostream& os);
207 
209 
220 
222  void setOptions(const PeakFileOptions& opt)
223  {
224  options_ = opt;
225  }
226 
229  {
230  return options_;
231  }
232 
234 
236  void getCounts(Size& spectra_counts, Size& chromatogram_counts)
237  {
238  spectra_counts = scan_count;
239  chromatogram_counts = chromatogram_count;
240  }
241 
244  {
245  consumer_ = consumer;
246  }
247 
248 protected:
249 
251  typedef typename MapType::PeakType PeakType;
258 
260 
261  void writeSpectrum_(std::ostream& os, const SpectrumType& spec, Size s,
262  Internal::MzMLValidator& validator, bool renew_native_ids,
263  std::vector<std::vector<DataProcessing> >& dps);
264 
265  void writeChromatogram_(std::ostream& os, const ChromatogramType& chromatogram, Size c, Internal::MzMLValidator& validator);
266 
267  template <typename ContainerT>
268  void writeContainerData(std::ostream& os, const PeakFileOptions& pf_options_, const ContainerT& container, String array_type)
269  {
270 
271  bool is32Bit = ((array_type == "intensity" && pf_options_.getIntensity32Bit()) || pf_options_.getMz32Bit());
273  {
274  std::vector<double> data_to_encode(container.size());
275  if (array_type == "intensity")
276  {
277  for (Size p = 0; p < container.size(); ++p)
278  {
279  data_to_encode[p] = container[p].getIntensity();
280  }
281  }
282  else
283  {
284  for (Size p = 0; p < container.size(); ++p)
285  {
286  data_to_encode[p] = container[p].getMZ();
287  }
288  }
289  writeBinaryDataArray(os, pf_options_, data_to_encode, false, array_type);
290  }
291  else
292  {
293  std::vector<float> data_to_encode(container.size());
294 
295  if (array_type == "intensity")
296  {
297  for (Size p = 0; p < container.size(); ++p)
298  {
299  data_to_encode[p] = container[p].getIntensity();
300  }
301  }
302  else
303  {
304  for (Size p = 0; p < container.size(); ++p)
305  {
306  data_to_encode[p] = container[p].getMZ();
307  }
308  }
309  writeBinaryDataArray(os, pf_options_, data_to_encode, true, array_type);
310  }
311 
312  }
313 
321  {
322 
323  // Whether spectrum should be populated with data
324  if (options_.getFillData())
325  {
326  size_t errCount = 0;
327 #ifdef _OPENMP
328 #pragma omp parallel for
329 #endif
330  for (SignedSize i = 0; i < (SignedSize)spectrum_data_.size(); i++)
331  {
332  // parallel exception catching and re-throwing business
333  if (!errCount) // no need to parse further if already an error was encountered
334  {
335  try
336  {
338  spectrum_data_[i].default_array_length, options_,
339  spectrum_data_[i].spectrum);
340  if (options_.getSortSpectraByMZ() && !spectrum_data_[i].spectrum.isSorted())
341  {
342  spectrum_data_[i].spectrum.sortByPosition();
343  }
344  }
345  catch (...)
346  {
347 #pragma omp critical(HandleException)
348  ++errCount;
349  }
350  }
351  }
352  if (errCount != 0)
353  {
354  throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, file_, "Error during parsing of binary data.");
355  }
356  }
357 
358  // Append all spectra to experiment / consumer
359  for (Size i = 0; i < spectrum_data_.size(); i++)
360  {
361  if (consumer_ != NULL)
362  {
363  consumer_->consumeSpectrum(spectrum_data_[i].spectrum);
365  {
366  exp_->addSpectrum(spectrum_data_[i].spectrum);
367  }
368  }
369  else
370  {
371  exp_->addSpectrum(spectrum_data_[i].spectrum);
372  }
373  }
374 
375  // Delete batch
376  spectrum_data_.clear();
377  }
378 
386  {
387  // Whether chromatogram should be populated with data
388  if (options_.getFillData())
389  {
390  size_t errCount = 0;
391 #ifdef _OPENMP
392 #pragma omp parallel for
393 #endif
394  for (SignedSize i = 0; i < (SignedSize)chromatogram_data_.size(); i++)
395  {
396  // parallel exception catching and re-throwing business
397  try
398  {
400  chromatogram_data_[i].default_array_length, options_,
401  chromatogram_data_[i].chromatogram);
402  if (options_.getSortChromatogramsByRT() && !chromatogram_data_[i].chromatogram.isSorted())
403  {
404  chromatogram_data_[i].chromatogram.sortByPosition();
405  }
406  }
407  catch (...)
408  {++errCount; }
409  }
410  if (errCount != 0)
411  {
412  throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, file_, "Error during parsing of binary data.");
413  }
414 
415  }
416 
417  // Append all chromatograms to experiment / consumer
418  for (Size i = 0; i < chromatogram_data_.size(); i++)
419  {
420  if (consumer_ != NULL)
421  {
422  consumer_->consumeChromatogram(chromatogram_data_[i].chromatogram);
424  {
425  exp_->addChromatogram(chromatogram_data_[i].chromatogram);
426  }
427  }
428  else
429  {
430  exp_->addChromatogram(chromatogram_data_[i].chromatogram);
431  }
432  }
433 
434  // Delete batch
435  chromatogram_data_.clear();
436  }
437 
445  template <typename SpectrumType>
446  void populateSpectraWithData_(std::vector<MzMLHandlerHelper::BinaryData>& input_data,
447  Size& default_arr_length, const PeakFileOptions& peak_file_options,
448  SpectrumType& spectrum)
449  {
450  typedef typename SpectrumType::PeakType PeakType;
451 
452  //decode all base64 arrays
454 
455  //look up the precision and the index of the intensity and m/z array
456  bool mz_precision_64 = true;
457  bool int_precision_64 = true;
458  SignedSize mz_index = -1;
459  SignedSize int_index = -1;
460  MzMLHandlerHelper::computeDataProperties_(input_data, mz_precision_64, mz_index, "m/z array");
461  MzMLHandlerHelper::computeDataProperties_(input_data, int_precision_64, int_index, "intensity array");
462 
463  //Abort if no m/z or intensity array is present
464  if (int_index == -1 || mz_index == -1)
465  {
466  //if defaultArrayLength > 0 : warn that no m/z or int arrays is present
467  if (default_arr_length != 0)
468  {
469  warning(LOAD, String("The m/z or intensity array of spectrum '") + spectrum.getNativeID() + "' is missing and default_arr_length is " + default_arr_length + ".");
470  }
471  return;
472  }
473 
474  // Error if intensity or m/z is encoded as int32|64 - they should be float32|64!
475  if ((input_data[mz_index].ints_32.size() > 0) || (input_data[mz_index].ints_64.size() > 0))
476  {
477  fatalError(LOAD, "Encoding m/z array as integer is not allowed!");
478  }
479  if ((input_data[int_index].ints_32.size() > 0) || (input_data[int_index].ints_64.size() > 0))
480  {
481  fatalError(LOAD, "Encoding intensity array as integer is not allowed!");
482  }
483 
484  // Warn if the decoded data has a different size than the defaultArrayLength
485  Size mz_size = mz_precision_64 ? input_data[mz_index].floats_64.size() : input_data[mz_index].floats_32.size();
486  Size int_size = int_precision_64 ? input_data[int_index].floats_64.size() : input_data[int_index].floats_32.size();
487  // Check if int-size and mz-size are equal
488  if (mz_size != int_size)
489  {
490  fatalError(LOAD, String("The length of m/z and integer values of spectrum '") + spectrum.getNativeID() + "' differ (mz-size: " + mz_size + ", int-size: " + int_size + "! Not reading spectrum!");
491  }
492  bool repair_array_length = false;
493  if (default_arr_length != mz_size)
494  {
495  warning(LOAD, String("The m/z array of spectrum '") + spectrum.getNativeID() + "' has the size " + mz_size + ", but it should have size " + default_arr_length + " (defaultArrayLength).");
496  repair_array_length = true;
497  }
498  if (default_arr_length != int_size)
499  {
500  warning(LOAD, String("The intensity array of spectrum '") + spectrum.getNativeID() + "' has the size " + int_size + ", but it should have size " + default_arr_length + " (defaultArrayLength).");
501  repair_array_length = true;
502  }
503  if (repair_array_length)
504  {
505  default_arr_length = int_size;
506  warning(LOAD, String("Fixing faulty defaultArrayLength to ") + default_arr_length + ".");
507  }
508 
509  //create meta data arrays and reserve enough space for the content
510  if (input_data.size() > 2)
511  {
512  for (Size i = 0; i < input_data.size(); i++)
513  {
514  if (input_data[i].meta.getName() != "m/z array" && input_data[i].meta.getName() != "intensity array")
515  {
516  if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_FLOAT)
517  {
518  //create new array
519  spectrum.getFloatDataArrays().resize(spectrum.getFloatDataArrays().size() + 1);
520  //reserve space in the array
521  spectrum.getFloatDataArrays().back().reserve(input_data[i].size);
522  //copy meta info into MetaInfoDescription
523  spectrum.getFloatDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
524  }
525  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_INT)
526  {
527  //create new array
528  spectrum.getIntegerDataArrays().resize(spectrum.getIntegerDataArrays().size() + 1);
529  //reserve space in the array
530  spectrum.getIntegerDataArrays().back().reserve(input_data[i].size);
531  //copy meta info into MetaInfoDescription
532  spectrum.getIntegerDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
533  }
534  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_STRING)
535  {
536  //create new array
537  spectrum.getStringDataArrays().resize(spectrum.getStringDataArrays().size() + 1);
538  //reserve space in the array
539  spectrum.getStringDataArrays().back().reserve(input_data[i].decoded_char.size());
540  //copy meta info into MetaInfoDescription
541  spectrum.getStringDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
542  }
543  }
544  }
545  }
546 
547  // Copy meta data from m/z and intensity binary
548  // We don't have this as a separate location => store it in spectrum
549  for (Size i = 0; i < input_data.size(); i++)
550  {
551  if (input_data[i].meta.getName() == "m/z array" || input_data[i].meta.getName() == "intensity array")
552  {
553  std::vector<UInt> keys;
554  input_data[i].meta.getKeys(keys);
555  for (Size k = 0; k < keys.size(); ++k)
556  {
557  spectrum.setMetaValue(keys[k], input_data[i].meta.getMetaValue(keys[k]));
558  }
559  }
560  }
561 
562  //add the peaks and the meta data to the container (if they pass the restrictions)
563  PeakType tmp;
564  spectrum.reserve(default_arr_length);
565  for (Size n = 0; n < default_arr_length; n++)
566  {
567  double mz = mz_precision_64 ? input_data[mz_index].floats_64[n] : input_data[mz_index].floats_32[n];
568  double intensity = int_precision_64 ? input_data[int_index].floats_64[n] : input_data[int_index].floats_32[n];
569  if ((!peak_file_options.hasMZRange() || peak_file_options.getMZRange().encloses(DPosition<1>(mz)))
570  && (!peak_file_options.hasIntensityRange() || peak_file_options.getIntensityRange().encloses(DPosition<1>(intensity))))
571  {
572  //add peak
573  tmp.setIntensity(intensity);
574  tmp.setMZ(mz);
575  spectrum.push_back(tmp);
576 
577  //add meta data
578  UInt meta_float_array_index = 0;
579  UInt meta_int_array_index = 0;
580  UInt meta_string_array_index = 0;
581  for (Size i = 0; i < input_data.size(); i++) //loop over all binary data arrays
582  {
583  if (input_data[i].meta.getName() != "m/z array" && input_data[i].meta.getName() != "intensity array") // is meta data array?
584  {
585  if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_FLOAT)
586  {
587  if (n < input_data[i].size)
588  {
589  double value = (input_data[i].precision == MzMLHandlerHelper::BinaryData::PRE_64) ? input_data[i].floats_64[n] : input_data[i].floats_32[n];
590  spectrum.getFloatDataArrays()[meta_float_array_index].push_back(value);
591  }
592  ++meta_float_array_index;
593  }
594  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_INT)
595  {
596  if (n < input_data[i].size)
597  {
598  Int64 value = (input_data[i].precision == MzMLHandlerHelper::BinaryData::PRE_64) ? input_data[i].ints_64[n] : input_data[i].ints_32[n];
599  spectrum.getIntegerDataArrays()[meta_int_array_index].push_back(value);
600  }
601  ++meta_int_array_index;
602  }
603  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_STRING)
604  {
605  if (n < input_data[i].decoded_char.size())
606  {
607  String value = input_data[i].decoded_char[n];
608  spectrum.getStringDataArrays()[meta_string_array_index].push_back(value);
609  }
610  ++meta_string_array_index;
611  }
612  }
613  }
614  }
615  }
616  }
617 
625  template <typename ChromatogramType>
626  void populateChromatogramsWithData_(std::vector<MzMLHandlerHelper::BinaryData>& input_data,
627  Size& default_arr_length, const PeakFileOptions& peak_file_options,
628  ChromatogramType& inp_chromatogram)
629  {
631 
632  //decode all base64 arrays
634 
635  //look up the precision and the index of the intensity and m/z array
636  bool int_precision_64 = true;
637  bool rt_precision_64 = true;
638  SignedSize int_index = -1;
639  SignedSize rt_index = -1;
640  MzMLHandlerHelper::computeDataProperties_(input_data, rt_precision_64, rt_index, "time array");
641  MzMLHandlerHelper::computeDataProperties_(input_data, int_precision_64, int_index, "intensity array");
642 
643  //Abort if no m/z or intensity array is present
644  if (int_index == -1 || rt_index == -1)
645  {
646  //if defaultArrayLength > 0 : warn that no m/z or int arrays is present
647  if (default_arr_length != 0)
648  {
649  warning(LOAD, String("The m/z or intensity array of chromatogram '") + inp_chromatogram.getNativeID() + "' is missing and default_arr_length is " + default_arr_length + ".");
650  }
651  return;
652  }
653 
654  //Warn if the decoded data has a different size than the defaultArrayLength
655  Size rt_size = rt_precision_64 ? input_data[rt_index].floats_64.size() : input_data[rt_index].floats_32.size();
656  if (default_arr_length != rt_size)
657  {
658  warning(LOAD, String("The base64-decoded rt array of chromatogram '") + inp_chromatogram.getNativeID() + "' has the size " + rt_size + ", but it should have size " + default_arr_length + " (defaultArrayLength).");
659  }
660  Size int_size = int_precision_64 ? input_data[int_index].floats_64.size() : input_data[int_index].floats_32.size();
661  if (default_arr_length != int_size)
662  {
663  warning(LOAD, String("The base64-decoded intensity array of chromatogram '") + inp_chromatogram.getNativeID() + "' has the size " + int_size + ", but it should have size " + default_arr_length + " (defaultArrayLength).");
664  }
665 
666  //create meta data arrays and reserve enough space for the content
667  if (input_data.size() > 2)
668  {
669  for (Size i = 0; i < input_data.size(); i++)
670  {
671  if (input_data[i].meta.getName() != "intensity array" && input_data[i].meta.getName() != "time array")
672  {
673  if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_FLOAT)
674  {
675  //create new array
676  inp_chromatogram.getFloatDataArrays().resize(inp_chromatogram.getFloatDataArrays().size() + 1);
677  //reserve space in the array
678  inp_chromatogram.getFloatDataArrays().back().reserve(input_data[i].size);
679  //copy meta info into MetaInfoDescription
680  inp_chromatogram.getFloatDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
681  }
682  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_INT)
683  {
684  //create new array
685  inp_chromatogram.getIntegerDataArrays().resize(inp_chromatogram.getIntegerDataArrays().size() + 1);
686  //reserve space in the array
687  inp_chromatogram.getIntegerDataArrays().back().reserve(input_data[i].size);
688  //copy meta info into MetaInfoDescription
689  inp_chromatogram.getIntegerDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
690  }
691  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_STRING)
692  {
693  //create new array
694  inp_chromatogram.getStringDataArrays().resize(inp_chromatogram.getStringDataArrays().size() + 1);
695  //reserve space in the array
696  inp_chromatogram.getStringDataArrays().back().reserve(input_data[i].decoded_char.size());
697  //copy meta info into MetaInfoDescription
698  inp_chromatogram.getStringDataArrays().back().MetaInfoDescription::operator=(input_data[i].meta);
699  }
700  }
701  }
702  }
703 
704  //copy meta data from time and intensity binary
705  //We don't have this as a separate location => store it in spectrum
706  for (Size i = 0; i < input_data.size(); i++)
707  {
708  if (input_data[i].meta.getName() == "time array" || input_data[i].meta.getName() == "intensity array")
709  {
710  std::vector<UInt> keys;
711  input_data[i].meta.getKeys(keys);
712  for (Size k = 0; k < keys.size(); ++k)
713  {
714  inp_chromatogram.setMetaValue(keys[k], input_data[i].meta.getMetaValue(keys[k]));
715  }
716  }
717  }
718 
719  //add the peaks and the meta data to the container (if they pass the restrictions)
720  inp_chromatogram.reserve(default_arr_length);
721  ChromatogramPeakType tmp;
722  for (Size n = 0; n < default_arr_length; n++)
723  {
724  double rt = rt_precision_64 ? input_data[rt_index].floats_64[n] : input_data[rt_index].floats_32[n];
725  double intensity = int_precision_64 ? input_data[int_index].floats_64[n] : input_data[int_index].floats_32[n];
726  if ((!peak_file_options.hasRTRange() || peak_file_options.getRTRange().encloses(DPosition<1>(rt)))
727  && (!peak_file_options.hasIntensityRange() || peak_file_options.getIntensityRange().encloses(DPosition<1>(intensity))))
728  {
729  //add peak
730  tmp.setIntensity(intensity);
731  tmp.setRT(rt);
732  inp_chromatogram.push_back(tmp);
733 
734  //add meta data
735  UInt meta_float_array_index = 0;
736  UInt meta_int_array_index = 0;
737  UInt meta_string_array_index = 0;
738  for (Size i = 0; i < input_data.size(); i++) //loop over all binary data arrays
739  {
740  if (input_data[i].meta.getName() != "intensity array" && input_data[i].meta.getName() != "time array") // is meta data array?
741  {
742  if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_FLOAT)
743  {
744  if (n < input_data[i].size)
745  {
746  double value = (input_data[i].precision == MzMLHandlerHelper::BinaryData::PRE_64) ? input_data[i].floats_64[n] : input_data[i].floats_32[n];
747  inp_chromatogram.getFloatDataArrays()[meta_float_array_index].push_back(value);
748  }
749  ++meta_float_array_index;
750  }
751  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_INT)
752  {
753  if (n < input_data[i].size)
754  {
755  Int64 value = (input_data[i].precision == MzMLHandlerHelper::BinaryData::PRE_64) ? input_data[i].ints_64[n] : input_data[i].ints_32[n];
756  inp_chromatogram.getIntegerDataArrays()[meta_int_array_index].push_back(value);
757  }
758  ++meta_int_array_index;
759  }
760  else if (input_data[i].data_type == MzMLHandlerHelper::BinaryData::DT_STRING)
761  {
762  if (n < input_data[i].decoded_char.size())
763  {
764  String value = input_data[i].decoded_char[n];
765  inp_chromatogram.getStringDataArrays()[meta_string_array_index].push_back(value);
766  }
767  ++meta_string_array_index;
768  }
769  }
770  }
771  }
772  }
773  }
774 
775  template <typename DataType>
776  void writeBinaryDataArray(std::ostream& os, const PeakFileOptions& pf_options_, std::vector<DataType> data_to_encode, bool is32bit, String array_type)
777  {
778  String encoded_string;
779  bool no_numpress = true;
780 
781  // Compute the array-type and the compression CV term
782  String cv_term_type;
783  String compression_term;
784  String compression_term_no_np;
786  if (array_type == "mz")
787  {
788  cv_term_type = "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000514\" name=\"m/z array\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
789  compression_term = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationMassTime(), true);
790  compression_term_no_np = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationMassTime(), false);
791  np_config = pf_options_.getNumpressConfigurationMassTime();
792  }
793  else if (array_type == "time")
794  {
795  cv_term_type = "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000595\" name=\"time array\" unitAccession=\"UO:0000010\" unitName=\"second\" unitCvRef=\"MS\" />\n";
796  compression_term = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationMassTime(), true);
797  compression_term_no_np = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationMassTime(), false);
798  np_config = pf_options_.getNumpressConfigurationMassTime();
799  }
800  else if (array_type == "intensity")
801  {
802  cv_term_type = "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000515\" name=\"intensity array\" unitAccession=\"MS:1000131\" unitName=\"number of detector counts\" unitCvRef=\"MS\"/>\n";
803  compression_term = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationIntensity(), true);
804  compression_term_no_np = MzMLHandlerHelper::getCompressionTerm_(pf_options_, pf_options_.getNumpressConfigurationIntensity(), false);
805  np_config = pf_options_.getNumpressConfigurationIntensity();
806  }
807  else
808  {
809  throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Unknown array type", array_type);
810  }
811 
812  // Try numpress encoding (if it is enabled) and fall back to regular encoding if it fails
813  if (np_config.np_compression != MSNumpressCoder::NONE)
814  {
815  MSNumpressCoder().encodeNP(data_to_encode, encoded_string, pf_options_.getCompression(), np_config);
816  if (!encoded_string.empty())
817  {
818  // numpress succeeded
819  no_numpress = false;
820  os << "\t\t\t\t\t<binaryDataArray encodedLength=\"" << encoded_string.size() << "\">\n";
821  os << cv_term_type;
822  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000523\" name=\"64-bit float\" />\n";
823  }
824  }
825 
826  // Regular DataArray without numpress (either 32 or 64 bit encoded)
827  if (is32bit && no_numpress)
828  {
829  compression_term = compression_term_no_np; // select the no-numpress term
830  decoder_.encode(data_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, pf_options_.getCompression());
831  os << "\t\t\t\t\t<binaryDataArray encodedLength=\"" << encoded_string.size() << "\">\n";
832  os << cv_term_type;
833  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000521\" name=\"32-bit float\" />\n";
834  }
835  else if (!is32bit && no_numpress)
836  {
837  compression_term = compression_term_no_np; // select the no-numpress term
838  decoder_.encode(data_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, pf_options_.getCompression());
839  os << "\t\t\t\t\t<binaryDataArray encodedLength=\"" << encoded_string.size() << "\">\n";
840  os << cv_term_type;
841  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000523\" name=\"64-bit float\" />\n";
842  }
843 
844  os << "\t\t\t\t\t\t" << compression_term << "\n";
845  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
846  os << "\t\t\t\t\t</binaryDataArray>\n";
847  }
848 
849  void writeHeader_(std::ostream& os, const MapType& exp, std::vector<std::vector<DataProcessing> >& dps, Internal::MzMLValidator& validator);
850 
854  const MapType* cexp_;
855 
858 
861  SpectrumType spec_;
864  ChromatogramType chromatogram_;
866  std::vector<BinaryData> data_;
887 
896  {
897  std::vector<BinaryData> data;
899  SpectrumType spectrum;
900  bool skip_data;
901  };
902 
904  std::vector<SpectrumData> spectrum_data_;
905 
914  {
915  std::vector<BinaryData> data;
917  ChromatogramType chromatogram;
918  };
919 
921  std::vector<ChromatogramData> chromatogram_data_;
922 
924 
926  std::vector<std::pair<std::string, long> > spectra_offsets;
927  std::vector<std::pair<std::string, long> > chromatograms_offsets;
929 
932 
935 
938 
942 
946 
947  // Remember whether the RT of the spectrum was set or not
948  bool rt_set_;
949 
953  //~ Internal::MzMLValidator validator_;
954 
957 
958  /*
960  void fillData_();
961  */
962 
964  void fillChromatogramData_();
965 
967  void handleCVParam_(const String& parent_parent_tag, const String& parent_tag, /* const String & cvref, */ const String& accession, const String& name, const String& value, const String& unit_accession = "");
968 
970  void handleUserParam_(const String& parent_parent_tag, const String& parent_tag, const String& name, const String& type, const String& value);
971 
973  void writeUserParam_(std::ostream& os, const MetaInfoInterface& meta, UInt indent, String path, Internal::MzMLValidator& validator) const;
974 
976  ControlledVocabulary::CVTerm getChildWithName_(const String& parent_accession, const String& name) const;
977 
979  void writeSoftware_(std::ostream& os, const String& id, const Software& software, Internal::MzMLValidator& validator);
980 
982  void writeSourceFile_(std::ostream& os, const String& id, const SourceFile& software, Internal::MzMLValidator& validator);
983 
985  void writeDataProcessing_(std::ostream& os, const String& id, const std::vector<DataProcessing>& dps, Internal::MzMLValidator& validator);
986 
988  void writePrecursor_(std::ostream& os, const Precursor& precursor, Internal::MzMLValidator& validator);
989 
991  void writeProduct_(std::ostream& os, const Product& product, Internal::MzMLValidator& validator);
992 
994  String writeCV_(const ControlledVocabulary::CVTerm& c, const DataValue& metaValue) const;
995 
997  bool validateCV_(const ControlledVocabulary::CVTerm& c, const String& path, const Internal::MzMLValidator& validator) const;
998  };
999 
1000  //--------------------------------------------------------------------------------
1001 
1002  template <typename MapType>
1003  void MzMLHandler<MapType>::characters(const XMLCh* const chars, const XMLSize_t length)
1004  {
1005 
1006  if (skip_spectrum_ || skip_chromatogram_)
1007  return;
1008 
1009  String& current_tag = open_tags_.back();
1010 
1011  if (current_tag == "binary")
1012  {
1013  // Since we convert a Base64 string here, it can only contain plain ASCII
1014  sm_.appendASCII(chars, length, data_.back().base64);
1015  }
1016  else if (current_tag == "offset" || current_tag == "indexListOffset" || current_tag == "fileChecksum")
1017  {
1018  //do nothing for
1019  // - index
1020  // - checksum
1021  // - binary chromatogram data
1022  }
1023  else
1024  {
1025  char* transcoded_chars = sm_.convert(chars);
1026  String transcoded_chars2 = transcoded_chars;
1027  transcoded_chars2.trim();
1028  if (transcoded_chars2 != "")
1029  warning(LOAD, String("Unhandled character content in tag '") + current_tag + "': " + transcoded_chars2);
1030  }
1031  }
1032 
1033  template <typename MapType>
1034  void MzMLHandler<MapType>::startElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname, const xercesc::Attributes& attributes)
1035  {
1036  static const XMLCh* s_count = xercesc::XMLString::transcode("count");
1037  static const XMLCh* s_default_array_length = xercesc::XMLString::transcode("defaultArrayLength");
1038  static const XMLCh* s_array_length = xercesc::XMLString::transcode("arrayLength");
1039  static const XMLCh* s_accession = xercesc::XMLString::transcode("accession");
1040  static const XMLCh* s_name = xercesc::XMLString::transcode("name");
1041  static const XMLCh* s_type = xercesc::XMLString::transcode("type");
1042  static const XMLCh* s_value = xercesc::XMLString::transcode("value");
1043  static const XMLCh* s_unit_accession = xercesc::XMLString::transcode("unitAccession");
1044  static const XMLCh* s_id = xercesc::XMLString::transcode("id");
1045  static const XMLCh* s_spot_id = xercesc::XMLString::transcode("spotID");
1046  //~ static const XMLCh * s_cvref = xercesc::XMLString::transcode("cvRef"); TODO
1047  static const XMLCh* s_ref = xercesc::XMLString::transcode("ref");
1048  static const XMLCh* s_version = xercesc::XMLString::transcode("version");
1049  static const XMLCh* s_order = xercesc::XMLString::transcode("order");
1050  static const XMLCh* s_location = xercesc::XMLString::transcode("location");
1051  static const XMLCh* s_sample_ref = xercesc::XMLString::transcode("sampleRef");
1052  static const XMLCh* s_software_ref = xercesc::XMLString::transcode("softwareRef");
1053  static const XMLCh* s_source_file_ref = xercesc::XMLString::transcode("sourceFileRef");
1054  static const XMLCh* s_default_instrument_configuration_ref = xercesc::XMLString::transcode("defaultInstrumentConfigurationRef");
1055  static const XMLCh* s_instrument_configuration_ref = xercesc::XMLString::transcode("instrumentConfigurationRef");
1056  static const XMLCh* s_default_data_processing_ref = xercesc::XMLString::transcode("defaultDataProcessingRef");
1057  static const XMLCh* s_data_processing_ref = xercesc::XMLString::transcode("dataProcessingRef");
1058  static const XMLCh* s_start_time_stamp = xercesc::XMLString::transcode("startTimeStamp");
1059  static const XMLCh* s_external_spectrum_id = xercesc::XMLString::transcode("externalSpectrumID");
1060  static const XMLCh* s_default_source_file_ref = xercesc::XMLString::transcode("defaultSourceFileRef");
1061  static const XMLCh* s_scan_settings_ref = xercesc::XMLString::transcode("scanSettingsRef");
1062 
1063  String tag = sm_.convert(qname);
1064  open_tags_.push_back(tag);
1065 
1066  //determine parent tag
1067  String parent_tag;
1068  if (open_tags_.size() > 1)
1069  parent_tag = *(open_tags_.end() - 2);
1070  String parent_parent_tag;
1071  if (open_tags_.size() > 2)
1072  parent_parent_tag = *(open_tags_.end() - 3);
1073 
1074  //do nothing until a new spectrum is reached
1075  if (tag != "spectrum" && skip_spectrum_)
1076  return;
1077 
1078  if (tag != "chromatogram" && skip_chromatogram_)
1079  return;
1080 
1081  if (tag == "spectrum")
1082  {
1083  //number of peaks
1084  spec_ = SpectrumType();
1085  default_array_length_ = attributeAsInt_(attributes, s_default_array_length);
1086  //spectrum source file
1087  String source_file_ref;
1088  if (optionalAttributeAsString_(source_file_ref, attributes, s_source_file_ref))
1089  {
1090  spec_.setSourceFile(source_files_[source_file_ref]);
1091  }
1092  //native id
1093  spec_.setNativeID(attributeAsString_(attributes, s_id));
1094  //maldi spot id
1095  String maldi_spot_id;
1096  if (optionalAttributeAsString_(maldi_spot_id, attributes, s_spot_id))
1097  {
1098  spec_.setMetaValue("maldi_spot_id", maldi_spot_id);
1099  }
1100  //data processing
1101  String data_processing_ref;
1102  if (optionalAttributeAsString_(data_processing_ref, attributes, s_data_processing_ref))
1103  {
1104  spec_.setDataProcessing(processing_[data_processing_ref]);
1105  }
1106  else
1107  {
1108  spec_.setDataProcessing(processing_[default_processing_]);
1109  }
1110  }
1111  else if (tag == "chromatogram")
1112  {
1113  chromatogram_ = ChromatogramType();
1114  default_array_length_ = attributeAsInt_(attributes, s_default_array_length);
1115  String source_file_ref;
1116  if (optionalAttributeAsString_(source_file_ref, attributes, s_source_file_ref))
1117  {
1118  chromatogram_.setSourceFile(source_files_[source_file_ref]);
1119  }
1120  // native id
1121  chromatogram_.setNativeID(attributeAsString_(attributes, s_id));
1122  // data processing
1123  String data_processing_ref;
1124  if (optionalAttributeAsString_(data_processing_ref, attributes, s_data_processing_ref))
1125  {
1126  chromatogram_.setDataProcessing(processing_[data_processing_ref]);
1127  }
1128  else
1129  {
1130  chromatogram_.setDataProcessing(processing_[default_processing_]);
1131  }
1132  }
1133  else if (tag == "spectrumList")
1134  {
1135  //default data processing
1136  default_processing_ = attributeAsString_(attributes, s_default_data_processing_ref);
1137 
1138  //Abort if we need meta data only
1139  if (options_.getMetadataOnly())
1140  throw EndParsingSoftly(__FILE__, __LINE__, __PRETTY_FUNCTION__);
1141 
1142  UInt count = attributeAsInt_(attributes, s_count);
1143  exp_->reserveSpaceSpectra(count);
1144  logger_.startProgress(0, count, "loading spectra list");
1145  in_spectrum_list_ = true;
1146  }
1147  else if (tag == "chromatogramList")
1148  {
1149  // default data processing
1150  default_processing_ = attributeAsString_(attributes, s_default_data_processing_ref);
1151 
1152  //Abort if we need meta data only
1153  if (options_.getMetadataOnly())
1154  throw EndParsingSoftly(__FILE__, __LINE__, __PRETTY_FUNCTION__);
1155 
1156  UInt count = attributeAsInt_(attributes, s_count);
1157  exp_->reserveSpaceChromatograms(count);
1158  logger_.startProgress(0, count, "loading chromatogram list");
1159  in_spectrum_list_ = false;
1160  }
1161  else if (tag == "binaryDataArrayList" /* && in_spectrum_list_*/)
1162  {
1163  data_.reserve(attributeAsInt_(attributes, s_count));
1164  }
1165  else if (tag == "binaryDataArray" /* && in_spectrum_list_*/)
1166  {
1167  data_.push_back(BinaryData());
1168  data_.back().np_compression = MSNumpressCoder::NONE; // ensure that numpress compression is initially set to none ...
1169  data_.back().compression = false; // ensure that zlib compression is initially set to none ...
1170 
1171  //array length
1172  Int array_length = (Int) default_array_length_;
1173  optionalAttributeAsInt_(array_length, attributes, s_array_length);
1174  data_.back().size = array_length;
1175 
1176  //data processing
1177  String data_processing_ref;
1178  if (optionalAttributeAsString_(data_processing_ref, attributes, s_data_processing_ref))
1179  {
1180  data_.back().meta.setDataProcessing(processing_[data_processing_ref]);
1181  }
1182  }
1183  else if (tag == "cvParam")
1184  {
1185  String value = "";
1186  optionalAttributeAsString_(value, attributes, s_value);
1187  String unit_accession = "";
1188  optionalAttributeAsString_(unit_accession, attributes, s_unit_accession);
1189  handleCVParam_(parent_parent_tag, parent_tag, /* attributeAsString_(attributes, s_cvref), */ attributeAsString_(attributes, s_accession), attributeAsString_(attributes, s_name), value, unit_accession);
1190  }
1191  else if (tag == "userParam")
1192  {
1193  String type = "";
1194  optionalAttributeAsString_(type, attributes, s_type);
1195  String value = "";
1196  optionalAttributeAsString_(value, attributes, s_value);
1197  handleUserParam_(parent_parent_tag, parent_tag, attributeAsString_(attributes, s_name), type, value);
1198  }
1199  else if (tag == "referenceableParamGroup")
1200  {
1201  current_id_ = attributeAsString_(attributes, s_id);
1202  }
1203  else if (tag == "sourceFile")
1204  {
1205  current_id_ = attributeAsString_(attributes, s_id);
1206  source_files_[current_id_].setNameOfFile(attributeAsString_(attributes, s_name));
1207  source_files_[current_id_].setPathToFile(attributeAsString_(attributes, s_location));
1208  }
1209  else if (tag == "referenceableParamGroupRef")
1210  {
1211  //call handleCVParam_ with the parent tag for each parameter in the group
1212  String ref = attributeAsString_(attributes, s_ref);
1213  for (Size i = 0; i < ref_param_[ref].size(); ++i)
1214  {
1215  handleCVParam_(parent_parent_tag, parent_tag, /* attributeAsString_(attributes, s_cvref), */ ref_param_[ref][i].accession, ref_param_[ref][i].name, ref_param_[ref][i].value, ref_param_[ref][i].unit_accession);
1216  }
1217  }
1218  else if (tag == "scan")
1219  {
1220  Acquisition tmp;
1221  //source file => meta data
1222  String source_file_ref;
1223  if (optionalAttributeAsString_(source_file_ref, attributes, s_source_file_ref))
1224  {
1225  tmp.setMetaValue("source_file_name", source_files_[source_file_ref].getNameOfFile());
1226  tmp.setMetaValue("source_file_path", source_files_[source_file_ref].getPathToFile());
1227  }
1228  //external spectrum id => meta data
1229  String external_spectrum_id;
1230  if (optionalAttributeAsString_(external_spectrum_id, attributes, s_external_spectrum_id))
1231  {
1232  tmp.setIdentifier(external_spectrum_id);
1233  }
1234 
1235  //spectrumRef - not really needed
1236 
1237  //instrumentConfigurationRef - not really needed: why should a scan have a different instrument?
1238  String instrument_configuration_ref;
1239  if (optionalAttributeAsString_(instrument_configuration_ref, attributes, s_instrument_configuration_ref))
1240  {
1241  warning(LOAD, "Unhandled attribute 'instrumentConfigurationRef' in 'scan' tag.");
1242  }
1243 
1244  spec_.getAcquisitionInfo().push_back(tmp);
1245  }
1246  else if (tag == "mzML")
1247  {
1248  scan_count = 0;
1249  chromatogram_count = 0;
1250 
1251  //check file version against schema version
1252  String file_version = attributeAsString_(attributes, s_version);
1253 
1254  VersionInfo::VersionDetails current_version = VersionInfo::VersionDetails::create(file_version);
1255  static VersionInfo::VersionDetails mzML_min_version = VersionInfo::VersionDetails::create("1.1.0");
1256 
1257  if (current_version == VersionInfo::VersionDetails::EMPTY)
1258  {
1259  warning(LOAD, String("Invalid mzML version string '") + file_version + "'. Assuming mzML version " + version_ + "!");
1260  }
1261  else
1262  {
1263  if (current_version < mzML_min_version)
1264  {
1265  fatalError(LOAD, String("Only mzML 1.1.0 or higher is supported! This file has version '") + file_version + "'.");
1266  }
1267  else if (current_version > VersionInfo::VersionDetails::create(version_))
1268  {
1269  warning(LOAD, "The mzML file version (" + file_version + ") is newer than the parser version (" + version_ + "). This might lead to undefined behavior.");
1270  }
1271  }
1272 
1273  //handle file accession
1274  String accession;
1275  if (optionalAttributeAsString_(accession, attributes, s_accession))
1276  {
1277  exp_->setIdentifier(accession);
1278  }
1279  //handle file id
1280  String id;
1281  if (optionalAttributeAsString_(id, attributes, s_id))
1282  {
1283  exp_->setMetaValue("mzml_id", id);
1284  }
1285  }
1286  else if (tag == "contact")
1287  {
1288  exp_->getContacts().push_back(ContactPerson());
1289  }
1290  else if (tag == "sample")
1291  {
1292  current_id_ = attributeAsString_(attributes, s_id);
1293  String name;
1294  if (optionalAttributeAsString_(name, attributes, s_name))
1295  {
1296  samples_[current_id_].setName(name);
1297  }
1298  }
1299  else if (tag == "run")
1300  {
1301  //sample
1302  String sample_ref;
1303  if (optionalAttributeAsString_(sample_ref, attributes, s_sample_ref))
1304  {
1305  exp_->setSample(samples_[sample_ref]);
1306  }
1307  //instrument
1308  String instrument_ref = attributeAsString_(attributes, s_default_instrument_configuration_ref);
1309  exp_->setInstrument(instruments_[instrument_ref]);
1310  //start time
1311  String start_time;
1312  if (optionalAttributeAsString_(start_time, attributes, s_start_time_stamp))
1313  {
1314  exp_->setDateTime(asDateTime_(start_time));
1315  }
1316  //defaultSourceFileRef
1317  String default_source_file_ref;
1318  if (optionalAttributeAsString_(default_source_file_ref, attributes, s_default_source_file_ref))
1319  {
1320  exp_->getSourceFiles().push_back(source_files_[default_source_file_ref]);
1321  }
1322  }
1323  else if (tag == "software")
1324  {
1325  current_id_ = attributeAsString_(attributes, s_id);
1326  software_[current_id_].setVersion(attributeAsString_(attributes, s_version));
1327  }
1328  else if (tag == "dataProcessing")
1329  {
1330  current_id_ = attributeAsString_(attributes, s_id);
1331  }
1332  else if (tag == "processingMethod")
1333  {
1334  DataProcessing dp;
1335  // See ticket 452: Do NOT remove this try/catch block until foreign
1336  // software (e.g. ProteoWizard msconvert.exe) produces valid mzML.
1337  try
1338  {
1339  dp.setSoftware(software_[attributeAsString_(attributes, s_software_ref)]);
1340  }
1341  catch (Exception::ParseError& /*e*/)
1342  {
1343  LOG_ERROR << "Warning: Parsing error, \"processingMethod\" is missing the required attribute \"softwareRef\".\n" <<
1344  "The software tool which generated this mzML should be fixed. Please notify the maintainers." << std::endl;
1345  }
1346  processing_[current_id_].push_back(dp);
1347  //The order of processing methods is currently ignored
1348  }
1349  else if (tag == "instrumentConfiguration")
1350  {
1351  current_id_ = attributeAsString_(attributes, s_id);
1352 
1353  //scan settings
1354  String scan_settings_ref;
1355  if (optionalAttributeAsString_(scan_settings_ref, attributes, s_scan_settings_ref))
1356  {
1357  warning(LOAD, "Unhandled attribute 'scanSettingsRef' in 'instrumentConfiguration' tag.");
1358  }
1359  }
1360  else if (tag == "softwareRef")
1361  {
1362  //Set the software of the instrument
1363  instruments_[current_id_].setSoftware(software_[attributeAsString_(attributes, s_ref)]);
1364  }
1365  else if (tag == "source")
1366  {
1367  instruments_[current_id_].getIonSources().push_back(IonSource());
1368  instruments_[current_id_].getIonSources().back().setOrder(attributeAsInt_(attributes, s_order));
1369  }
1370  else if (tag == "analyzer")
1371  {
1372  instruments_[current_id_].getMassAnalyzers().push_back(MassAnalyzer());
1373  instruments_[current_id_].getMassAnalyzers().back().setOrder(attributeAsInt_(attributes, s_order));
1374  }
1375  else if (tag == "detector")
1376  {
1377  instruments_[current_id_].getIonDetectors().push_back(IonDetector());
1378  instruments_[current_id_].getIonDetectors().back().setOrder(attributeAsInt_(attributes, s_order));
1379  }
1380  else if (tag == "precursor")
1381  {
1382  if (in_spectrum_list_)
1383  {
1384  //initialize
1385  spec_.getPrecursors().push_back(Precursor());
1386 
1387  //source file => meta data
1388  String source_file_ref;
1389  if (optionalAttributeAsString_(source_file_ref, attributes, s_source_file_ref))
1390  {
1391  spec_.getPrecursors().back().setMetaValue("source_file_name", source_files_[source_file_ref].getNameOfFile());
1392  spec_.getPrecursors().back().setMetaValue("source_file_path", source_files_[source_file_ref].getPathToFile());
1393  }
1394  //external spectrum id => meta data
1395  String external_spectrum_id;
1396  if (optionalAttributeAsString_(external_spectrum_id, attributes, s_external_spectrum_id))
1397  {
1398  spec_.getPrecursors().back().setMetaValue("external_spectrum_id", external_spectrum_id);
1399  }
1400  //reset selected ion count
1401  selected_ion_count_ = 0;
1402  }
1403  else
1404  {
1405  chromatogram_.setPrecursor(Precursor());
1406 
1407  String source_file_ref;
1408  if (optionalAttributeAsString_(source_file_ref, attributes, s_source_file_ref))
1409  {
1410  chromatogram_.getPrecursor().setMetaValue("source_file_name", source_files_[source_file_ref].getNameOfFile());
1411  chromatogram_.getPrecursor().setMetaValue("source_file_path", source_files_[source_file_ref].getPathToFile());
1412  }
1413 
1414  String external_spectrum_id;
1415  if (optionalAttributeAsString_(external_spectrum_id, attributes, s_external_spectrum_id))
1416  {
1417  chromatogram_.getPrecursor().setMetaValue("external_spectrum_id", external_spectrum_id);
1418  }
1419  selected_ion_count_ = 0;
1420  }
1421  }
1422  else if (tag == "product")
1423  {
1424  //initialize
1425  if (in_spectrum_list_)
1426  {
1427  spec_.getProducts().push_back(Product());
1428  }
1429  else
1430  {
1431  chromatogram_.setProduct(Product());
1432  }
1433  }
1434  else if (tag == "selectedIon")
1435  {
1436  //increase selected ion count
1437  ++selected_ion_count_;
1438  }
1439  else if (tag == "selectedIonList")
1440  {
1441  //Warn if more than one selected ion is present
1442  if (attributeAsInt_(attributes, s_count) > 1)
1443  {
1444  warning(LOAD, "OpenMS can currently handle only one selection ion per precursor! Only the first ion is loaded!");
1445  }
1446  }
1447  else if (tag == "scanWindow")
1448  {
1449  spec_.getInstrumentSettings().getScanWindows().push_back(ScanWindow());
1450  }
1451  }
1452 
1453  template <typename MapType>
1454  void MzMLHandler<MapType>::endElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname)
1455  {
1456  static const XMLCh* s_spectrum = xercesc::XMLString::transcode("spectrum");
1457  static const XMLCh* s_chromatogram = xercesc::XMLString::transcode("chromatogram");
1458  static const XMLCh* s_spectrum_list = xercesc::XMLString::transcode("spectrumList");
1459  static const XMLCh* s_chromatogram_list = xercesc::XMLString::transcode("chromatogramList");
1460  static const XMLCh* s_mzml = xercesc::XMLString::transcode("mzML");
1461 
1462  open_tags_.pop_back();
1463 
1464  if (equal_(qname, s_spectrum))
1465  {
1466 
1467  // catch errors stemming from confusion about elution time and scan time
1468  if (!rt_set_ && spec_.metaValueExists("elution time (seconds)"))
1469  {
1470  spec_.setRT(spec_.getMetaValue("elution time (seconds)"));
1471  }
1472  /* this is too hot (could be SRM as well? -- check!):
1473  // correct spectrum type if possible (i.e., make it more specific)
1474  if (spec_.getInstrumentSettings().getScanMode() == InstrumentSettings::MASSSPECTRUM)
1475  {
1476  if (spec_.getMSLevel() <= 1) spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MS1SPECTRUM);
1477  else spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MSNSPECTRUM);
1478  }
1479  */
1480 
1481  if (!skip_spectrum_)
1482  {
1483  spectrum_data_.push_back(SpectrumData());
1484  spectrum_data_.back().default_array_length = default_array_length_;
1485  spectrum_data_.back().spectrum = spec_;
1486  if (options_.getFillData())
1487  {
1488  spectrum_data_.back().data = data_;
1489  }
1490  }
1491 
1492  if (spectrum_data_.size() >= options_.getMaxDataPoolSize())
1493  {
1494  populateSpectraWithData();
1495  }
1496 
1497  skip_spectrum_ = false;
1498  rt_set_ = false;
1499  if (options_.getSizeOnly()) {skip_spectrum_ = true; }
1500  logger_.setProgress(++scan_count);
1501  data_.clear();
1502  default_array_length_ = 0;
1503  }
1504  else if (equal_(qname, s_chromatogram))
1505  {
1506 
1507  if (!skip_chromatogram_)
1508  {
1509  chromatogram_data_.push_back(ChromatogramData());
1510  chromatogram_data_.back().default_array_length = default_array_length_;
1511  chromatogram_data_.back().chromatogram = chromatogram_;
1512  if (options_.getFillData())
1513  {
1514  chromatogram_data_.back().data = data_;
1515  }
1516  }
1517 
1518  if (chromatogram_data_.size() >= options_.getMaxDataPoolSize())
1519  {
1520  populateChromatogramsWithData();
1521  }
1522 
1523  skip_chromatogram_ = false;
1524  if (options_.getSizeOnly()) {skip_chromatogram_ = true; }
1525  logger_.setProgress(++chromatogram_count);
1526  data_.clear();
1527  default_array_length_ = 0;
1528  }
1529  else if (equal_(qname, s_spectrum_list))
1530  {
1531  in_spectrum_list_ = false;
1532  logger_.endProgress();
1533  }
1534  else if (equal_(qname, s_chromatogram_list))
1535  {
1536  in_spectrum_list_ = false;
1537  logger_.endProgress();
1538  }
1539  else if (equal_(qname, s_mzml))
1540  {
1541  ref_param_.clear();
1542  current_id_ = "";
1543  source_files_.clear();
1544  samples_.clear();
1545  software_.clear();
1546  instruments_.clear();
1547  processing_.clear();
1548 
1549  // Flush the remaining data
1550  populateSpectraWithData();
1551  populateChromatogramsWithData();
1552  }
1553 
1554  sm_.clear();
1555  }
1556 
1557  template <typename MapType>
1558  void MzMLHandler<MapType>::handleCVParam_(const String& parent_parent_tag, const String& parent_tag, /* const String & cvref, */ const String& accession, const String& name, const String& value, const String& unit_accession)
1559  {
1560  // the actual value stored in the CVParam
1561  // we assume for now that it is a string value, we update the type later on
1562  DataValue termValue = value;
1563 
1564  //Abort on unknown terms
1565  if (!cv_.exists(accession))
1566  {
1567  //in 'sample' several external CVs are used (Brenda, GO, ...). Do not warn then.
1568  if (parent_tag != "sample")
1569  {
1570  warning(LOAD, String("Unknown cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1571  return;
1572  }
1573  }
1574  else
1575  {
1576  const ControlledVocabulary::CVTerm& term = cv_.getTerm(accession);
1577 
1578  //obsolete CV terms
1579  if (term.obsolete)
1580  {
1581  warning(LOAD, String("Obsolete CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "'.");
1582  }
1583  //check if term name and parsed name match
1584  String parsed_name = name;
1585  parsed_name.trim();
1586  String correct_name = term.name;
1587  correct_name.trim();
1588  if (parsed_name != correct_name)
1589  {
1590  warning(LOAD, String("Name of CV term not correct: '") + term.id + " - " + parsed_name + "' should be '" + correct_name + "'");
1591  }
1592  if (term.obsolete)
1593  {
1594  warning(LOAD, String("Obsolete CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "'.");
1595  }
1596  //values used in wrong places and wrong value types
1597  if (value != "")
1598  {
1600  {
1601  //Quality CV does not state value type :(
1602  if (!accession.hasPrefix("PATO:"))
1603  {
1604  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' must not have a value. The value is '" + value + "'.");
1605  }
1606  }
1607  else
1608  {
1609  switch (term.xref_type)
1610  {
1611  //string value can be anything
1613  break;
1614 
1615  //int value => try casting
1621  try
1622  {
1623  termValue = value.toInt();
1624  }
1626  {
1627  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' must have an integer value. The value is '" + value + "'.");
1628  return;
1629  }
1630  break;
1631 
1632  //double value => try casting
1634  try
1635  {
1636  termValue = value.toDouble();
1637  }
1639  {
1640  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' must have a floating-point value. The value is '" + value + "'.");
1641  return;
1642  }
1643  break;
1644 
1645  //date string => try conversion
1647  try
1648  {
1649  DateTime tmp;
1650  tmp.set(value);
1651  }
1652  catch (Exception::ParseError&)
1653  {
1654  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' must be a valid date. The value is '" + value + "'.");
1655  return;
1656  }
1657  break;
1658 
1659  default:
1660  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' has the unknown value type '" + ControlledVocabulary::CVTerm::getXRefTypeName(term.xref_type) + "'.");
1661  break;
1662  }
1663  }
1664  }
1665  //no value, although there should be a numerical value
1667  {
1668  warning(LOAD, String("The CV term '") + accession + " - " + term.name + "' used in tag '" + parent_tag + "' should have a numerical value. The value is '" + value + "'.");
1669  return;
1670  }
1671  }
1672 
1673  if (unit_accession != "") termValue.setUnit(unit_accession);
1674 
1675  //------------------------- run ----------------------------
1676  if (parent_tag == "run")
1677  {
1678  //MS:1000857 ! run attribute
1679  if (accession == "MS:1000858") //fraction identifier
1680  {
1681  exp_->setFractionIdentifier(value);
1682  }
1683  else
1684  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1685  }
1686  //------------------------- binaryDataArray ----------------------------
1687  else if (parent_tag == "binaryDataArray")
1688  {
1689  if (!MzMLHandlerHelper::handleBinaryDataArrayCVParam(data_, accession, value, name))
1690  {
1691  if (cv_.isChildOf(accession, "MS:1000513")) //other array names as string
1692  {
1693  data_.back().meta.setName(cv_.getTerm(accession).name);
1694  }
1695  else
1696  {
1697  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1698  }
1699  }
1700  }
1701  //------------------------- spectrum ----------------------------
1702  else if (parent_tag == "spectrum")
1703  {
1704  //spectrum type
1705  if (accession == "MS:1000294") //mass spectrum
1706  {
1707  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
1708  }
1709  else if (accession == "MS:1000579") //MS1 spectrum
1710  {
1711  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MS1SPECTRUM);
1712  }
1713  else if (accession == "MS:1000580") //MSn spectrum
1714  {
1715  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MSNSPECTRUM);
1716  }
1717  else if (accession == "MS:1000581") //CRM spectrum
1718  {
1719  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CRM);
1720  }
1721  else if (accession == "MS:1000582") //SIM spectrum
1722  {
1723  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SIM);
1724  }
1725  else if (accession == "MS:1000583") //SRM spectrum
1726  {
1727  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SRM);
1728  }
1729  else if (accession == "MS:1000804") //electromagnetic radiation spectrum
1730  {
1731  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::EMR);
1732  }
1733  else if (accession == "MS:1000805") //emission spectrum
1734  {
1735  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::EMISSION);
1736  }
1737  else if (accession == "MS:1000806") //absorption spectrum
1738  {
1739  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::ABSORBTION);
1740  }
1741  else if (accession == "MS:1000325") //constant neutral gain spectrum
1742  {
1743  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNG);
1744  }
1745  else if (accession == "MS:1000326") //constant neutral loss spectrum
1746  {
1747  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNL);
1748  }
1749  else if (accession == "MS:1000341") //precursor ion spectrum
1750  {
1751  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::PRECURSOR);
1752  }
1753  else if (accession == "MS:1000789") //enhanced multiply charged spectrum
1754  {
1755  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::EMC);
1756  }
1757  else if (accession == "MS:1000790") //time-delayed fragmentation spectrum
1758  {
1759  spec_.getInstrumentSettings().setScanMode(InstrumentSettings::TDF);
1760  }
1761  //spectrum representation
1762  else if (accession == "MS:1000127") //centroid spectrum
1763  {
1764  spec_.setType(SpectrumSettings::PEAKS);
1765  }
1766  else if (accession == "MS:1000128") //profile spectrum
1767  {
1768  spec_.setType(SpectrumSettings::RAWDATA);
1769  }
1770  else if (accession == "MS:1000525") //spectrum representation
1771  {
1772  spec_.setType(SpectrumSettings::UNKNOWN);
1773  }
1774  //spectrum attribute
1775  else if (accession == "MS:1000511") //ms level
1776  {
1777  spec_.setMSLevel(value.toInt());
1778 
1779  if (options_.hasMSLevels() && !options_.containsMSLevel(spec_.getMSLevel()))
1780  {
1781  skip_spectrum_ = true;
1782  }
1783  }
1784  else if (accession == "MS:1000497") //zoom scan
1785  {
1786  spec_.getInstrumentSettings().setZoomScan(true);
1787  }
1788  else if (accession == "MS:1000285") //total ion current
1789  {
1790  //No member => meta data
1791  spec_.setMetaValue("total ion current", termValue);
1792  }
1793  else if (accession == "MS:1000504") //base peak m/z
1794  {
1795  //No member => meta data
1796  spec_.setMetaValue("base peak m/z", termValue);
1797  }
1798  else if (accession == "MS:1000505") //base peak intensity
1799  {
1800  //No member => meta data
1801  spec_.setMetaValue("base peak intensity", termValue);
1802  }
1803  else if (accession == "MS:1000527") //highest observed m/z
1804  {
1805  //No member => meta data
1806  spec_.setMetaValue("highest observed m/z", termValue);
1807  }
1808  else if (accession == "MS:1000528") //lowest observed m/z
1809  {
1810  //No member => meta data
1811  spec_.setMetaValue("lowest observed m/z", termValue);
1812  }
1813  else if (accession == "MS:1000618") //highest observed wavelength
1814  {
1815  //No member => meta data
1816  spec_.setMetaValue("highest observed wavelength", termValue);
1817  }
1818  else if (accession == "MS:1000619") //lowest observed wavelength
1819  {
1820  //No member => meta data
1821  spec_.setMetaValue("lowest observed wavelength", termValue);
1822  }
1823  else if (accession == "MS:1000796") //spectrum title
1824  {
1825  //No member => meta data
1826  spec_.setMetaValue("spectrum title", termValue);
1827  }
1828  else if (accession == "MS:1000797") //peak list scans
1829  {
1830  //No member => meta data
1831  spec_.setMetaValue("peak list scans", termValue);
1832  }
1833  else if (accession == "MS:1000798") //peak list raw scans
1834  {
1835  //No member => meta data
1836  spec_.setMetaValue("peak list raw scans", termValue);
1837  }
1838  //scan polarity
1839  else if (accession == "MS:1000129") //negative scan
1840  {
1841  spec_.getInstrumentSettings().setPolarity(IonSource::NEGATIVE);
1842  }
1843  else if (accession == "MS:1000130") //positive scan
1844  {
1845  spec_.getInstrumentSettings().setPolarity(IonSource::POSITIVE);
1846  }
1847  else
1848  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1849  }
1850  //------------------------- scanWindow ----------------------------
1851  else if (parent_tag == "scanWindow")
1852  {
1853  if (accession == "MS:1000501") //scan window lower limit
1854  {
1855  spec_.getInstrumentSettings().getScanWindows().back().begin = value.toDouble();
1856  }
1857  else if (accession == "MS:1000500") //scan window upper limit
1858  {
1859  spec_.getInstrumentSettings().getScanWindows().back().end = value.toDouble();
1860  }
1861  else
1862  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1863  }
1864  //------------------------- referenceableParamGroup ----------------------------
1865  else if (parent_tag == "referenceableParamGroup")
1866  {
1868  term.accession = accession;
1869  term.name = name;
1870  term.value = value;
1871  term.unit_accession = unit_accession;
1872  ref_param_[current_id_].push_back(term);
1873  }
1874  //------------------------- selectedIon ----------------------------
1875  else if (parent_tag == "selectedIon")
1876  {
1877  //parse only the first selected ion
1878  if (selected_ion_count_ > 1)
1879  return;
1880 
1881  if (accession == "MS:1000744") //selected ion m/z
1882  {
1883  //this overwrites the m/z of the isolation window, as it is probably more accurate
1884  if (in_spectrum_list_)
1885  {
1886  spec_.getPrecursors().back().setMZ(value.toDouble());
1887  }
1888  else
1889  {
1890  chromatogram_.getPrecursor().setMZ(value.toDouble());
1891  }
1892  }
1893  else if (accession == "MS:1000041") //charge state
1894  {
1895  if (in_spectrum_list_)
1896  {
1897  spec_.getPrecursors().back().setCharge(value.toInt());
1898  }
1899  else
1900  {
1901  chromatogram_.getPrecursor().setCharge(value.toInt());
1902  }
1903  }
1904  else if (accession == "MS:1000042") //peak intensity
1905  {
1906  if (in_spectrum_list_)
1907  {
1908  spec_.getPrecursors().back().setIntensity(value.toDouble());
1909  }
1910  else
1911  {
1912  chromatogram_.getPrecursor().setIntensity(value.toDouble());
1913  }
1914  }
1915  else if (accession == "MS:1000633") //possible charge state
1916  {
1917  if (in_spectrum_list_)
1918  {
1919  spec_.getPrecursors().back().getPossibleChargeStates().push_back(value.toInt());
1920  }
1921  else
1922  {
1923  chromatogram_.getPrecursor().getPossibleChargeStates().push_back(value.toInt());
1924  }
1925  }
1926  else
1927  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
1928  }
1929  //------------------------- activation ----------------------------
1930  else if (parent_tag == "activation")
1931  {
1932  //precursor activation attribute
1933  if (in_spectrum_list_)
1934  {
1935  if (accession == "MS:1000245") //charge stripping
1936  {
1937  //No member => meta data
1938  spec_.getPrecursors().back().setMetaValue("charge stripping", String("true"));
1939  }
1940  else if (accession == "MS:1000045") //collision energy (ev)
1941  {
1942  //No member => meta data
1943  spec_.getPrecursors().back().setMetaValue("collision energy", termValue);
1944  }
1945  else if (accession == "MS:1000412") //buffer gas
1946  {
1947  //No member => meta data
1948  spec_.getPrecursors().back().setMetaValue("buffer gas", termValue);
1949  }
1950  else if (accession == "MS:1000419") //collision gas
1951  {
1952  //No member => meta data
1953  spec_.getPrecursors().back().setMetaValue("collision gas", termValue);
1954  }
1955  else if (accession == "MS:1000509") //activation energy (ev)
1956  {
1957  spec_.getPrecursors().back().setActivationEnergy(value.toDouble());
1958  }
1959  else if (accession == "MS:1000138") //percent collision energy
1960  {
1961  //No member => meta data
1962  spec_.getPrecursors().back().setMetaValue("percent collision energy", termValue);
1963  }
1964  else if (accession == "MS:1000869") //collision gas pressure
1965  {
1966  //No member => meta data
1967  spec_.getPrecursors().back().setMetaValue("collision gas pressure", termValue);
1968  }
1969  //dissociation method
1970  else if (accession == "MS:1000044") //dissociation method
1971  {
1972  //nothing to do here
1973  }
1974  else if (accession == "MS:1000133") //collision-induced dissociation
1975  {
1976  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::CID);
1977  }
1978  else if (accession == "MS:1000134") //plasma desorption
1979  {
1980  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::PD);
1981  }
1982  else if (accession == "MS:1000135") //post-source decay
1983  {
1984  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::PSD);
1985  }
1986  else if (accession == "MS:1000136") //surface-induced dissociation
1987  {
1988  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::SID);
1989  }
1990  else if (accession == "MS:1000242") //blackbody infrared radiative dissociation
1991  {
1992  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::BIRD);
1993  }
1994  else if (accession == "MS:1000250") //electron capture dissociation
1995  {
1996  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::ECD);
1997  }
1998  else if (accession == "MS:1000262") //infrared multiphoton dissociation
1999  {
2000  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::IMD);
2001  }
2002  else if (accession == "MS:1000282") //sustained off-resonance irradiation
2003  {
2004  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::SORI);
2005  }
2006  else if (accession == "MS:1000422") //high-energy collision-induced dissociation
2007  {
2008  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::HCID);
2009  }
2010  else if (accession == "MS:1000433") //low-energy collision-induced dissociation
2011  {
2012  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::LCID);
2013  }
2014  else if (accession == "MS:1000435") //photodissociation
2015  {
2016  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::PHD);
2017  }
2018  else if (accession == "MS:1000598") //electron transfer dissociation
2019  {
2020  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::ETD);
2021  }
2022  else if (accession == "MS:1000599") //pulsed q dissociation
2023  {
2024  spec_.getPrecursors().back().getActivationMethods().insert(Precursor::PQD);
2025  }
2026  else
2027  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2028  }
2029  else
2030  {
2031  if (accession == "MS:1000245") //charge stripping
2032  {
2033  //No member => meta data
2034  chromatogram_.getPrecursor().setMetaValue("charge stripping", String("true"));
2035  }
2036  else if (accession == "MS:1000045") //collision energy (ev)
2037  {
2038  //No member => meta data
2039  chromatogram_.getPrecursor().setMetaValue("collision energy", termValue);
2040  }
2041  else if (accession == "MS:1000412") //buffer gas
2042  {
2043  //No member => meta data
2044  chromatogram_.getPrecursor().setMetaValue("buffer gas", termValue);
2045  }
2046  else if (accession == "MS:1000419") //collision gas
2047  {
2048  //No member => meta data
2049  chromatogram_.getPrecursor().setMetaValue("collision gas", termValue);
2050  }
2051  else if (accession == "MS:1000509") //activation energy (ev)
2052  {
2053  chromatogram_.getPrecursor().setActivationEnergy(value.toDouble());
2054  }
2055  else if (accession == "MS:1000138") //percent collision energy
2056  {
2057  //No member => meta data
2058  chromatogram_.getPrecursor().setMetaValue("percent collision energy", termValue);
2059  }
2060  else if (accession == "MS:1000869") //collision gas pressure
2061  {
2062  //No member => meta data
2063  chromatogram_.getPrecursor().setMetaValue("collision gas pressure", termValue);
2064  }
2065  //dissociation method
2066  else if (accession == "MS:1000044") //dissociation method
2067  {
2068  //nothing to do here
2069  }
2070  else if (accession == "MS:1000133") //collision-induced dissociation
2071  {
2072  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::CID);
2073  }
2074  else if (accession == "MS:1000134") //plasma desorption
2075  {
2076  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::PD);
2077  }
2078  else if (accession == "MS:1000135") //post-source decay
2079  {
2080  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::PSD);
2081  }
2082  else if (accession == "MS:1000136") //surface-induced dissociation
2083  {
2084  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::SID);
2085  }
2086  else if (accession == "MS:1000242") //blackbody infrared radiative dissociation
2087  {
2088  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::BIRD);
2089  }
2090  else if (accession == "MS:1000250") //electron capture dissociation
2091  {
2092  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::ECD);
2093  }
2094  else if (accession == "MS:1000262") //infrared multiphoton dissociation
2095  {
2096  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::IMD);
2097  }
2098  else if (accession == "MS:1000282") //sustained off-resonance irradiation
2099  {
2100  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::SORI);
2101  }
2102  else if (accession == "MS:1000422") //high-energy collision-induced dissociation
2103  {
2104  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::HCID);
2105  }
2106  else if (accession == "MS:1000433") //low-energy collision-induced dissociation
2107  {
2108  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::LCID);
2109  }
2110  else if (accession == "MS:1000435") //photodissociation
2111  {
2112  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::PHD);
2113  }
2114  else if (accession == "MS:1000598") //electron transfer dissociation
2115  {
2116  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::ETD);
2117  }
2118  else if (accession == "MS:1000599") //pulsed q dissociation
2119  {
2120  chromatogram_.getPrecursor().getActivationMethods().insert(Precursor::PQD);
2121  }
2122  else
2123  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2124  }
2125  }
2126  //------------------------- isolationWindow ----------------------------
2127  else if (parent_tag == "isolationWindow")
2128  {
2129  if (parent_parent_tag == "precursor")
2130  {
2131  if (accession == "MS:1000827") //isolation window target m/z
2132  {
2133  if (in_spectrum_list_)
2134  {
2135  spec_.getPrecursors().back().setMZ(value.toDouble());
2136  }
2137  else
2138  {
2139  chromatogram_.getPrecursor().setMZ(value.toDouble());
2140  }
2141  }
2142  else if (accession == "MS:1000828") //isolation window lower offset
2143  {
2144  if (in_spectrum_list_)
2145  {
2146  spec_.getPrecursors().back().setIsolationWindowLowerOffset(value.toDouble());
2147  }
2148  else
2149  {
2150  chromatogram_.getPrecursor().setIsolationWindowLowerOffset(value.toDouble());
2151  }
2152  }
2153  else if (accession == "MS:1000829") //isolation window upper offset
2154  {
2155  if (in_spectrum_list_)
2156  {
2157  spec_.getPrecursors().back().setIsolationWindowUpperOffset(value.toDouble());
2158  }
2159  else
2160  {
2161  chromatogram_.getPrecursor().setIsolationWindowUpperOffset(value.toDouble());
2162  }
2163  }
2164  else
2165  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2166  }
2167  else if (parent_parent_tag == "product")
2168  {
2169  if (accession == "MS:1000827") //isolation window target m/z
2170  {
2171  if (in_spectrum_list_)
2172  {
2173  spec_.getProducts().back().setMZ(value.toDouble());
2174  }
2175  else
2176  {
2177  chromatogram_.getProduct().setMZ(value.toDouble());
2178  }
2179  }
2180  else if (accession == "MS:1000829") //isolation window upper offset
2181  {
2182  if (in_spectrum_list_)
2183  {
2184  spec_.getProducts().back().setIsolationWindowUpperOffset(value.toDouble());
2185  }
2186  else
2187  {
2188  chromatogram_.getProduct().setIsolationWindowUpperOffset(value.toDouble());
2189  }
2190  }
2191  else if (accession == "MS:1000828") //isolation window lower offset
2192  {
2193  if (in_spectrum_list_)
2194  {
2195  spec_.getProducts().back().setIsolationWindowLowerOffset(value.toDouble());
2196  }
2197  else
2198  {
2199  chromatogram_.getProduct().setIsolationWindowLowerOffset(value.toDouble());
2200  }
2201  }
2202  else
2203  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2204  }
2205  }
2206  //------------------------- scanList ----------------------------
2207  else if (parent_tag == "scanList")
2208  {
2209  if (cv_.isChildOf(accession, "MS:1000570")) //method of combination as string
2210  {
2211  spec_.getAcquisitionInfo().setMethodOfCombination(cv_.getTerm(accession).name);
2212  }
2213  else
2214  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2215  }
2216  //------------------------- scan ----------------------------
2217  else if (parent_tag == "scan")
2218  {
2219  //scan attributes
2220  if (accession == "MS:1000502") //dwell time
2221  {
2222  //No member => meta data
2223  spec_.setMetaValue("dwell time", termValue);
2224  }
2225  else if (accession == "MS:1000011") //mass resolution
2226  {
2227  //No member => meta data
2228  spec_.setMetaValue("mass resolution", termValue);
2229  }
2230  else if (accession == "MS:1000015") //scan rate
2231  {
2232  //No member => meta data
2233  spec_.setMetaValue("scan rate", termValue);
2234  }
2235  else if (accession == "MS:1000016") //scan start time
2236  {
2237  if (unit_accession == "UO:0000031") //minutes
2238  {
2239  spec_.setRT(60.0 * value.toDouble());
2240  rt_set_ = true;
2241  }
2242  else //seconds
2243  {
2244  spec_.setRT(value.toDouble());
2245  rt_set_ = true;
2246  }
2247  if (options_.hasRTRange() && !options_.getRTRange().encloses(DPosition<1>(spec_.getRT())))
2248  {
2249  skip_spectrum_ = true;
2250  }
2251  }
2252  else if (accession == "MS:1000826") //elution time
2253  {
2254  if (unit_accession == "UO:0000031") //minutes
2255  {
2256  spec_.setMetaValue("elution time (seconds)", 60.0 * value.toDouble());
2257  }
2258  else //seconds
2259  {
2260  spec_.setMetaValue("elution time (seconds)", value.toDouble());
2261  }
2262  }
2263  else if (accession == "MS:1000512") //filter string
2264  {
2265  //No member => meta data
2266  spec_.setMetaValue("filter string", termValue);
2267  }
2268  else if (accession == "MS:1000803") //analyzer scan offset
2269  {
2270  //No member => meta data
2271  spec_.setMetaValue("analyzer scan offset", termValue); // used in SpectraIdentificationViewWidget()
2272  }
2273  else if (accession == "MS:1000616") //preset scan configuration
2274  {
2275  //No member => meta data
2276  spec_.setMetaValue("preset scan configuration", termValue);
2277  }
2278  else if (accession == "MS:1000800") //mass resolving power
2279  {
2280  //No member => meta data
2281  spec_.setMetaValue("mass resolving power", termValue);
2282  }
2283  else if (accession == "MS:1000880") //interchannel delay
2284  {
2285  //No member => meta data
2286  spec_.setMetaValue("interchannel delay", termValue);
2287  }
2288  //scan direction
2289  else if (accession == "MS:1000092") //decreasing m/z scan
2290  {
2291  //No member => meta data
2292  spec_.setMetaValue("scan direction", String("decreasing"));
2293  }
2294  else if (accession == "MS:1000093") //increasing m/z scan
2295  {
2296  //No member => meta data
2297  spec_.setMetaValue("scan direction", String("increasing"));
2298  }
2299  //scan law
2300  else if (accession == "MS:1000094") //scan law: exponential
2301  {
2302  //No member => meta data
2303  spec_.setMetaValue("scan law", String("exponential"));
2304  }
2305  else if (accession == "MS:1000095") //scan law: linear
2306  {
2307  //No member => meta data
2308  spec_.setMetaValue("scan law", String("linear"));
2309  }
2310  else if (accession == "MS:1000096") //scan law: quadratic
2311  {
2312  //No member => meta data
2313  spec_.setMetaValue("scan law", String("quadratic"));
2314  }
2315  else
2316  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2317  }
2318  //------------------------- contact ----------------------------
2319  else if (parent_tag == "contact")
2320  {
2321  if (accession == "MS:1000586") //contact name
2322  {
2323  exp_->getContacts().back().setName(value);
2324  }
2325  else if (accession == "MS:1000587") //contact address
2326  {
2327  exp_->getContacts().back().setAddress(value);
2328  }
2329  else if (accession == "MS:1000588") //contact URL
2330  {
2331  exp_->getContacts().back().setURL(value);
2332  }
2333  else if (accession == "MS:1000589") //contact email
2334  {
2335  exp_->getContacts().back().setEmail(value);
2336  }
2337  else if (accession == "MS:1000590") //contact organization
2338  {
2339  exp_->getContacts().back().setInstitution(value);
2340  }
2341  else
2342  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2343  }
2344  //------------------------- sourceFile ----------------------------
2345  else if (parent_tag == "sourceFile")
2346  {
2347  if (accession == "MS:1000569") //SHA-1 checksum
2348  {
2349  source_files_[current_id_].setChecksum(value, SourceFile::SHA1);
2350  }
2351  else if (accession == "MS:1000568") //MD5 checksum
2352  {
2353  source_files_[current_id_].setChecksum(value, SourceFile::MD5);
2354  }
2355  else if (cv_.isChildOf(accession, "MS:1000560")) //source file type as string
2356  {
2357  source_files_[current_id_].setFileType(cv_.getTerm(accession).name);
2358  }
2359  else if (cv_.isChildOf(accession, "MS:1000767")) //native spectrum identifier format as string
2360  {
2361  source_files_[current_id_].setNativeIDType(cv_.getTerm(accession).name);
2362  }
2363  else
2364  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2365  }
2366  //------------------------- sample ----------------------------
2367  else if (parent_tag == "sample")
2368  {
2369  if (accession == "MS:1000004") //sample mass (gram)
2370  {
2371  samples_[current_id_].setMass(value.toDouble());
2372  }
2373  else if (accession == "MS:1000001") //sample number
2374  {
2375  samples_[current_id_].setNumber(value);
2376  }
2377  else if (accession == "MS:1000005") //sample volume (milliliter)
2378  {
2379  samples_[current_id_].setVolume(value.toDouble());
2380  }
2381  else if (accession == "MS:1000006") //sample concentration (gram per liter)
2382  {
2383  samples_[current_id_].setConcentration(value.toDouble());
2384  }
2385  else if (accession == "MS:1000053") //sample batch
2386  {
2387  //No member => meta data
2388  samples_[current_id_].setMetaValue("sample batch", termValue);
2389  }
2390  else if (accession == "MS:1000047") //emulsion
2391  {
2392  samples_[current_id_].setState(Sample::EMULSION);
2393  }
2394  else if (accession == "MS:1000048") //gas
2395  {
2396  samples_[current_id_].setState(Sample::GAS);
2397  }
2398  else if (accession == "MS:1000049") //liquid
2399  {
2400  samples_[current_id_].setState(Sample::LIQUID);
2401  }
2402  else if (accession == "MS:1000050") //solid
2403  {
2404  samples_[current_id_].setState(Sample::SOLID);
2405  }
2406  else if (accession == "MS:1000051") //solution
2407  {
2408  samples_[current_id_].setState(Sample::SOLUTION);
2409  }
2410  else if (accession == "MS:1000052") //suspension
2411  {
2412  samples_[current_id_].setState(Sample::SUSPENSION);
2413  }
2414  else if (accession.hasPrefix("PATO:")) //quality of an object
2415  {
2416  //No member => meta data
2417  samples_[current_id_].setMetaValue(String(name), termValue);
2418  }
2419  else if (accession.hasPrefix("GO:")) //cellular_component
2420  {
2421  //No member => meta data
2422  samples_[current_id_].setMetaValue("GO cellular component", String(name));
2423  }
2424  else if (accession.hasPrefix("BTO:")) //brenda source tissue ontology
2425  {
2426  //No member => meta data
2427  samples_[current_id_].setMetaValue("brenda source tissue", String(name));
2428  }
2429  else
2430  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2431  }
2432  //------------------------- instrumentConfiguration ----------------------------
2433  else if (parent_tag == "instrumentConfiguration")
2434  {
2435  //instrument model
2436  if (accession == "MS:1000031")
2437  {
2438  //unknown instrument => nothing to do
2439  }
2440  else if (cv_.isChildOf(accession, "MS:1000031")) //instrument name as string
2441  {
2442  instruments_[current_id_].setName(cv_.getTerm(accession).name);
2443  }
2444  //instrument attribute
2445  else if (accession == "MS:1000529") //instrument serial number
2446  {
2447  //No member => meta data
2448  instruments_[current_id_].setMetaValue("instrument serial number", termValue);
2449  }
2450  else if (accession == "MS:1000032") //customization
2451  {
2452  instruments_[current_id_].setCustomizations(value);
2453  }
2454  else if (accession == "MS:1000236") //transmission
2455  {
2456  //No member => metadata
2457  instruments_[current_id_].setMetaValue("transmission", termValue);
2458  }
2459  //ion optics type
2460  else if (accession == "MS:1000246") //delayed extraction
2461  {
2462  instruments_[current_id_].setIonOptics(Instrument::DELAYED_EXTRACTION);
2463  }
2464  else if (accession == "MS:1000221") //magnetic deflection
2465  {
2466  instruments_[current_id_].setIonOptics(Instrument::MAGNETIC_DEFLECTION);
2467  }
2468  else if (accession == "MS:1000275") //collision quadrupole
2469  {
2470  instruments_[current_id_].setIonOptics(Instrument::COLLISION_QUADRUPOLE);
2471  }
2472  else if (accession == "MS:1000281") //selected ion flow tube
2473  {
2474  instruments_[current_id_].setIonOptics(Instrument::SELECTED_ION_FLOW_TUBE);
2475  }
2476  else if (accession == "MS:1000286") //time lag focusing
2477  {
2478  instruments_[current_id_].setIonOptics(Instrument::TIME_LAG_FOCUSING);
2479  }
2480  else if (accession == "MS:1000300") //reflectron
2481  {
2482  instruments_[current_id_].setIonOptics(Instrument::REFLECTRON);
2483  }
2484  else if (accession == "MS:1000307") //einzel lens
2485  {
2486  instruments_[current_id_].setIonOptics(Instrument::EINZEL_LENS);
2487  }
2488  else if (accession == "MS:1000309") //first stability region
2489  {
2490  instruments_[current_id_].setIonOptics(Instrument::FIRST_STABILITY_REGION);
2491  }
2492  else if (accession == "MS:1000310") //fringing field
2493  {
2494  instruments_[current_id_].setIonOptics(Instrument::FRINGING_FIELD);
2495  }
2496  else if (accession == "MS:1000311") //kinetic energy analyzer
2497  {
2498  instruments_[current_id_].setIonOptics(Instrument::KINETIC_ENERGY_ANALYZER);
2499  }
2500  else if (accession == "MS:1000320") //static field
2501  {
2502  instruments_[current_id_].setIonOptics(Instrument::STATIC_FIELD);
2503  }
2504  //ion optics attribute
2505  else if (accession == "MS:1000304") //accelerating voltage
2506  {
2507  //No member => metadata
2508  instruments_[current_id_].setMetaValue("accelerating voltage", termValue);
2509  }
2510  else if (accession == "MS:1000216") //field-free region
2511  {
2512  //No member => metadata
2513  instruments_[current_id_].setMetaValue("field-free region", String("true"));
2514  }
2515  else if (accession == "MS:1000308") //electric field strength
2516  {
2517  //No member => metadata
2518  instruments_[current_id_].setMetaValue("electric field strength", termValue);
2519  }
2520  else if (accession == "MS:1000319") //space charge effect
2521  {
2522  //No member => metadata
2523  instruments_[current_id_].setMetaValue("space charge effect", String("true"));
2524  }
2525  else
2526  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2527  }
2528  else if (parent_tag == "source")
2529  {
2530  //inlet type
2531  if (accession == "MS:1000055") //continuous flow fast atom bombardment
2532  {
2533  instruments_[current_id_].getIonSources().back().setInletType(IonSource::CONTINUOUSFLOWFASTATOMBOMBARDMENT);
2534  }
2535  else if (accession == "MS:1000056") //direct inlet
2536  {
2537  instruments_[current_id_].getIonSources().back().setInletType(IonSource::DIRECT);
2538  }
2539  else if (accession == "MS:1000057") //electrospray inlet
2540  {
2541  instruments_[current_id_].getIonSources().back().setInletType(IonSource::ELECTROSPRAYINLET);
2542  }
2543  else if (accession == "MS:1000058") //flow injection analysis
2544  {
2545  instruments_[current_id_].getIonSources().back().setInletType(IonSource::FLOWINJECTIONANALYSIS);
2546  }
2547  else if (accession == "MS:1000059") //inductively coupled plasma
2548  {
2549  instruments_[current_id_].getIonSources().back().setInletType(IonSource::INDUCTIVELYCOUPLEDPLASMA);
2550  }
2551  else if (accession == "MS:1000060") //infusion
2552  {
2553  instruments_[current_id_].getIonSources().back().setInletType(IonSource::INFUSION);
2554  }
2555  else if (accession == "MS:1000061") //jet separator
2556  {
2557  instruments_[current_id_].getIonSources().back().setInletType(IonSource::JETSEPARATOR);
2558  }
2559  else if (accession == "MS:1000062") //membrane separator
2560  {
2561  instruments_[current_id_].getIonSources().back().setInletType(IonSource::MEMBRANESEPARATOR);
2562  }
2563  else if (accession == "MS:1000063") //moving belt
2564  {
2565  instruments_[current_id_].getIonSources().back().setInletType(IonSource::MOVINGBELT);
2566  }
2567  else if (accession == "MS:1000064") //moving wire
2568  {
2569  instruments_[current_id_].getIonSources().back().setInletType(IonSource::MOVINGWIRE);
2570  }
2571  else if (accession == "MS:1000065") //open split
2572  {
2573  instruments_[current_id_].getIonSources().back().setInletType(IonSource::OPENSPLIT);
2574  }
2575  else if (accession == "MS:1000066") //particle beam
2576  {
2577  instruments_[current_id_].getIonSources().back().setInletType(IonSource::PARTICLEBEAM);
2578  }
2579  else if (accession == "MS:1000067") //reservoir
2580  {
2581  instruments_[current_id_].getIonSources().back().setInletType(IonSource::RESERVOIR);
2582  }
2583  else if (accession == "MS:1000068") //septum
2584  {
2585  instruments_[current_id_].getIonSources().back().setInletType(IonSource::SEPTUM);
2586  }
2587  else if (accession == "MS:1000069") //thermospray inlet
2588  {
2589  instruments_[current_id_].getIonSources().back().setInletType(IonSource::THERMOSPRAYINLET);
2590  }
2591  else if (accession == "MS:1000248") //direct insertion probe
2592  {
2593  instruments_[current_id_].getIonSources().back().setInletType(IonSource::BATCH);
2594  }
2595  else if (accession == "MS:1000249") //direct liquid introduction
2596  {
2597  instruments_[current_id_].getIonSources().back().setInletType(IonSource::CHROMATOGRAPHY);
2598  }
2599  else if (accession == "MS:1000396") //membrane inlet
2600  {
2601  instruments_[current_id_].getIonSources().back().setInletType(IonSource::MEMBRANE);
2602  }
2603  else if (accession == "MS:1000485") //nanospray inlet
2604  {
2605  instruments_[current_id_].getIonSources().back().setInletType(IonSource::NANOSPRAY);
2606  }
2607  //ionization type
2608  else if (accession == "MS:1000071") //chemical ionization
2609  {
2610  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::CI);
2611  }
2612  else if (accession == "MS:1000073") //electrospray ionization
2613  {
2614  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::ESI);
2615  }
2616  else if (accession == "MS:1000074") //fast atom bombardment ionization
2617  {
2618  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::FAB);
2619  }
2620  else if (accession == "MS:1000227") //multiphoton ionization
2621  {
2622  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::MPI);
2623  }
2624  else if (accession == "MS:1000240") //atmospheric pressure ionization
2625  {
2626  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::API);
2627  }
2628  else if (accession == "MS:1000247") //desorption ionization
2629  {
2630  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::DI);
2631  }
2632  else if (accession == "MS:1000255") //flowing afterglow
2633  {
2634  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::FA);
2635  }
2636  else if (accession == "MS:1000258") //field ionization
2637  {
2638  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::FII);
2639  }
2640  else if (accession == "MS:1000259") //glow discharge ionization
2641  {
2642  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::GD_MS);
2643  }
2644  else if (accession == "MS:1000271") //Negative ion chemical ionization
2645  {
2646  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::NICI);
2647  }
2648  else if (accession == "MS:1000272") //neutralization reionization mass spectrometry
2649  {
2650  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::NRMS);
2651  }
2652  else if (accession == "MS:1000273") //photoionization
2653  {
2654  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::PI);
2655  }
2656  else if (accession == "MS:1000274") //pyrolysis mass spectrometry
2657  {
2658  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::PYMS);
2659  }
2660  else if (accession == "MS:1000276") //resonance enhanced multiphoton ionization
2661  {
2662  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::REMPI);
2663  }
2664  else if (accession == "MS:1000380") //adiabatic ionization
2665  {
2666  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::AI);
2667  }
2668  else if (accession == "MS:1000381") //associative ionization
2669  {
2670  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::ASI);
2671  }
2672  else if (accession == "MS:1000383") //autodetachment
2673  {
2674  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::AD);
2675  }
2676  else if (accession == "MS:1000384") //autoionization
2677  {
2678  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::AUI);
2679  }
2680  else if (accession == "MS:1000385") //charge exchange ionization
2681  {
2682  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::CEI);
2683  }
2684  else if (accession == "MS:1000386") //chemi-ionization
2685  {
2686  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::CHEMI);
2687  }
2688  else if (accession == "MS:1000388") //dissociative ionization
2689  {
2690  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::DISSI);
2691  }
2692  else if (accession == "MS:1000389") //electron ionization
2693  {
2694  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::EI);
2695  }
2696  else if (accession == "MS:1000395") //liquid secondary ionization
2697  {
2698  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::LSI);
2699  }
2700  else if (accession == "MS:1000399") //penning ionization
2701  {
2702  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::PEI);
2703  }
2704  else if (accession == "MS:1000400") //plasma desorption ionization
2705  {
2706  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::PD);
2707  }
2708  else if (accession == "MS:1000402") //secondary ionization
2709  {
2710  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SI);
2711  }
2712  else if (accession == "MS:1000403") //soft ionization
2713  {
2714  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SOI);
2715  }
2716  else if (accession == "MS:1000404") //spark ionization
2717  {
2718  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SPI);
2719  }
2720  else if (accession == "MS:1000406") //surface ionization
2721  {
2722  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SUI);
2723  }
2724  else if (accession == "MS:1000407") //thermal ionization
2725  {
2726  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::TI);
2727  }
2728  else if (accession == "MS:1000408") //vertical ionization
2729  {
2730  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::VI);
2731  }
2732  else if (accession == "MS:1000446") //fast ion bombardment
2733  {
2734  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::FIB);
2735  }
2736  else if (accession == "MS:1000070") //atmospheric pressure chemical ionization
2737  {
2738  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::APCI);
2739  }
2740  else if (accession == "MS:1000239") //atmospheric pressure matrix-assisted laser desorption ionization
2741  {
2742  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::AP_MALDI);
2743  }
2744  else if (accession == "MS:1000382") //atmospheric pressure photoionization
2745  {
2746  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::APPI);
2747  }
2748  else if (accession == "MS:1000075") //matrix-assisted laser desorption ionization
2749  {
2750  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::MALDI);
2751  }
2752  else if (accession == "MS:1000257") //field desorption
2753  {
2754  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::FD);
2755  }
2756  else if (accession == "MS:1000387") //desorption/ionization on silicon
2757  {
2758  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SILI);
2759  }
2760  else if (accession == "MS:1000393") //laser desorption ionization
2761  {
2762  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::LD);
2763  }
2764  else if (accession == "MS:1000405") //surface-assisted laser desorption ionization
2765  {
2766  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SALDI);
2767  }
2768  else if (accession == "MS:1000397") //microelectrospray
2769  {
2770  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::MESI);
2771  }
2772  else if (accession == "MS:1000398") //nanoelectrospray
2773  {
2774  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::NESI);
2775  }
2776  else if (accession == "MS:1000278") //surface enhanced laser desorption ionization
2777  {
2778  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SELDI);
2779  }
2780  else if (accession == "MS:1000279") //surface enhanced neat desorption
2781  {
2782  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::SEND);
2783  }
2784  else if (accession == "MS:1000008") //ionization type (base term)
2785  {
2786  instruments_[current_id_].getIonSources().back().setIonizationMethod(IonSource::IONMETHODNULL);
2787  }
2788  //source attribute
2789  else if (accession == "MS:1000392") //ionization efficiency
2790  {
2791  //No member => meta data
2792  instruments_[current_id_].getIonSources().back().setMetaValue("ionization efficiency", termValue);
2793  }
2794  else if (accession == "MS:1000486") //source potential
2795  {
2796  //No member => meta data
2797  instruments_[current_id_].getIonSources().back().setMetaValue("source potential", termValue);
2798  }
2799  else if (accession == "MS:1000875") // declustering potential
2800  {
2801  //No member => meta data
2802  instruments_[current_id_].getIonSources().back().setMetaValue("declustering potential", termValue);
2803  }
2804  else if (accession == "MS:1000876") // cone voltage
2805  {
2806  //No member => meta data
2807  instruments_[current_id_].getIonSources().back().setMetaValue("cone voltage", termValue);
2808  }
2809  else if (accession == "MS:1000877") // tube lens
2810  {
2811  //No member => meta data
2812  instruments_[current_id_].getIonSources().back().setMetaValue("tube lens", termValue);
2813  }
2814  //laser attribute
2815  else if (accession == "MS:1000843") // wavelength
2816  {
2817  //No member => meta data
2818  instruments_[current_id_].getIonSources().back().setMetaValue("wavelength", termValue);
2819  }
2820  else if (accession == "MS:1000844") // focus diameter x
2821  {
2822  //No member => meta data
2823  instruments_[current_id_].getIonSources().back().setMetaValue("focus diameter x", termValue);
2824  }
2825  else if (accession == "MS:1000845") // focus diameter y
2826  {
2827  //No member => meta data
2828  instruments_[current_id_].getIonSources().back().setMetaValue("focus diameter y", termValue);
2829  }
2830  else if (accession == "MS:1000846") // pulse energy
2831  {
2832  //No member => meta data
2833  instruments_[current_id_].getIonSources().back().setMetaValue("pulse energy", termValue);
2834  }
2835  else if (accession == "MS:1000847") // pulse duration
2836  {
2837  //No member => meta data
2838  instruments_[current_id_].getIonSources().back().setMetaValue("pulse duration", termValue);
2839  }
2840  else if (accession == "MS:1000848") // attenuation
2841  {
2842  //No member => meta data
2843  instruments_[current_id_].getIonSources().back().setMetaValue("attenuation", termValue);
2844  }
2845  else if (accession == "MS:1000849") // impact angle
2846  {
2847  //No member => meta data
2848  instruments_[current_id_].getIonSources().back().setMetaValue("impact angle", termValue);
2849  }
2850  //laser type
2851  else if (accession == "MS:1000850") // gas laser
2852  {
2853  //No member => meta data
2854  instruments_[current_id_].getIonSources().back().setMetaValue("laser type", "gas laser");
2855  }
2856  else if (accession == "MS:1000851") // solid-state laser
2857  {
2858  //No member => meta data
2859  instruments_[current_id_].getIonSources().back().setMetaValue("laser type", "solid-state laser");
2860  }
2861  else if (accession == "MS:1000852") // dye-laser
2862  {
2863  //No member => meta data
2864  instruments_[current_id_].getIonSources().back().setMetaValue("laser type", "dye-laser");
2865  }
2866  else if (accession == "MS:1000853") // free electron laser
2867  {
2868  //No member => meta data
2869  instruments_[current_id_].getIonSources().back().setMetaValue("laser type", "free electron laser");
2870  }
2871  //MALDI matrix application
2872  else if (accession == "MS:1000834") // matrix solution
2873  {
2874  //No member => meta data
2875  instruments_[current_id_].getIonSources().back().setMetaValue("matrix solution", termValue);
2876  }
2877  else if (accession == "MS:1000835") // matrix solution concentration
2878  {
2879  //No member => meta data
2880  instruments_[current_id_].getIonSources().back().setMetaValue("matrix solution concentration", termValue);
2881  }
2882  // matrix application type
2883  else if (accession == "MS:1000836") // dried dropplet
2884  {
2885  //No member => meta data
2886  instruments_[current_id_].getIonSources().back().setMetaValue("matrix application type", "dried dropplet");
2887  }
2888  else if (accession == "MS:1000837") // printed
2889  {
2890  //No member => meta data
2891  instruments_[current_id_].getIonSources().back().setMetaValue("matrix application type", "printed");
2892  }
2893  else if (accession == "MS:1000838") // sprayed
2894  {
2895  //No member => meta data
2896  instruments_[current_id_].getIonSources().back().setMetaValue("matrix application type", "sprayed");
2897  }
2898  else if (accession == "MS:1000839") // precoated plate
2899  {
2900  //No member => meta data
2901  instruments_[current_id_].getIonSources().back().setMetaValue("matrix application type", " precoated plate");
2902  }
2903  else
2904  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2905  }
2906  else if (parent_tag == "analyzer")
2907  {
2908  //mass analyzer type
2909  if (accession == "MS:1000079") //fourier transform ion cyclotron resonance mass spectrometer
2910  {
2911  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::FOURIERTRANSFORM);
2912  }
2913  else if (accession == "MS:1000080") //magnetic sector
2914  {
2915  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::SECTOR);
2916  }
2917  else if (accession == "MS:1000081") //quadrupole
2918  {
2919  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::QUADRUPOLE);
2920  }
2921  else if (accession == "MS:1000084") //time-of-flight
2922  {
2923  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::TOF);
2924  }
2925  else if (accession == "MS:1000254") //electrostatic energy analyzer
2926  {
2927  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::ESA);
2928  }
2929  else if (accession == "MS:1000264") //ion trap
2930  {
2931  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::IT);
2932  }
2933  else if (accession == "MS:1000284") //stored waveform inverse fourier transform
2934  {
2935  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::SWIFT);
2936  }
2937  else if (accession == "MS:1000288") //cyclotron
2938  {
2939  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::CYCLOTRON);
2940  }
2941  else if (accession == "MS:1000484") //orbitrap
2942  {
2943  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::ORBITRAP);
2944  }
2945  else if (accession == "MS:1000078") //axial ejection linear ion trap
2946  {
2947  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::AXIALEJECTIONLINEARIONTRAP);
2948  }
2949  else if (accession == "MS:1000082") //quadrupole ion trap
2950  {
2951  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::PAULIONTRAP);
2952  }
2953  else if (accession == "MS:1000083") //radial ejection linear ion trap
2954  {
2955  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::RADIALEJECTIONLINEARIONTRAP);
2956  }
2957  else if (accession == "MS:1000291") //linear ion trap
2958  {
2959  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::LIT);
2960  }
2961  else if (accession == "MS:1000443") //mass analyzer type (base term)
2962  {
2963  instruments_[current_id_].getMassAnalyzers().back().setType(MassAnalyzer::ANALYZERNULL);
2964  }
2965  //mass analyzer attribute
2966  else if (accession == "MS:1000014") //accuracy (ppm)
2967  {
2968  instruments_[current_id_].getMassAnalyzers().back().setAccuracy(value.toDouble());
2969  }
2970  else if (accession == "MS:1000022") //TOF Total Path Length (meter)
2971  {
2972  instruments_[current_id_].getMassAnalyzers().back().setTOFTotalPathLength(value.toDouble());
2973  }
2974  else if (accession == "MS:1000024") //final MS exponent
2975  {
2976  instruments_[current_id_].getMassAnalyzers().back().setFinalMSExponent(value.toInt());
2977  }
2978  else if (accession == "MS:1000025") //magnetic field strength (tesla)
2979  {
2980  instruments_[current_id_].getMassAnalyzers().back().setMagneticFieldStrength(value.toDouble());
2981  }
2982  else if (accession == "MS:1000105") //reflectron off
2983  {
2984  instruments_[current_id_].getMassAnalyzers().back().setReflectronState(MassAnalyzer::OFF);
2985  }
2986  else if (accession == "MS:1000106") //reflectron on
2987  {
2988  instruments_[current_id_].getMassAnalyzers().back().setReflectronState(MassAnalyzer::ON);
2989  }
2990  else
2991  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
2992  }
2993  else if (parent_tag == "detector")
2994  {
2995  //detector type
2996  if (accession == "MS:1000107") //channeltron
2997  {
2998  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::CHANNELTRON);
2999  }
3000  else if (accession == "MS:1000110") //daly detector
3001  {
3002  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::DALYDETECTOR);
3003  }
3004  else if (accession == "MS:1000112") //faraday cup
3005  {
3006  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::FARADAYCUP);
3007  }
3008  else if (accession == "MS:1000114") //microchannel plate detector
3009  {
3010  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::MICROCHANNELPLATEDETECTOR);
3011  }
3012  else if (accession == "MS:1000115") //multi-collector
3013  {
3014  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::MULTICOLLECTOR);
3015  }
3016  else if (accession == "MS:1000116") //photomultiplier
3017  {
3018  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::PHOTOMULTIPLIER);
3019  }
3020  else if (accession == "MS:1000253") //electron multiplier
3021  {
3022  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::ELECTRONMULTIPLIER);
3023  }
3024  else if (accession == "MS:1000345") //array detector
3025  {
3026  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::ARRAYDETECTOR);
3027  }
3028  else if (accession == "MS:1000346") //conversion dynode
3029  {
3030  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::CONVERSIONDYNODE);
3031  }
3032  else if (accession == "MS:1000347") //dynode
3033  {
3034  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::DYNODE);
3035  }
3036  else if (accession == "MS:1000348") //focal plane collector
3037  {
3038  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::FOCALPLANECOLLECTOR);
3039  }
3040  else if (accession == "MS:1000349") //ion-to-photon detector
3041  {
3042  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::IONTOPHOTONDETECTOR);
3043  }
3044  else if (accession == "MS:1000350") //point collector
3045  {
3046  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::POINTCOLLECTOR);
3047  }
3048  else if (accession == "MS:1000351") //postacceleration detector
3049  {
3050  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::POSTACCELERATIONDETECTOR);
3051  }
3052  else if (accession == "MS:1000621") //photodiode array detector
3053  {
3054  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::PHOTODIODEARRAYDETECTOR);
3055  }
3056  else if (accession == "MS:1000624") //inductive detector
3057  {
3058  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::INDUCTIVEDETECTOR);
3059  }
3060  else if (accession == "MS:1000108") //conversion dynode electron multiplier
3061  {
3062  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::CONVERSIONDYNODEELECTRONMULTIPLIER);
3063  }
3064  else if (accession == "MS:1000109") //conversion dynode photomultiplier
3065  {
3066  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::CONVERSIONDYNODEPHOTOMULTIPLIER);
3067  }
3068  else if (accession == "MS:1000111") //electron multiplier tube
3069  {
3070  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::ELECTRONMULTIPLIERTUBE);
3071  }
3072  else if (accession == "MS:1000113") //focal plane array
3073  {
3074  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::FOCALPLANEARRAY);
3075  }
3076  else if (accession == "MS:1000026") //detector type (base term)
3077  {
3078  instruments_[current_id_].getIonDetectors().back().setType(IonDetector::TYPENULL);
3079  }
3080  //detector attribute
3081  else if (accession == "MS:1000028") //detector resolution
3082  {
3083  instruments_[current_id_].getIonDetectors().back().setResolution(value.toDouble());
3084  }
3085  else if (accession == "MS:1000029") //sampling frequency
3086  {
3087  instruments_[current_id_].getIonDetectors().back().setADCSamplingFrequency(value.toDouble());
3088  }
3089  //detector acquisition mode
3090  else if (accession == "MS:1000117") //analog-digital converter
3091  {
3092  instruments_[current_id_].getIonDetectors().back().setAcquisitionMode(IonDetector::ADC);
3093  }
3094  else if (accession == "MS:1000118") //pulse counting
3095  {
3096  instruments_[current_id_].getIonDetectors().back().setAcquisitionMode(IonDetector::PULSECOUNTING);
3097  }
3098  else if (accession == "MS:1000119") //time-digital converter
3099  {
3100  instruments_[current_id_].getIonDetectors().back().setAcquisitionMode(IonDetector::TDC);
3101  }
3102  else if (accession == "MS:1000120") //transient recorder
3103  {
3104  instruments_[current_id_].getIonDetectors().back().setAcquisitionMode(IonDetector::TRANSIENTRECORDER);
3105  }
3106  else
3107  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3108  }
3109  else if (parent_tag == "processingMethod")
3110  {
3111  //data processing parameter
3112  if (accession == "MS:1000629") //low intensity threshold (ion count)
3113  {
3114  processing_[current_id_].back().setMetaValue("low_intensity_threshold", termValue);
3115  }
3116  else if (accession == "MS:1000631") //high intensity threshold (ion count)
3117  {
3118  processing_[current_id_].back().setMetaValue("high_intensity_threshold", termValue);
3119  }
3120  else if (accession == "MS:1000787") //inclusive low intensity threshold
3121  {
3122  processing_[current_id_].back().setMetaValue("inclusive_low_intensity_threshold", termValue);
3123  }
3124  else if (accession == "MS:1000788") //inclusive high intensity threshold
3125  {
3126  processing_[current_id_].back().setMetaValue("inclusive_high_intensity_threshold", termValue);
3127  }
3128  else if (accession == "MS:1000747") //completion time
3129  {
3130  processing_[current_id_].back().setCompletionTime(asDateTime_(value));
3131  }
3132  //file format conversion
3133  else if (accession == "MS:1000530") //file format conversion
3134  {
3135  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::FORMAT_CONVERSION);
3136  }
3137  else if (accession == "MS:1000544") //Conversion to mzML
3138  {
3139  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CONVERSION_MZML);
3140  }
3141  else if (accession == "MS:1000545") //Conversion to mzXML
3142  {
3143  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CONVERSION_MZXML);
3144  }
3145  else if (accession == "MS:1000546") //Conversion to mzData
3146  {
3147  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CONVERSION_MZDATA);
3148  }
3149  else if (accession == "MS:1000741") //Conversion to DTA
3150  {
3151  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CONVERSION_DTA);
3152  }
3153  //data processing action
3154  else if (accession == "MS:1000543") //data processing action
3155  {
3156  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::DATA_PROCESSING);
3157  }
3158  else if (accession == "MS:1000033") //deisotoping
3159  {
3160  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::DEISOTOPING);
3161  }
3162  else if (accession == "MS:1000034") //charge deconvolution
3163  {
3164  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CHARGE_DECONVOLUTION);
3165  }
3166  else if (accession == "MS:1000035" || cv_.isChildOf(accession, "MS:1000035")) //peak picking (or child terms, we make no difference)
3167  {
3168  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::PEAK_PICKING);
3169  }
3170  else if (accession == "MS:1000592" || cv_.isChildOf(accession, "MS:1000592")) //smoothing (or child terms, we make no difference)
3171  {
3172  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::SMOOTHING);
3173  }
3174  else if (accession == "MS:1000778" || cv_.isChildOf(accession, "MS:1000778")) //charge state calculation (or child terms, we make no difference)
3175  {
3176  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CHARGE_CALCULATION);
3177  }
3178  else if (accession == "MS:1000780" || cv_.isChildOf(accession, "MS:1000780")) //precursor recalculation (or child terms, we make no difference)
3179  {
3180  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::PRECURSOR_RECALCULATION);
3181  }
3182  else if (accession == "MS:1000593") //baseline reduction
3183  {
3184  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::BASELINE_REDUCTION);
3185  }
3186  else if (accession == "MS:1000745") //retention time alignment
3187  {
3188  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::ALIGNMENT);
3189  }
3190  else if (accession == "MS:1001484") //intensity normalization
3191  {
3192  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::NORMALIZATION);
3193  }
3194  else if (accession == "MS:1001485") //m/z calibration
3195  {
3196  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::CALIBRATION);
3197  }
3198  else if (accession == "MS:1001486" || cv_.isChildOf(accession, "MS:1001486")) //data filtering (or child terms, we make no difference)
3199  {
3200  processing_[current_id_].back().getProcessingActions().insert(DataProcessing::FILTERING);
3201  }
3202  else
3203  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3204  }
3205  else if (parent_tag == "fileContent")
3206  {
3207  if (cv_.isChildOf(accession, "MS:1000524")) //data file content
3208  {
3209  //ignored
3210  //exp_->setMetaValue(name, termValue);
3211  }
3212  else if (cv_.isChildOf(accession, "MS:1000525")) //spectrum representation
3213  {
3214  //ignored
3215  //exp_->setMetaValue(name, termValue);
3216  }
3217  else
3218  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3219  }
3220  else if (parent_tag == "software")
3221  {
3222  if (cv_.isChildOf(accession, "MS:1000531")) //software as string
3223  {
3224  if (accession == "MS:1000799") //custom unreleased software tool => use value as name
3225  {
3226  software_[current_id_].setName(value);
3227  }
3228  else //use name as name
3229  {
3230  software_[current_id_].setName(name);
3231  }
3232  }
3233  else
3234  {
3235  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3236  }
3237  //~ software_[current_id_].addCVTerm( CVTerm (accession, value, const String &cv_identifier_ref, const String &value, const Unit &unit) ); TODO somthing like that
3238  }
3239  else if (parent_tag == "chromatogram")
3240  {
3241  if (accession == "MS:1000810")
3242  {
3243  chromatogram_.setChromatogramType(ChromatogramSettings::MASS_CHROMATOGRAM);
3244  }
3245  else if (accession == "MS:1000235")
3246  {
3247  chromatogram_.setChromatogramType(ChromatogramSettings::TOTAL_ION_CURRENT_CHROMATOGRAM);
3248  }
3249  else if (accession == "MS:1000627")
3250  {
3251  chromatogram_.setChromatogramType(ChromatogramSettings::SELECTED_ION_CURRENT_CHROMATOGRAM);
3252  }
3253  else if (accession == "MS:1000628")
3254  {
3255  chromatogram_.setChromatogramType(ChromatogramSettings::BASEPEAK_CHROMATOGRAM);
3256  }
3257  else if (accession == "MS:1001472")
3258  {
3259  chromatogram_.setChromatogramType(ChromatogramSettings::SELECTED_ION_MONITORING_CHROMATOGRAM);
3260  }
3261  else if (accession == "MS:1001473")
3262  {
3263  chromatogram_.setChromatogramType(ChromatogramSettings::SELECTED_REACTION_MONITORING_CHROMATOGRAM);
3264  }
3265  else if (accession == "MS:1001474")
3266  {
3267  chromatogram_.setChromatogramType(ChromatogramSettings::SELECTED_REACTION_MONITORING_CHROMATOGRAM);
3268  }
3269  else if (accession == "MS:1000811")
3270  {
3271  chromatogram_.setChromatogramType(ChromatogramSettings::ELECTROMAGNETIC_RADIATION_CHROMATOGRAM);
3272  }
3273  else if (accession == "MS:1000812")
3274  {
3275  chromatogram_.setChromatogramType(ChromatogramSettings::ABSORPTION_CHROMATOGRAM);
3276  }
3277  else if (accession == "MS:1000813")
3278  {
3279  chromatogram_.setChromatogramType(ChromatogramSettings::EMISSION_CHROMATOGRAM);
3280  }
3281  else if (accession == "MS:1000809")
3282  {
3283  chromatogram_.setName(value);
3284  }
3285  else
3286  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3287  }
3288  else if (parent_tag == "target")
3289  {
3290  //allowed but, not needed
3291  }
3292  else
3293  warning(LOAD, String("Unhandled cvParam '") + accession + "' in tag '" + parent_tag + "'.");
3294  }
3295 
3296  template <typename MapType>
3297  void MzMLHandler<MapType>::handleUserParam_(const String& parent_parent_tag, const String& parent_tag, const String& name, const String& type, const String& value)
3298  {
3299  //create a DataValue that contains the data in the right type
3300  DataValue data_value;
3301  //float type
3302  if (type == "xsd:double" || type == "xsd:float")
3303  {
3304  data_value = DataValue(value.toDouble());
3305  }
3306  //integer type
3307  else if (type == "xsd:byte" || type == "xsd:decimal" || type == "xsd:int" || type == "xsd:integer" || type == "xsd:long" || type == "xsd:negativeInteger" || type == "xsd:nonNegativeInteger" || type == "xsd:nonPositiveInteger" || type == "xsd:positiveInteger" || type == "xsd:short" || type == "xsd:unsignedByte" || type == "xsd:unsignedInt" || type == "xsd:unsignedLong" || type == "xsd:unsignedShort")
3308  {
3309  data_value = DataValue(value.toInt());
3310  }
3311  //everything else is treated as a string
3312  else
3313  {
3314  data_value = DataValue(value);
3315  }
3316 
3317  //find the right MetaInfoInterface
3318  if (parent_tag == "run")
3319  {
3320  exp_->setMetaValue(name, data_value);
3321  }
3322  else if (parent_tag == "instrumentConfiguration")
3323  {
3324  instruments_[current_id_].setMetaValue(name, data_value);
3325  }
3326  else if (parent_tag == "source")
3327  {
3328  instruments_[current_id_].getIonSources().back().setMetaValue(name, data_value);
3329  }
3330  else if (parent_tag == "analyzer")
3331  {
3332  instruments_[current_id_].getMassAnalyzers().back().setMetaValue(name, data_value);
3333  }
3334  else if (parent_tag == "detector")
3335  {
3336  instruments_[current_id_].getIonDetectors().back().setMetaValue(name, data_value);
3337  }
3338  else if (parent_tag == "sample")
3339  {
3340  samples_[current_id_].setMetaValue(name, data_value);
3341  }
3342  else if (parent_tag == "software")
3343  {
3344  software_[current_id_].setMetaValue(name, data_value);
3345  }
3346  else if (parent_tag == "contact")
3347  {
3348  exp_->getContacts().back().setMetaValue(name, data_value);
3349  }
3350  else if (parent_tag == "sourceFile")
3351  {
3352  source_files_[current_id_].setMetaValue(name, data_value);
3353  }
3354  else if (parent_tag == "binaryDataArray")
3355  {
3356  data_.back().meta.setMetaValue(name, data_value);
3357  }
3358  else if (parent_tag == "spectrum")
3359  {
3360  spec_.setMetaValue(name, data_value);
3361  }
3362  else if (parent_tag == "chromatogram")
3363  {
3364  chromatogram_.setMetaValue(name, data_value);
3365  }
3366  else if (parent_tag == "scanList")
3367  {
3368  spec_.getAcquisitionInfo().setMetaValue(name, data_value);
3369  }
3370  else if (parent_tag == "scan")
3371  {
3372  spec_.getAcquisitionInfo().back().setMetaValue(name, data_value);
3373  }
3374  else if (parent_tag == "scanWindow")
3375  {
3376  spec_.getInstrumentSettings().getScanWindows().back().setMetaValue(name, data_value);
3377  }
3378  else if (parent_tag == "isolationWindow")
3379  {
3380  //We don't have this as a separate location => store it in the precursor
3381  if (parent_parent_tag == "precursor")
3382  {
3383  if (in_spectrum_list_)
3384  {
3385  spec_.getPrecursors().back().setMetaValue(name, data_value);
3386  }
3387  else
3388  {
3389  chromatogram_.getPrecursor().setMetaValue(name, data_value);
3390  }
3391  }
3392  else if (parent_parent_tag == "product")
3393  {
3394  if (in_spectrum_list_)
3395  {
3396  spec_.getProducts().back().setMetaValue(name, data_value);
3397  }
3398  else
3399  {
3400  chromatogram_.getProduct().setMetaValue(name, data_value);
3401  }
3402  }
3403  }
3404  else if (parent_tag == "selectedIon")
3405  {
3406  //parse only the first selected ion
3407  if (selected_ion_count_ > 1)
3408  return;
3409 
3410  //We don't have this as a separate location => store it in the precursor
3411  if (in_spectrum_list_)
3412  {
3413  spec_.getPrecursors().back().setMetaValue(name, data_value);
3414  }
3415  else
3416  {
3417  chromatogram_.getPrecursor().setMetaValue(name, data_value);
3418  }
3419  }
3420  else if (parent_tag == "activation")
3421  {
3422  //We don't have this as a separate location => store it in the precursor
3423  if (in_spectrum_list_)
3424  {
3425  spec_.getPrecursors().back().setMetaValue(name, data_value);
3426  }
3427  else
3428  {
3429  chromatogram_.getPrecursor().setMetaValue(name, data_value);
3430  }
3431  }
3432  else if (parent_tag == "processingMethod")
3433  {
3434  processing_[current_id_].back().setMetaValue(name, data_value);
3435  }
3436  else if (parent_tag == "fileContent")
3437  {
3438  //exp_->setMetaValue(name, data_value);
3439  }
3440  else
3441  warning(LOAD, String("Unhandled userParam '") + name + "' in tag '" + parent_tag + "'.");
3442  }
3443 
3444  template <typename MapType>
3446  {
3448 
3449  sc.accession = c.id;
3450  sc.name = c.name;
3451  sc.has_unit_accession = false;
3452  sc.has_unit_name = false;
3453 
3454  return validator.SemanticValidator::locateTerm(path, sc);
3455  }
3456 
3457  template <typename MapType>
3459  {
3460  String cvTerm = "<cvParam cvRef=\"" + c.id.prefix(':') + "\" accession=\"" + c.id + "\" name=\"" + c.name;
3461  if (!metaValue.isEmpty())
3462  {
3463  cvTerm += "\" value=\"" + writeXMLEscape(metaValue.toString());
3464  if (metaValue.hasUnit())
3465  {
3466  // unitAccession="UO:0000021" unitName="gram" unitCvRef="UO"
3467  ControlledVocabulary::CVTerm unit = cv_.getTerm(metaValue.getUnit());
3468  cvTerm += "\" unitAccession=\"" + unit.id + "\" unitName=\"" + unit.name + "\" unitCvRef=\"" + unit.id.prefix(2);
3469  }
3470  }
3471  cvTerm += "\"/>\n";
3472  return cvTerm;
3473  }
3474 
3475  template <typename MapType>
3476  void MzMLHandler<MapType>::writeUserParam_(std::ostream& os, const MetaInfoInterface& meta, UInt indent, String path, Internal::MzMLValidator& validator) const
3477  {
3478  std::vector<String> cvParams;
3479  std::vector<String> userParams;
3480 
3481  std::vector<String> keys;
3482  meta.getKeys(keys);
3483 
3484  for (std::vector<String>::iterator key = keys.begin(); key != keys.end(); ++key)
3485  {
3486  // special treatment of GO and BTO terms
3487  // <cvParam cvRef="BTO" accession="BTO:0000199" name="cardiac muscle"/>
3488 
3489  if (*key == "GO cellular component" || *key == "brenda source tissue")
3490  {
3491  // the CVTerm info is in the value
3492  const DataValue& metaValue = meta.getMetaValue(*key);
3493 
3494  if (cv_.hasTermWithName((String) metaValue))
3495  {
3496  ControlledVocabulary::CVTerm c = cv_.getTermByName((String) metaValue);
3497 
3498  // TODO: validate CV, we currently cannot do this as the relations in the BTO and GO are not captured by our CV impl
3499  cvParams.push_back(writeCV_(c, DataValue::EMPTY));
3500  }
3501  }
3502  else
3503  {
3504 
3505  bool writtenAsCVTerm = false;
3506  if (cv_.hasTermWithName(*key))
3507  {
3508  ControlledVocabulary::CVTerm c = cv_.getTermByName(*key); // in cv_ write cvparam else write userparam
3509  if (validateCV_(c, path, validator))
3510  {
3511  // write CV
3512  cvParams.push_back(writeCV_(c, meta.getMetaValue(*key)));
3513  writtenAsCVTerm = true;
3514  }
3515  }
3516 
3517  // if we could not write it as CVTerm we will store it at least as userParam
3518  if (!writtenAsCVTerm)
3519  {
3520  String userParam = "<userParam name=\"" + *key + "\" type=\"";
3521 
3522  const DataValue& d = meta.getMetaValue(*key);
3523  //determine type
3524  if (d.valueType() == DataValue::INT_VALUE)
3525  {
3526  userParam += "xsd:integer";
3527  }
3528  else if (d.valueType() == DataValue::DOUBLE_VALUE)
3529  {
3530  userParam += "xsd:double";
3531  }
3532  else //string or lists are converted to string
3533  {
3534  userParam += "xsd:string";
3535  }
3536  userParam += "\" value=\"" + writeXMLEscape(d.toString()) + "\"/>" + "\n";
3537  userParams.push_back(userParam);
3538  }
3539  }
3540  }
3541 
3542  // write out all the cvParams and userParams in correct order
3543  for (std::vector<String>::iterator term = cvParams.begin(); term != cvParams.end(); ++term)
3544  {
3545  os << String(indent, '\t') << *term;
3546  }
3547 
3548  for (std::vector<String>::iterator term = userParams.begin(); term != userParams.end(); ++term)
3549  {
3550  os << String(indent, '\t') << *term;
3551  }
3552  }
3553 
3554  template <typename MapType>
3556  {
3557  std::set<String> terms;
3558  cv_.getAllChildTerms(terms, parent_accession);
3559  for (std::set<String>::const_iterator it = terms.begin(); it != terms.end(); ++it)
3560  {
3561  if (cv_.getTerm(*it).name == name)
3562  {
3563  return cv_.getTerm(*it);
3564  }
3565  }
3567  }
3568 
3569  template <typename MapType>
3570  void MzMLHandler<MapType>::writeSoftware_(std::ostream& os, const String& id, const Software& software, Internal::MzMLValidator& validator)
3571  {
3572  os << "\t\t<software id=\"" << id << "\" version=\"" << software.getVersion() << "\" >\n";
3573  ControlledVocabulary::CVTerm so_term = getChildWithName_("MS:1000531", software.getName());
3574  if (so_term.id == "")
3575  {
3576  so_term = getChildWithName_("MS:1000531", software.getName() + " software"); //act of desperation to find the right cv and keep compatible with older cv mzmls
3577  }
3578  if (so_term.id == "")
3579  {
3580  so_term = getChildWithName_("MS:1000531", "TOPP " + software.getName()); //act of desperation to find the right cv and keep compatible with older cv mzmls
3581  }
3582  if (so_term.id == "MS:1000799")
3583  {
3584  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000799\" name=\"custom unreleased software tool\" value=\"\" />\n";
3585  }
3586  else if (so_term.id != "")
3587  {
3588  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"" << so_term.id << "\" name=\"" << writeXMLEscape(so_term.name) << "\" />\n";
3589  }
3590  else
3591  {
3592  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000799\" name=\"custom unreleased software tool\" value=\"" << writeXMLEscape(software.getName()) << "\" />\n";
3593  }
3594  writeUserParam_(os, software, 3, "/mzML/Software/cvParam/@accession", validator);
3595  os << "\t\t</software>\n";
3596  }
3597 
3598  template <typename MapType>
3599  void MzMLHandler<MapType>::writeSourceFile_(std::ostream& os, const String& id, const SourceFile& source_file, Internal::MzMLValidator& validator)
3600  {
3601  os << "\t\t\t<sourceFile id=\"" << id << "\" name=\"" << writeXMLEscape(source_file.getNameOfFile()) << "\" location=\"" << writeXMLEscape(source_file.getPathToFile()) << "\">\n";
3602  //checksum
3603  if (source_file.getChecksumType() == SourceFile::SHA1)
3604  {
3605  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000569\" name=\"SHA-1\" value=\"" << source_file.getChecksum() << "\" />\n";
3606  }
3607  else if (source_file.getChecksumType() == SourceFile::MD5)
3608  {
3609  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000568\" name=\"MD5\" value=\"" << source_file.getChecksum() << "\" />\n";
3610  }
3611  else //FORCED
3612  {
3613  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000569\" name=\"SHA-1\" value=\"\" />\n";
3614  }
3615  //file type
3616  ControlledVocabulary::CVTerm ft_term = getChildWithName_("MS:1000560", source_file.getFileType());
3617  if (ft_term.id.empty() && source_file.getFileType().hasSuffix("file"))
3618  {
3619  ft_term = getChildWithName_("MS:1000560", source_file.getFileType().chop(4) + "format"); // this is born out of desperation that sourcefile has a string interface for its filetype and not the enum, which could have been easily manipulated to the updated cv
3620  }
3621  if (ft_term.id != "")
3622  {
3623  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << ft_term.id << "\" name=\"" << ft_term.name << "\" />\n";
3624  }
3625  else //FORCED
3626  {
3627  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000564\" name=\"PSI mzData format\" />\n";
3628  }
3629  //native ID format
3630  ControlledVocabulary::CVTerm id_term = getChildWithName_("MS:1000767", source_file.getNativeIDType());
3631  if (id_term.id != "")
3632  {
3633  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << id_term.id << "\" name=\"" << id_term.name << "\" />\n";
3634  }
3635  else //FORCED
3636  {
3637  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000777\" name=\"spectrum identifier nativeID format\" />\n";
3638  }
3639  writeUserParam_(os, source_file, 4, "/mzML/fileDescription/sourceFileList/sourceFile/cvParam/@accession", validator);
3640  os << "\t\t\t</sourceFile>\n";
3641  }
3642 
3643  template <typename MapType>
3644  void MzMLHandler<MapType>::writeDataProcessing_(std::ostream& os, const String& id, const std::vector<DataProcessing>& dps, Internal::MzMLValidator& validator)
3645  {
3646  os << "\t\t<dataProcessing id=\"" << id << "\">\n";
3647 
3648  //FORCED
3649  if (dps.empty())
3650  {
3651  os << "\t\t\t<processingMethod order=\"0\" softwareRef=\"so_default\">\n";
3652  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000544\" name=\"Conversion to mzML\" />\n";
3653  os << "\t\t\t\t<userParam name=\"warning\" type=\"xsd:string\" value=\"fictional processing method used to fulfill format requirements\" />\n";
3654  os << "\t\t\t</processingMethod>\n";
3655  }
3656 
3657  bool written = false;
3658  for (Size i = 0; i < dps.size(); ++i)
3659  {
3660  //data processing action
3661  os << "\t\t\t<processingMethod order=\"0\" softwareRef=\"so_" << id << "_pm_" << i << "\">\n";
3662  if (dps[i].getProcessingActions().count(DataProcessing::DATA_PROCESSING) == 1)
3663  {
3664  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000543\" name=\"data processing action\" />\n";
3665  written = true;
3666  }
3667  if (dps[i].getProcessingActions().count(DataProcessing::CHARGE_DECONVOLUTION) == 1)
3668  {
3669  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000034\" name=\"charge deconvolution\" />\n";
3670  written = true;
3671  }
3672  if (dps[i].getProcessingActions().count(DataProcessing::DEISOTOPING) == 1)
3673  {
3674  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000033\" name=\"deisotoping\" />\n";
3675  written = true;
3676  }
3677  if (dps[i].getProcessingActions().count(DataProcessing::SMOOTHING) == 1)
3678  {
3679  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000592\" name=\"smoothing\" />\n";
3680  written = true;
3681  }
3682  if (dps[i].getProcessingActions().count(DataProcessing::CHARGE_CALCULATION) == 1)
3683  {
3684  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000778\" name=\"charge state calculation\" />\n";
3685  written = true;
3686  }
3687  if (dps[i].getProcessingActions().count(DataProcessing::PRECURSOR_RECALCULATION) == 1)
3688  {
3689  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000780\" name=\"precursor recalculation\" />\n";
3690  written = true;
3691  }
3692  if (dps[i].getProcessingActions().count(DataProcessing::BASELINE_REDUCTION) == 1)
3693  {
3694  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000593\" name=\"baseline reduction\" />\n";
3695  written = true;
3696  }
3697  if (dps[i].getProcessingActions().count(DataProcessing::PEAK_PICKING) == 1)
3698  {
3699  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000035\" name=\"peak picking\" />\n";
3700  written = true;
3701  }
3702  if (dps[i].getProcessingActions().count(DataProcessing::ALIGNMENT) == 1)
3703  {
3704  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000745\" name=\"retention time alignment\" />\n";
3705  written = true;
3706  }
3707  if (dps[i].getProcessingActions().count(DataProcessing::CALIBRATION) == 1)
3708  {
3709  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001485\" name=\"m/z calibration\" />\n";
3710  written = true;
3711  }
3712  if (dps[i].getProcessingActions().count(DataProcessing::NORMALIZATION) == 1)
3713  {
3714  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001484\" name=\"intensity normalization\" />\n";
3715  written = true;
3716  }
3717  if (dps[i].getProcessingActions().count(DataProcessing::FILTERING) == 1)
3718  {
3719  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001486\" name=\"data filtering\" />\n";
3720  written = true;
3721  }
3722  //file format conversion
3723  if (dps[i].getProcessingActions().count(DataProcessing::FORMAT_CONVERSION) == 1)
3724  {
3725  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000530\" name=\"file format conversion\" />\n";
3726  written = true;
3727  }
3728  if (dps[i].getProcessingActions().count(DataProcessing::CONVERSION_MZDATA) == 1)
3729  {
3730  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000546\" name=\"Conversion to mzData\" />\n";
3731  written = true;
3732  }
3733  if (dps[i].getProcessingActions().count(DataProcessing::CONVERSION_MZML) == 1)
3734  {
3735  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000544\" name=\"Conversion to mzML\" />\n";
3736  written = true;
3737  }
3738  if (dps[i].getProcessingActions().count(DataProcessing::CONVERSION_MZXML) == 1)
3739  {
3740  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000545\" name=\"Conversion to mzXML\" />\n";
3741  written = true;
3742  }
3743  if (dps[i].getProcessingActions().count(DataProcessing::CONVERSION_DTA) == 1)
3744  {
3745  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000741\" name=\"Conversion to dta\" />\n";
3746  written = true;
3747  }
3748  if (!written)
3749  {
3750  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000543\" name=\"data processing action\" />\n";
3751  }
3752 
3753  //data processing attribute
3754  if (dps[i].getCompletionTime().isValid())
3755  {
3756  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000747\" name=\"completion time\" value=\"" << dps[i].getCompletionTime().toString("yyyy-MM-dd+hh:mm").toStdString() << "\" />\n";
3757  }
3758 
3759  writeUserParam_(os, dps[i], 4, "/mzML/dataProcessingList/dataProcessing/processingMethod/cvParam/@accession", validator);
3760  os << "\t\t\t</processingMethod>\n";
3761  }
3762 
3763  os << "\t\t</dataProcessing>\n";
3764  }
3765 
3766  template <typename MapType>
3767  void MzMLHandler<MapType>::writePrecursor_(std::ostream& os, const Precursor& precursor, Internal::MzMLValidator& validator)
3768  {
3769  os << "\t\t\t\t\t<precursor>\n";
3770  //--------------------------------------------------------------------------------------------
3771  //isolation window
3772  //--------------------------------------------------------------------------------------------
3773  os << "\t\t\t\t\t\t<isolationWindow>\n";
3774  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000827\" name=\"isolation window target m/z\" value=\"" << precursor.getMZ() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3775  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000828\" name=\"isolation window lower offset\" value=\"" << precursor.getIsolationWindowLowerOffset() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3776  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000829\" name=\"isolation window upper offset\" value=\"" << precursor.getIsolationWindowUpperOffset() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3777  os << "\t\t\t\t\t\t</isolationWindow>\n";
3778  //userParam: no extra object for it => no user parameters
3779 
3780  //--------------------------------------------------------------------------------------------
3781  //selected ion list
3782  //--------------------------------------------------------------------------------------------
3783  os << "\t\t\t\t\t\t<selectedIonList count=\"1\">\n";
3784  os << "\t\t\t\t\t\t\t<selectedIon>\n";
3785  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000744\" name=\"selected ion m/z\" value=\"" << precursor.getMZ() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3786  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000041\" name=\"charge state\" value=\"" << precursor.getCharge() << "\" />\n";
3787  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000042\" name=\"peak intensity\" value=\"" << precursor.getIntensity() << "\" unitAccession=\"MS:1000132\" unitName=\"percent of base peak\" unitCvRef=\"MS\" />\n";
3788  for (Size j = 0; j < precursor.getPossibleChargeStates().size(); ++j)
3789  {
3790  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000633\" name=\"possible charge state\" value=\"" << precursor.getPossibleChargeStates()[j] << "\" />\n";
3791  }
3792  //userParam: no extra object for it => no user parameters
3793  os << "\t\t\t\t\t\t\t</selectedIon>\n";
3794  os << "\t\t\t\t\t\t</selectedIonList>\n";
3795 
3796  //--------------------------------------------------------------------------------------------
3797  //activation
3798  //--------------------------------------------------------------------------------------------
3799  os << "\t\t\t\t\t\t<activation>\n";
3800 #pragma clang diagnostic push
3801 #pragma clang diagnostic ignored "-Wfloat-equal"
3802  if (precursor.getActivationEnergy() != 0)
3803 #pragma clang diagnostic pop
3804  {
3805  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000509\" name=\"activation energy\" value=\"" << precursor.getActivationEnergy() << "\" unitAccession=\"UO:0000266\" unitName=\"electronvolt\" unitCvRef=\"UO\" />\n";
3806  }
3807  if (precursor.getActivationMethods().count(Precursor::CID) != 0)
3808  {
3809  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000133\" name=\"collision-induced dissociation\" />\n";
3810  }
3811  if (precursor.getActivationMethods().count(Precursor::PD) != 0)
3812  {
3813  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000134\" name=\"plasma desorption\" />\n";
3814  }
3815  if (precursor.getActivationMethods().count(Precursor::PSD) != 0)
3816  {
3817  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000135\" name=\"post-source decay\" />\n";
3818  }
3819  if (precursor.getActivationMethods().count(Precursor::SID) != 0)
3820  {
3821  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000136\" name=\"surface-induced dissociation\" />\n";
3822  }
3823  if (precursor.getActivationMethods().count(Precursor::BIRD) != 0)
3824  {
3825  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000242\" name=\"blackbody infrared radiative dissociation\" />\n";
3826  }
3827  if (precursor.getActivationMethods().count(Precursor::ECD) != 0)
3828  {
3829  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000250\" name=\"electron capture dissociation\" />\n";
3830  }
3831  if (precursor.getActivationMethods().count(Precursor::IMD) != 0)
3832  {
3833  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000262\" name=\"infrared multiphoton dissociation\" />\n";
3834  }
3835  if (precursor.getActivationMethods().count(Precursor::SORI) != 0)
3836  {
3837  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000282\" name=\"sustained off-resonance irradiation\" />\n";
3838  }
3839  if (precursor.getActivationMethods().count(Precursor::HCID) != 0)
3840  {
3841  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000422\" name=\"high-energy collision-induced dissociation\" />\n";
3842  }
3843  if (precursor.getActivationMethods().count(Precursor::LCID) != 0)
3844  {
3845  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000433\" name=\"low-energy collision-induced dissociation\" />\n";
3846  }
3847  if (precursor.getActivationMethods().count(Precursor::PHD) != 0)
3848  {
3849  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000435\" name=\"photodissociation\" />\n";
3850  }
3851  if (precursor.getActivationMethods().count(Precursor::ETD) != 0)
3852  {
3853  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000598\" name=\"electron transfer dissociation\" />\n";
3854  }
3855  if (precursor.getActivationMethods().count(Precursor::PQD) != 0)
3856  {
3857  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000599\" name=\"pulsed q dissociation\" />\n";
3858  }
3859  if (precursor.getActivationMethods().empty())
3860  {
3861  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000044\" name=\"dissociation method\" />\n";
3862  }
3863  //as "precursor" has no own user param its userParam is stored here
3864  writeUserParam_(os, precursor, 6, "/mzML/run/spectrumList/spectrum/precursorList/precursor/activation/cvParam/@accession", validator);
3865  os << "\t\t\t\t\t\t</activation>\n";
3866  os << "\t\t\t\t\t</precursor>\n";
3867 
3868  }
3869 
3870  template <typename MapType>
3871  void MzMLHandler<MapType>::writeProduct_(std::ostream& os, const Product& product, Internal::MzMLValidator& validator)
3872  {
3873  os << "\t\t\t\t\t<product>\n";
3874  os << "\t\t\t\t\t\t<isolationWindow>\n";
3875  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000827\" name=\"isolation window target m/z\" value=\"" << product.getMZ() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3876  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000828\" name=\"isolation window lower offset\" value=\"" << product.getIsolationWindowLowerOffset() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3877  os << "\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000829\" name=\"isolation window upper offset\" value=\"" << product.getIsolationWindowUpperOffset() << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
3878  writeUserParam_(os, product, 7, "/mzML/run/spectrumList/spectrum/productList/product/isolationWindow/cvParam/@accession", validator);
3879  os << "\t\t\t\t\t\t</isolationWindow>\n";
3880  os << "\t\t\t\t\t</product>\n";
3881  }
3882 
3883  template <typename MapType>
3884  void MzMLHandler<MapType>::writeTo(std::ostream& os)
3885  {
3886  const MapType& exp = *(cexp_);
3887  logger_.startProgress(0, exp.size() + exp.getChromatograms().size(), "storing mzML file");
3888  int progress = 0;
3889  Internal::MzMLValidator validator(mapping_, cv_);
3890 
3891  std::vector<std::vector<DataProcessing> > dps;
3892  //--------------------------------------------------------------------------------------------
3893  //header
3894  //--------------------------------------------------------------------------------------------
3895  writeHeader_(os, exp, dps, validator);
3896 
3897  //--------------------------------------------------------------------------------------------
3898  //spectrum
3899  //--------------------------------------------------------------------------------------------
3900  if (exp.size() != 0)
3901  {
3902  // INFO : do not try to be smart and skip empty spectra or
3903  // chromatograms. There can be very good reasons for this (e.g. if the
3904  // meta information needs to be stored here but the actual data is
3905  // stored somewhere else).
3906  os << "\t\t<spectrumList count=\"" << exp.size() << "\" defaultDataProcessingRef=\"dp_sp_0\">\n";
3907 
3908  //check native ids
3909  bool renew_native_ids = false;
3910  for (Size s = 0; s < exp.size(); ++s)
3911  {
3912  if (!exp[s].getNativeID().has('='))
3913  {
3914  renew_native_ids = true;
3915  break;
3916  }
3917  }
3918  //issue warning if something is wrong
3919  if (renew_native_ids)
3920  {
3921  warning(STORE, String("Invalid native IDs detected. Using spectrum identifier nativeID format (spectrum=xsd:nonNegativeInteger) for all spectra."));
3922  }
3923 
3924  //write actual data
3925  for (Size s = 0; s < exp.size(); ++s)
3926  {
3927  logger_.setProgress(progress++);
3928  const SpectrumType& spec = exp[s];
3929  writeSpectrum_(os, spec, s, validator, renew_native_ids, dps);
3930  }
3931  os << "\t\t</spectrumList>\n";
3932  }
3933 
3934  //--------------------------------------------------------------------------------------------
3935  //chromatograms
3936  //--------------------------------------------------------------------------------------------
3937  if (!exp.getChromatograms().empty())
3938  {
3939  // INFO : do not try to be smart and skip empty spectra or
3940  // chromatograms. There can be very good reasons for this (e.g. if the
3941  // meta information needs to be stored here but the actual data is
3942  // stored somewhere else).
3943  os << "\t\t<chromatogramList count=\"" << exp.getChromatograms().size() << "\" defaultDataProcessingRef=\"dp_sp_0\">\n";
3944  for (Size c = 0; c != exp.getChromatograms().size(); ++c)
3945  {
3946  logger_.setProgress(progress++);
3947  const ChromatogramType& chromatogram = exp.getChromatograms()[c];
3948  writeChromatogram_(os, chromatogram, c, validator);
3949  }
3950  os << "\t\t</chromatogramList>" << "\n";
3951  }
3952 
3953  MzMLHandlerHelper::writeFooter_(os, options_, spectra_offsets, chromatograms_offsets);
3954  logger_.endProgress();
3955  }
3956 
3957  template <typename MapType>
3958  void MzMLHandler<MapType>::writeHeader_(std::ostream& os, const MapType& exp,
3959  std::vector<std::vector<DataProcessing> >& dps, Internal::MzMLValidator& validator)
3960  {
3961  os << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
3962 
3963  if (options_.getWriteIndex())
3964  {
3965  os << "<indexedmzML xmlns=\"http://psi.hupo.org/ms/mzml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://psi.hupo.org/ms/mzml http://psidev.info/files/ms/mzML/xsd/mzML1.1.0_idx.xsd\">\n";
3966  }
3967  os << "<mzML xmlns=\"http://psi.hupo.org/ms/mzml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://psi.hupo.org/ms/mzml http://psidev.info/files/ms/mzML/xsd/mzML1.1.0.xsd\" accession=\"" << writeXMLEscape(exp.getIdentifier()) << "\" version=\"" << version_ << "\">\n";
3968  //--------------------------------------------------------------------------------------------
3969  // CV list
3970  //--------------------------------------------------------------------------------------------
3971  os << "\t<cvList count=\"5\">\n"
3972  << "\t\t<cv id=\"MS\" fullName=\"Proteomics Standards Initiative Mass Spectrometry Ontology\" URI=\"http://psidev.cvs.sourceforge.net/*checkout*/psidev/psi/psi-ms/mzML/controlledVocabulary/psi-ms.obo\"/>\n"
3973  << "\t\t<cv id=\"UO\" fullName=\"Unit Ontology\" URI=\"http://obo.cvs.sourceforge.net/obo/obo/ontology/phenotype/unit.obo\"/>\n"
3974  << "\t\t<cv id=\"BTO\" fullName=\"BrendaTissue545\" version=\"unknown\" URI=\"http://www.brenda-enzymes.info/ontology/tissue/tree/update/update_files/BrendaTissueOBO\"/>\n"
3975  << "\t\t<cv id=\"GO\" fullName=\"Gene Ontology - Slim Versions\" version=\"unknown\" URI=\"http://www.geneontology.org/GO_slims/goslim_goa.obo\"/>\n"
3976  << "\t\t<cv id=\"PATO\" fullName=\"Quality ontology\" version=\"unknown\" URI=\"http://obo.cvs.sourceforge.net/*checkout*/obo/obo/ontology/phenotype/quality.obo\"/>\n"
3977  << "\t</cvList>\n";
3978  //--------------------------------------------------------------------------------------------
3979  // file content
3980  //--------------------------------------------------------------------------------------------
3981  os << "\t<fileDescription>\n";
3982  os << "\t\t<fileContent>\n";
3984  for (Size i = 0; i < exp.size(); ++i)
3985  {
3986  ++file_content[exp[i].getInstrumentSettings().getScanMode()];
3987  }
3988  if (file_content.has(InstrumentSettings::MASSSPECTRUM))
3989  {
3990  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000294\" name=\"mass spectrum\" />\n";
3991  }
3992  if (file_content.has(InstrumentSettings::MS1SPECTRUM))
3993  {
3994  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000579\" name=\"MS1 spectrum\" />\n";
3995  }
3996  if (file_content.has(InstrumentSettings::MSNSPECTRUM))
3997  {
3998  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000580\" name=\"MSn spectrum\" />\n";
3999  }
4000  if (file_content.has(InstrumentSettings::SIM))
4001  {
4002  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000582\" name=\"SIM spectrum\" />\n";
4003  }
4004  if (file_content.has(InstrumentSettings::SRM))
4005  {
4006  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000583\" name=\"SRM spectrum\" />\n";
4007  }
4008  if (file_content.has(InstrumentSettings::CRM))
4009  {
4010  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000581\" name=\"CRM spectrum\" />\n";
4011  }
4012  if (file_content.has(InstrumentSettings::PRECURSOR))
4013  {
4014  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000341\" name=\"precursor ion spectrum\" />\n";
4015  }
4016  if (file_content.has(InstrumentSettings::CNG))
4017  {
4018  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000325\" name=\"constant neutral gain spectrum\" />\n";
4019  }
4020  if (file_content.has(InstrumentSettings::CNL))
4021  {
4022  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000326\" name=\"constant neutral loss spectrum\" />\n";
4023  }
4024  if (file_content.has(InstrumentSettings::EMR))
4025  {
4026  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000804\" name=\"electromagnetic radiation spectrum\" />\n";
4027  }
4028  if (file_content.has(InstrumentSettings::EMISSION))
4029  {
4030  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000805\" name=\"emission spectrum\" />\n";
4031  }
4032  if (file_content.has(InstrumentSettings::ABSORBTION))
4033  {
4034  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000806\" name=\"absorption spectrum\" />\n";
4035  }
4036  if (file_content.has(InstrumentSettings::EMC))
4037  {
4038  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000789\" name=\"enhanced multiply charged spectrum\" />\n";
4039  }
4040  if (file_content.has(InstrumentSettings::TDF))
4041  {
4042  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000789\" name=\"time-delayed fragmentation spectrum\" />\n";
4043  }
4044  if (file_content.has(InstrumentSettings::UNKNOWN) || file_content.empty())
4045  {
4046  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000294\" name=\"mass spectrum\" />\n";
4047  }
4048  // writeUserParam_(os, exp, 3, "/mzML/fileDescription/fileContent/cvParam/@accession", validator);
4049  os << "\t\t</fileContent>\n";
4050 
4051  //--------------------------------------------------------------------------------------------
4052  // source file list
4053  //--------------------------------------------------------------------------------------------
4054  //find out how many spectra source files need to be written
4055  UInt sf_sp_count = 0;
4056  for (Size i = 0; i < exp.size(); ++i)
4057  {
4058  if (exp[i].getSourceFile() != SourceFile())
4059  {
4060  ++sf_sp_count;
4061  }
4062  }
4063  if (exp.getSourceFiles().size() > 0 || sf_sp_count > 0)
4064  {
4065  os << "\t\t<sourceFileList count=\"" << exp.getSourceFiles().size() + sf_sp_count << "\">\n";
4066 
4067  //write source file of run
4068  for (Size i = 0; i < exp.getSourceFiles().size(); ++i)
4069  {
4070  writeSourceFile_(os, String("sf_ru_") + String(i), exp.getSourceFiles()[i], validator);
4071  }
4072 
4073  // write source files of spectra
4074  if (sf_sp_count > 0)
4075  {
4076  const SourceFile sf_default;
4077  for (Size i = 0; i < exp.size(); ++i)
4078  {
4079  if (exp[i].getSourceFile() != sf_default)
4080  {
4081  writeSourceFile_(os, String("sf_sp_") + i, exp[i].getSourceFile(), validator);
4082  }
4083  }
4084  }
4085 
4086  os << "\t\t</sourceFileList>\n";
4087  }
4088 
4089  //--------------------------------------------------------------------------------------------
4090  // contacts
4091  //--------------------------------------------------------------------------------------------
4092  for (Size i = 0; i < exp.getContacts().size(); ++i)
4093  {
4094  const ContactPerson& cp = exp.getContacts()[i];
4095  os << "\t\t<contact>\n";
4096  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000586\" name=\"contact name\" value=\"" << writeXMLEscape(cp.getLastName()) << ", " << writeXMLEscape(cp.getFirstName()) << "\" />\n";
4097  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000590\" name=\"contact affiliation\" value=\"" << writeXMLEscape(cp.getInstitution()) << "\" />\n";
4098 
4099  if (cp.getAddress() != "")
4100  {
4101  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000587\" name=\"contact address\" value=\"" << writeXMLEscape(cp.getAddress()) << "\" />\n";
4102  }
4103  if (cp.getURL() != "")
4104  {
4105  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000588\" name=\"contact URL\" value=\"" << writeXMLEscape(cp.getURL()) << "\" />\n";
4106  }
4107  if (cp.getEmail() != "")
4108  {
4109  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000589\" name=\"contact email\" value=\"" << writeXMLEscape(cp.getEmail()) << "\" />\n";
4110  }
4111  if (cp.getContactInfo() != "")
4112  {
4113  os << "\t\t\t<userParam name=\"contact_info\" type=\"xsd:string\" value=\"" << writeXMLEscape(cp.getContactInfo()) << "\" />\n";
4114  }
4115  writeUserParam_(os, cp, 3, "/mzML/fileDescription/contact/cvParam/@accession", validator);
4116  os << "\t\t</contact>\n";
4117  }
4118  os << "\t</fileDescription>\n";
4119 
4120  //--------------------------------------------------------------------------------------------
4121  // sample
4122  //--------------------------------------------------------------------------------------------
4123  const Sample& sa = exp.getSample();
4124  os << "\t<sampleList count=\"1\">\n";
4125  os << "\t\t<sample id=\"sa_0\" name=\"" << writeXMLEscape(sa.getName()) << "\">\n";
4126  if (sa.getNumber() != "")
4127  {
4128  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000001\" name=\"sample number\" value=\"" << writeXMLEscape(sa.getNumber()) << "\" />\n";
4129  }
4130  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000004\" name=\"sample mass\" value=\"" << sa.getMass() << "\" unitAccession=\"UO:0000021\" unitName=\"gram\" unitCvRef=\"UO\" />\n";
4131  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000005\" name=\"sample volume\" value=\"" << sa.getVolume() << "\" unitAccession=\"UO:0000098\" unitName=\"milliliter\" unitCvRef=\"UO\" />\n";
4132  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000006\" name=\"sample concentration\" value=\"" << sa.getConcentration() << "\" unitAccession=\"UO:0000175\" unitName=\"gram per liter\" unitCvRef=\"UO\" />\n";
4133  if (sa.getState() == Sample::EMULSION)
4134  {
4135  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000047\" name=\"emulsion\" />\n";
4136  }
4137  else if (sa.getState() == Sample::GAS)
4138  {
4139  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000048\" name=\"gas\" />\n";
4140  }
4141  else if (sa.getState() == Sample::LIQUID)
4142  {
4143  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000049\" name=\"liquid\" />\n";
4144  }
4145  else if (sa.getState() == Sample::SOLID)
4146  {
4147  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000050\" name=\"solid\" />\n";
4148  }
4149  else if (sa.getState() == Sample::SOLUTION)
4150  {
4151  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000051\" name=\"solution\" />\n";
4152  }
4153  else if (sa.getState() == Sample::SUSPENSION)
4154  {
4155  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000052\" name=\"suspension\" />\n";
4156  }
4157  if (sa.getComment() != "")
4158  {
4159  os << "\t\t\t<userParam name=\"comment\" type=\"xsd:string\" value=\"" << writeXMLEscape(sa.getComment()) << "\" />\n";
4160  }
4161  writeUserParam_(os, sa, 3, "/mzML/sampleList/sample/cvParam/@accession", validator);
4162  os << "\t\t</sample>\n";
4163  os << "\t</sampleList>\n";
4164 
4165  //--------------------------------------------------------------------------------------------
4166  // software
4167  //--------------------------------------------------------------------------------------------
4168 
4169  // create a list of all different data processings
4170  Size num_software(2); // instrument software is always written
4171  for (Size s = 0; s < exp.size(); ++s)
4172  {
4173  if (find(dps.begin(), dps.end(), exp[s].getDataProcessing()) == dps.end())
4174  {
4175  dps.push_back(exp[s].getDataProcessing());
4176  num_software += exp[s].getDataProcessing().size();
4177  }
4178  }
4179  for (Size s = 0; s < exp.getChromatograms().size(); ++s)
4180  {
4181  if (find(dps.begin(), dps.end(), exp.getChromatograms()[s].getDataProcessing()) == dps.end())
4182  {
4183  dps.push_back(exp.getChromatograms()[s].getDataProcessing());
4184  num_software += exp.getChromatograms()[s].getDataProcessing().size();
4185  }
4186  }
4187 
4188  // count binary data array software
4189  Size num_bi_software(0);
4190 
4191  for (Size s = 0; s < exp.size(); ++s)
4192  {
4193  for (Size m = 0; m < exp[s].getFloatDataArrays().size(); ++m)
4194  {
4195  for (Size i = 0; i < exp[s].getFloatDataArrays()[m].getDataProcessing().size(); ++i)
4196  {
4197  ++num_bi_software;
4198  }
4199  }
4200  }
4201 
4202  os << "\t<softwareList count=\"" << num_software + num_bi_software << "\">\n";
4203  //write instrument software
4204  writeSoftware_(os, "so_in_0", exp.getInstrument().getSoftware(), validator);
4205 
4206  //write fallback software
4207  writeSoftware_(os, "so_default", Software(), validator);
4208 
4209  // write the software of the dps
4210  for (Size s1 = 0; s1 != dps.size(); ++s1)
4211  {
4212  for (Size s2 = 0; s2 != dps[s1].size(); ++s2)
4213  {
4214  writeSoftware_(os, String("so_dp_sp_") + s1 + "_pm_" + s2, dps[s1][s2].getSoftware(), validator);
4215  }
4216  }
4217 
4218  //write data processing (for each binary data array)
4219  for (Size s = 0; s < exp.size(); ++s)
4220  {
4221  for (Size m = 0; m < exp[s].getFloatDataArrays().size(); ++m)
4222  {
4223  for (Size i = 0; i < exp[s].getFloatDataArrays()[m].getDataProcessing().size(); ++i)
4224  {
4225  writeSoftware_(os, String("so_dp_sp_") + s + "_bi_" + m + "_pm_" + i, exp[s].getFloatDataArrays()[m].getDataProcessing()[i].getSoftware(), validator);
4226  }
4227  }
4228  }
4229  os << "\t</softwareList>\n";
4230 
4231  //--------------------------------------------------------------------------------------------
4232  // instrument configuration (enclosing ion source, mass analyzer and detector)
4233  //--------------------------------------------------------------------------------------------
4234  const Instrument& in = exp.getInstrument();
4235  os << "\t<instrumentConfigurationList count=\"1\">\n";
4236  os << "\t\t<instrumentConfiguration id=\"ic_0\">\n";
4237  ControlledVocabulary::CVTerm in_term = getChildWithName_("MS:1000031", in.getName());
4238  if (in_term.id != "")
4239  {
4240  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"" << in_term.id << "\" name=\"" << writeXMLEscape(in_term.name) << "\" />\n";
4241  }
4242  else
4243  {
4244  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000031\" name=\"instrument model\" />\n";
4245  }
4246 
4247  if (in.getCustomizations() != "")
4248  {
4249  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000032\" name=\"customization\" value=\"" << writeXMLEscape(in.getCustomizations()) << "\" />\n";
4250  }
4251 
4252  //ion optics
4254  {
4255  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000221\" name=\"magnetic deflection\" />\n";
4256  }
4258  {
4259  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000246\" name=\"delayed extraction\" />\n";
4260  }
4262  {
4263  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000275\" name=\"collision quadrupole\" />\n";
4264  }
4266  {
4267  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000281\" name=\"selected ion flow tube\" />\n";
4268  }
4270  {
4271  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000286\" name=\"time lag focusing\" />\n";
4272  }
4273  else if (in.getIonOptics() == Instrument::REFLECTRON)
4274  {
4275  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000300\" name=\"reflectron\" />\n";
4276  }
4277  else if (in.getIonOptics() == Instrument::EINZEL_LENS)
4278  {
4279  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000307\" name=\"einzel lens\" />\n";
4280  }
4282  {
4283  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000309\" name=\"first stability region\" />\n";
4284  }
4285  else if (in.getIonOptics() == Instrument::FRINGING_FIELD)
4286  {
4287  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000310\" name=\"fringing field\" />\n";
4288  }
4290  {
4291  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000311\" name=\"kinetic energy analyzer\" />\n";
4292  }
4293  else if (in.getIonOptics() == Instrument::STATIC_FIELD)
4294  {
4295  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000320\" name=\"static field\" />\n";
4296  }
4297 
4298  writeUserParam_(os, in, 3, "/mzML/instrumentConfigurationList/instrumentConfiguration/cvParam/@accession", validator);
4299  Size component_count = in.getIonSources().size() + in.getMassAnalyzers().size() + in.getIonDetectors().size();
4300  if (component_count != 0)
4301  {
4302  os << "\t\t\t<componentList count=\"" << (std::max)((Size)3, component_count) << "\">\n";
4303  //--------------------------------------------------------------------------------------------
4304  // ion source
4305  //--------------------------------------------------------------------------------------------
4306  for (Size i = 0; i < in.getIonSources().size(); ++i)
4307  {
4308  const IonSource& so = in.getIonSources()[i];
4309  os << "\t\t\t\t<source order=\"" << so.getOrder() << "\">\n";
4310 
4312  {
4313  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000055\" name=\"continuous flow fast atom bombardment\" />\n";
4314  }
4315  else if (so.getInletType() == IonSource::DIRECT)
4316  {
4317  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000056\" name=\"direct inlet\" />\n";
4318  }
4319  else if (so.getInletType() == IonSource::ELECTROSPRAYINLET)
4320  {
4321  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000057\" name=\"electrospray inlet\" />\n";
4322  }
4324  {
4325  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000058\" name=\"flow injection analysis\" />\n";
4326  }
4328  {
4329  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000059\" name=\"inductively coupled plasma\" />\n";
4330  }
4331  else if (so.getInletType() == IonSource::INFUSION)
4332  {
4333  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000060\" name=\"infusion\" />\n";
4334  }
4335  else if (so.getInletType() == IonSource::JETSEPARATOR)
4336  {
4337  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000061\" name=\"jet separator\" />\n";
4338  }
4339  else if (so.getInletType() == IonSource::MEMBRANESEPARATOR)
4340  {
4341  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000062\" name=\"membrane separator\" />\n";
4342  }
4343  else if (so.getInletType() == IonSource::MOVINGBELT)
4344  {
4345  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000063\" name=\"moving belt\" />\n";
4346  }
4347  else if (so.getInletType() == IonSource::MOVINGWIRE)
4348  {
4349  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000064\" name=\"moving wire\" />\n";
4350  }
4351  else if (so.getInletType() == IonSource::OPENSPLIT)
4352  {
4353  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000065\" name=\"open split\" />\n";
4354  }
4355  else if (so.getInletType() == IonSource::PARTICLEBEAM)
4356  {
4357  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000066\" name=\"particle beam\" />\n";
4358  }
4359  else if (so.getInletType() == IonSource::RESERVOIR)
4360  {
4361  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000067\" name=\"reservoir\" />\n";
4362  }
4363  else if (so.getInletType() == IonSource::SEPTUM)
4364  {
4365  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000068\" name=\"septum\" />\n";
4366  }
4367  else if (so.getInletType() == IonSource::THERMOSPRAYINLET)
4368  {
4369  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000069\" name=\"thermospray inlet\" />\n";
4370  }
4371  else if (so.getInletType() == IonSource::BATCH)
4372  {
4373  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000248\" name=\"direct insertion probe\" />\n";
4374  }
4375  else if (so.getInletType() == IonSource::CHROMATOGRAPHY)
4376  {
4377  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000249\" name=\"direct liquid introduction\" />\n";
4378  }
4379  else if (so.getInletType() == IonSource::MEMBRANE)
4380  {
4381  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000396\" name=\"membrane inlet\" />\n";
4382  }
4383  else if (so.getInletType() == IonSource::NANOSPRAY)
4384  {
4385  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000485\" name=\"nanospray inlet\" />\n";
4386  }
4387 
4389  {
4390  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000070\" name=\"atmospheric pressure chemical ionization\" />\n";
4391  }
4392  else if (so.getIonizationMethod() == IonSource::CI)
4393  {
4394  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000071\" name=\"chemical ionization\" />\n";
4395  }
4396  else if (so.getIonizationMethod() == IonSource::ESI)
4397  {
4398  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000073\" name=\"electrospray ionization\" />\n";
4399  }
4400  else if (so.getIonizationMethod() == IonSource::FAB)
4401  {
4402  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000074\" name=\"fast atom bombardment ionization\" />\n";
4403  }
4404  else if (so.getIonizationMethod() == IonSource::MALDI)
4405  {
4406  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000075\" name=\"matrix-assisted laser desorption ionization\" />\n";
4407  }
4408  else if (so.getIonizationMethod() == IonSource::MPI)
4409  {
4410  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000227\" name=\"multiphoton ionization\" />\n";
4411  }
4412  else if (so.getIonizationMethod() == IonSource::AP_MALDI)
4413  {
4414  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000239\" name=\"atmospheric pressure matrix-assisted laser desorption ionization\" />\n";
4415  }
4416  else if (so.getIonizationMethod() == IonSource::API)
4417  {
4418  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000240\" name=\"atmospheric pressure ionization\" />\n";
4419  }
4420  else if (so.getIonizationMethod() == IonSource::DI)
4421  {
4422  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000247\" name=\"desorption ionization\" />\n";
4423  }
4424  else if (so.getIonizationMethod() == IonSource::FA)
4425  {
4426  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000255\" name=\"flowing afterglow\" />\n";
4427  }
4428  else if (so.getIonizationMethod() == IonSource::FD)
4429  {
4430  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000257\" name=\"field desorption\" />\n";
4431  }
4432  else if (so.getIonizationMethod() == IonSource::FI)
4433  {
4434  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000258\" name=\"field ionization\" />\n";
4435  }
4436  else if (so.getIonizationMethod() == IonSource::GD_MS)
4437  {
4438  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000259\" name=\"glow discharge ionization\" />\n";
4439  }
4440  else if (so.getIonizationMethod() == IonSource::NICI)
4441  {
4442  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000271\" name=\"Negative ion chemical ionization\" />\n";
4443  }
4444  else if (so.getIonizationMethod() == IonSource::NRMS)
4445  {
4446  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000272\" name=\"neutralization reionization mass spectrometry\" />\n";
4447  }
4448  else if (so.getIonizationMethod() == IonSource::PI)
4449  {
4450  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000273\" name=\"photoionization\" />\n";
4451  }
4452  else if (so.getIonizationMethod() == IonSource::PYMS)
4453  {
4454  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000274\" name=\"pyrolysis mass spectrometry\" />\n";
4455  }
4456  else if (so.getIonizationMethod() == IonSource::REMPI)
4457  {
4458  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000276\" name=\"resonance enhanced multiphoton ionization\" />\n";
4459  }
4460  else if (so.getIonizationMethod() == IonSource::SELDI)
4461  {
4462  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000278\" name=\"surface enhanced laser desorption ionization\" />\n";
4463  }
4464  else if (so.getIonizationMethod() == IonSource::SEND)
4465  {
4466  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000279\" name=\"surface enhanced neat desorption\" />\n";
4467  }
4468  else if (so.getIonizationMethod() == IonSource::AI)
4469  {
4470  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000380\" name=\"adiabatic ionization\" />\n";
4471  }
4472  else if (so.getIonizationMethod() == IonSource::ASI)
4473  {
4474  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000381\" name=\"associative ionization\" />\n";
4475  }
4476  else if (so.getIonizationMethod() == IonSource::APPI)
4477  {
4478  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000382\" name=\"atmospheric pressure photoionization\" />\n";
4479  }
4480  else if (so.getIonizationMethod() == IonSource::AD)
4481  {
4482  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000383\" name=\"autodetachment\" />\n";
4483  }
4484  else if (so.getIonizationMethod() == IonSource::AUI)
4485  {
4486  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000384\" name=\"autoionization\" />\n";
4487  }
4488  else if (so.getIonizationMethod() == IonSource::CEI)
4489  {
4490  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000385\" name=\"charge exchange ionization\" />\n";
4491  }
4492  else if (so.getIonizationMethod() == IonSource::CHEMI)
4493  {
4494  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000386\" name=\"chemi-ionization\" />\n";
4495  }
4496  else if (so.getIonizationMethod() == IonSource::SILI)
4497  {
4498  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000387\" name=\"desorption/ionization on silicon\" />\n";
4499  }
4500  else if (so.getIonizationMethod() == IonSource::DISSI)
4501  {
4502  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000388\" name=\"dissociative ionization\" />\n";
4503  }
4504  else if (so.getIonizationMethod() == IonSource::EI)
4505  {
4506  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000389\" name=\"electron ionization\" />\n";
4507  }
4508  else if (so.getIonizationMethod() == IonSource::LD)
4509  {
4510  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000393\" name=\"laser desorption ionization\" />\n";
4511  }
4512  else if (so.getIonizationMethod() == IonSource::LSI)
4513  {
4514  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000395\" name=\"liquid secondary ionization\" />\n";
4515  }
4516  else if (so.getIonizationMethod() == IonSource::MESI)
4517  {
4518  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000397\" name=\"microelectrospray\" />\n";
4519  }
4520  else if (so.getIonizationMethod() == IonSource::NESI)
4521  {
4522  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000398\" name=\"nanoelectrospray\" />\n";
4523  }
4524  else if (so.getIonizationMethod() == IonSource::PEI)
4525  {
4526  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000399\" name=\"penning ionization\" />\n";
4527  }
4528  else if (so.getIonizationMethod() == IonSource::PD)
4529  {
4530  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000400\" name=\"plasma desorption ionization\" />\n";
4531  }
4532  else if (so.getIonizationMethod() == IonSource::SI)
4533  {
4534  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000402\" name=\"secondary ionization\" />\n";
4535  }
4536  else if (so.getIonizationMethod() == IonSource::SOI)
4537  {
4538  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000403\" name=\"soft ionization\" />\n";
4539  }
4540  else if (so.getIonizationMethod() == IonSource::SPI)
4541  {
4542  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000404\" name=\"spark ionization\" />\n";
4543  }
4544  else if (so.getIonizationMethod() == IonSource::SALDI)
4545  {
4546  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000405\" name=\"surface-assisted laser desorption ionization\" />\n";
4547  }
4548  else if (so.getIonizationMethod() == IonSource::SUI)
4549  {
4550  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000406\" name=\"surface ionization\" />\n";
4551  }
4552  else if (so.getIonizationMethod() == IonSource::TI)
4553  {
4554  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000407\" name=\"thermal ionization\" />\n";
4555  }
4556  else if (so.getIonizationMethod() == IonSource::VI)
4557  {
4558  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000408\" name=\"vertical ionization\" />\n";
4559  }
4560  else if (so.getIonizationMethod() == IonSource::FIB)
4561  {
4562  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000446\" name=\"fast ion bombardment\" />\n";
4563  }
4565  {
4566  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000008\" name=\"ionization type\" />\n";
4567  }
4568 
4569  writeUserParam_(os, so, 5, "/mzML/instrumentConfigurationList/instrumentConfiguration/componentList/source/cvParam/@accession", validator);
4570  os << "\t\t\t\t</source>\n";
4571  }
4572  //FORCED
4573  if (component_count < 3 && in.getIonSources().empty())
4574  {
4575  os << "\t\t\t\t<source order=\"1234\">\n";
4576  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000446\" name=\"fast ion bombardment\" />\n";
4577  os << "\t\t\t\t\t<userParam name=\"warning\" type=\"xsd:string\" value=\"invented ion source, to fulfill mzML schema\" />\n";
4578  os << "\t\t\t\t</source>\n";
4579  }
4580  //--------------------------------------------------------------------------------------------
4581  // mass analyzer
4582  //--------------------------------------------------------------------------------------------
4583  for (Size i = 0; i < in.getMassAnalyzers().size(); ++i)
4584  {
4585  const MassAnalyzer& ma = in.getMassAnalyzers()[i];
4586  os << "\t\t\t\t<analyzer order=\"" << ma.getOrder() << "\">\n";
4587 
4588  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000014\" name=\"accuracy\" value=\"" << ma.getAccuracy() << "\" unitAccession=\"UO:0000169\" unitName=\"parts per million\" unitCvRef=\"UO\" />\n";
4589  // @todo: the parameters below are instrument specific and should not be written every time
4590  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000022\" name=\"TOF Total Path Length\" value=\"" << ma.getTOFTotalPathLength() << "\" unitAccession=\"UO:0000008\" unitName=\"meter\" unitCvRef=\"UO\" />\n";
4591  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000024\" name=\"final MS exponent\" value=\"" << ma.getFinalMSExponent() << "\" />\n";
4592  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000025\" name=\"magnetic field strength\" value=\"" << ma.getMagneticFieldStrength() << "\" unitAccession=\"UO:0000228\" unitName=\"tesla\" unitCvRef=\"UO\" />\n";
4593 
4595  {
4596  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000106\" name=\"reflectron on\" />\n";
4597 
4598  }
4599  else if (ma.getReflectronState() == MassAnalyzer::OFF)
4600  {
4601  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000105\" name=\"reflectron off\" />\n";
4602  }
4603 
4605  {
4606  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000079\" name=\"fourier transform ion cyclotron resonance mass spectrometer\" />\n";
4607  }
4608  else if (ma.getType() == MassAnalyzer::SECTOR)
4609  {
4610  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000080\" name=\"magnetic sector\" />\n";
4611  }
4612  else if (ma.getType() == MassAnalyzer::QUADRUPOLE)
4613  {
4614  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000081\" name=\"quadrupole\" />\n";
4615  }
4616  else if (ma.getType() == MassAnalyzer::TOF)
4617  {
4618  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000084\" name=\"time-of-flight\" />\n";
4619  }
4620  else if (ma.getType() == MassAnalyzer::ESA)
4621  {
4622  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000254\" name=\"electrostatic energy analyzer\" />\n";
4623  }
4624  else if (ma.getType() == MassAnalyzer::IT)
4625  {
4626  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000264\" name=\"ion trap\" />\n";
4627  }
4628  else if (ma.getType() == MassAnalyzer::SWIFT)
4629  {
4630  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000284\" name=\"stored waveform inverse fourier transform\" />\n";
4631  }
4632  else if (ma.getType() == MassAnalyzer::CYCLOTRON)
4633  {
4634  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000288\" name=\"cyclotron\" />\n";
4635  }
4636  else if (ma.getType() == MassAnalyzer::ORBITRAP)
4637  {
4638  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000484\" name=\"orbitrap\" />\n";
4639  }
4641  {
4642  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000078\" name=\"axial ejection linear ion trap\" />\n";
4643  }
4644  else if (ma.getType() == MassAnalyzer::PAULIONTRAP)
4645  {
4646  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000082\" name=\"quadrupole ion trap\" />\n";
4647  }
4649  {
4650  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000083\" name=\"radial ejection linear ion trap\" />\n";
4651  }
4652  else if (ma.getType() == MassAnalyzer::LIT)
4653  {
4654  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000291\" name=\"linear ion trap\" />\n";
4655  }
4656  else if (ma.getType() == MassAnalyzer::ANALYZERNULL)
4657  {
4658  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000443\" name=\"mass analyzer type\" />\n";
4659  }
4660 
4661  writeUserParam_(os, ma, 5, "/mzML/instrumentConfigurationList/instrumentConfiguration/componentList/analyzer/cvParam/@accession", validator);
4662  os << "\t\t\t\t</analyzer>\n";
4663  }
4664  //FORCED
4665  if (component_count < 3 && in.getMassAnalyzers().empty())
4666  {
4667  os << "\t\t\t\t<analyzer order=\"1234\">\n";
4668  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000288\" name=\"cyclotron\" />\n";
4669  os << "\t\t\t\t\t<userParam name=\"warning\" type=\"xsd:string\" value=\"invented mass analyzer, to fulfill mzML schema\" />\n";
4670  os << "\t\t\t\t</analyzer>\n";
4671  }
4672  //--------------------------------------------------------------------------------------------
4673  // ion detector
4674  //--------------------------------------------------------------------------------------------
4675  for (Size i = 0; i < in.getIonDetectors().size(); ++i)
4676  {
4677  const IonDetector& id = in.getIonDetectors()[i];
4678  os << "\t\t\t\t<detector order=\"" << id.getOrder() << "\">\n";
4679 
4680  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000028\" name=\"detector resolution\" value=\"" << id.getResolution() << "\" />\n";
4681  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000029\" name=\"sampling frequency\" value=\"" << id.getADCSamplingFrequency() << "\" unitAccession=\"UO:0000106\" unitName=\"hertz\" unitCvRef=\"UO\" />\n";
4682 
4683  if (id.getAcquisitionMode() == IonDetector::ADC)
4684  {
4685  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000117\" name=\"analog-digital converter\" />\n";
4686  }
4687  else if (id.getAcquisitionMode() == IonDetector::PULSECOUNTING)
4688  {
4689  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000118\" name=\"pulse counting\" />\n";
4690  }
4691  else if (id.getAcquisitionMode() == IonDetector::TDC)
4692  {
4693  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000119\" name=\"time-digital converter\" />\n";
4694  }
4695  else if (id.getAcquisitionMode() == IonDetector::TRANSIENTRECORDER)
4696  {
4697  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000120\" name=\"transient recorder\" />\n";
4698  }
4699 
4700  if (id.getType() == IonDetector::CHANNELTRON)
4701  {
4702  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000107\" name=\"channeltron\" />\n";
4703  }
4704  else if (id.getType() == IonDetector::DALYDETECTOR)
4705  {
4706  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000110\" name=\"daly detector\" />\n";
4707  }
4708  else if (id.getType() == IonDetector::FARADAYCUP)
4709  {
4710  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000112\" name=\"faraday cup\" />\n";
4711  }
4712  else if (id.getType() == IonDetector::MICROCHANNELPLATEDETECTOR)
4713  {
4714  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000114\" name=\"microchannel plate detector\" />\n";
4715  }
4716  else if (id.getType() == IonDetector::MULTICOLLECTOR)
4717  {
4718  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000115\" name=\"multi-collector\" />\n";
4719  }
4720  else if (id.getType() == IonDetector::PHOTOMULTIPLIER)
4721  {
4722  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000116\" name=\"photomultiplier\" />\n";
4723  }
4724  else if (id.getType() == IonDetector::ELECTRONMULTIPLIER)
4725  {
4726  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000253\" name=\"electron multiplier\" />\n";
4727  }
4728  else if (id.getType() == IonDetector::ARRAYDETECTOR)
4729  {
4730  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000345\" name=\"array detector\" />\n";
4731  }
4732  else if (id.getType() == IonDetector::CONVERSIONDYNODE)
4733  {
4734  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000346\" name=\"conversion dynode\" />\n";
4735  }
4736  else if (id.getType() == IonDetector::DYNODE)
4737  {
4738  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000347\" name=\"dynode\" />\n";
4739  }
4740  else if (id.getType() == IonDetector::FOCALPLANECOLLECTOR)
4741  {
4742  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000348\" name=\"focal plane collector\" />\n";
4743  }
4744  else if (id.getType() == IonDetector::IONTOPHOTONDETECTOR)
4745  {
4746  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000349\" name=\"ion-to-photon detector\" />\n";
4747  }
4748  else if (id.getType() == IonDetector::POINTCOLLECTOR)
4749  {
4750  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000350\" name=\"point collector\" />\n";
4751  }
4752  else if (id.getType() == IonDetector::POSTACCELERATIONDETECTOR)
4753  {
4754  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000351\" name=\"postacceleration detector\" />\n";
4755  }
4756  else if (id.getType() == IonDetector::PHOTODIODEARRAYDETECTOR)
4757  {
4758  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000621\" name=\"photodiode array detector\" />\n";
4759  }
4760  else if (id.getType() == IonDetector::INDUCTIVEDETECTOR)
4761  {
4762  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000624\" name=\"inductive detector\" />\n";
4763  }
4764  else if (id.getType() == IonDetector::CONVERSIONDYNODEELECTRONMULTIPLIER)
4765  {
4766  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000108\" name=\"conversion dynode electron multiplier\" />\n";
4767  }
4768  else if (id.getType() == IonDetector::CONVERSIONDYNODEPHOTOMULTIPLIER)
4769  {
4770  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000109\" name=\"conversion dynode photomultiplier\" />\n";
4771  }
4772  else if (id.getType() == IonDetector::ELECTRONMULTIPLIERTUBE)
4773  {
4774  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000111\" name=\"electron multiplier tube\" />\n";
4775  }
4776  else if (id.getType() == IonDetector::FOCALPLANEARRAY)
4777  {
4778  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000113\" name=\"focal plane array\" />\n";
4779  }
4780  else if (id.getType() == IonDetector::TYPENULL)
4781  {
4782  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000026\" name=\"detector type\" />\n";
4783  }
4784 
4785  writeUserParam_(os, id, 5, "/mzML/instrumentConfigurationList/instrumentConfiguration/componentList/detector/cvParam/@accession", validator);
4786  os << "\t\t\t\t</detector>\n";
4787  }
4788  //FORCED
4789  if (component_count < 3 && in.getIonDetectors().empty())
4790  {
4791  os << "\t\t\t\t<detector order=\"1234\">\n";
4792  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000107\" name=\"channeltron\" />\n";
4793  os << "\t\t\t\t\t<userParam name=\"warning\" type=\"xsd:string\" value=\"invented ion detector, to fulfill mzML schema\" />\n";
4794  os << "\t\t\t\t</detector>\n";
4795  }
4796  os << "\t\t\t</componentList>\n";
4797  }
4798  os << "\t\t\t<softwareRef ref=\"so_in_0\" />\n";
4799  os << "\t\t</instrumentConfiguration>\n";
4800  os << "\t</instrumentConfigurationList>\n";
4801 
4802  //--------------------------------------------------------------------------------------------
4803  // data processing
4804  //--------------------------------------------------------------------------------------------
4805 
4806  // count number of float data array dps
4807  Size num_bi_dps(0);
4808  for (Size s = 0; s < exp.size(); ++s)
4809  {
4810  for (Size m = 0; m < exp[s].getFloatDataArrays().size(); ++m)
4811  {
4812  ++num_bi_dps;
4813  }
4814  }
4815 
4816  os << "\t<dataProcessingList count=\"" << (std::max)((Size)1, dps.size() + num_bi_dps) << "\">\n";
4817  //default (first spectrum data or fictional data)
4818  if (exp.empty())
4819  {
4820  std::vector<DataProcessing> dummy;
4821  writeDataProcessing_(os, "dp_sp_0", dummy, validator);
4822  }
4823 
4824  for (Size s = 0; s < dps.size(); ++s)
4825  {
4826  writeDataProcessing_(os, String("dp_sp_") + s, dps[s], validator);
4827  }
4828 
4829  //for each binary data array
4830  for (Size s = 0; s < exp.size(); ++s)
4831  {
4832  for (Size m = 0; m < exp[s].getFloatDataArrays().size(); ++m)
4833  {
4834  writeDataProcessing_(os, String("dp_sp_") + s + "_bi_" + m, exp[s].getFloatDataArrays()[m].getDataProcessing(), validator);
4835  }
4836  }
4837 
4838  os << "\t</dataProcessingList>\n";
4839  //--------------------------------------------------------------------------------------------
4840  // acquisitionSettings
4841  //--------------------------------------------------------------------------------------------
4842 
4843  //--------------------------------------------------------------------------------------------
4844  // run
4845  //--------------------------------------------------------------------------------------------
4846  os << "\t<run id=\"ru_0\" defaultInstrumentConfigurationRef=\"ic_0\" sampleRef=\"sa_0\"";
4847  if (exp.getDateTime().isValid())
4848  {
4849  os << " startTimeStamp=\"" << exp.getDateTime().get().substitute(' ', 'T') << "\"";
4850  }
4851  if (exp.getSourceFiles().size() > 0)
4852  {
4853  os << " defaultSourceFileRef=\"sf_ru_0\"";
4854  }
4855  os << ">\n";
4856 
4857  //run attributes
4858  if (exp.getFractionIdentifier() != "")
4859  {
4860  os << "\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000858\" name=\"fraction identifier\" value=\"" << exp.getFractionIdentifier() << "\" />\n";
4861  }
4862 
4863  writeUserParam_(os, exp, 2, "/mzML/run/cvParam/@accession", validator);
4864 
4865  }
4866 
4867  template <typename MapType>
4869  const SpectrumType& spec, Size s,
4870  Internal::MzMLValidator& validator, bool renew_native_ids,
4871  std::vector<std::vector<DataProcessing> >& dps)
4872  {
4873  //native id
4874  String native_id = spec.getNativeID();
4875  if (renew_native_ids)
4876  {
4877  native_id = String("spectrum=") + s;
4878  }
4879 
4880  long offset = os.tellp();
4881  spectra_offsets.push_back(make_pair(native_id, offset + 3));
4882 
4883  // IMPORTANT make sure the offset (above) corresponds to the start of the <spectrum tag
4884  os << "\t\t\t<spectrum id=\"" << writeXMLEscape(native_id) << "\" index=\"" << s << "\" defaultArrayLength=\"" << spec.size() << "\"";
4885  if (spec.getSourceFile() != SourceFile())
4886  {
4887  os << " sourceFileRef=\"sf_sp_" << s << "\"";
4888  }
4889  //the data processing info of the first spectrum is the default
4890  //if (s==0 || spec.getDataProcessing()!=exp[0].getDataProcessing())
4891  if (s == 0 || spec.getDataProcessing() != dps[0])
4892  {
4893  Size dp_ref_num = s;
4894  if (s != 0)
4895  {
4896  for (Size i = 0; i < dps.size(); ++i)
4897  {
4898  if (spec.getDataProcessing() == dps[i])
4899  {
4900  dp_ref_num = i;
4901  break;
4902  }
4903  }
4904  }
4905  os << " dataProcessingRef=\"dp_sp_" << dp_ref_num << "\"";
4906  }
4907  os << ">\n";
4908 
4909  //spectrum representation
4910  if (spec.getType() == SpectrumSettings::PEAKS)
4911  {
4912  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000127\" name=\"centroid spectrum\" />\n";
4913  }
4914  else if (spec.getType() == SpectrumSettings::RAWDATA)
4915  {
4916  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000128\" name=\"profile spectrum\" />\n";
4917  }
4918  else
4919  {
4920  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000525\" name=\"spectrum representation\" />\n";
4921  }
4922 
4923  //spectrum attributes
4924  if (spec.getMSLevel() != 0)
4925  {
4926  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000511\" name=\"ms level\" value=\"" << spec.getMSLevel() << "\" />\n";
4927  }
4928  if (spec.getInstrumentSettings().getZoomScan())
4929  {
4930  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000497\" name=\"zoom scan\" />\n";
4931  }
4932 
4933  //spectrum type
4935  {
4936  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000294\" name=\"mass spectrum\" />\n";
4937  }
4939  {
4940  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000579\" name=\"MS1 spectrum\" />\n";
4941  }
4943  {
4944  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000580\" name=\"MSn spectrum\" />\n";
4945  }
4947  {
4948  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000582\" name=\"SIM spectrum\" />\n";
4949  }
4951  {
4952  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000583\" name=\"SRM spectrum\" />\n";
4953  }
4955  {
4956  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000581\" name=\"CRM spectrum\" />\n";
4957  }
4959  {
4960  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000341\" name=\"precursor ion spectrum\" />\n";
4961  }
4963  {
4964  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000325\" name=\"constant neutral gain spectrum\" />\n";
4965  }
4967  {
4968  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000326\" name=\"constant neutral loss spectrum\" />\n";
4969  }
4971  {
4972  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000804\" name=\"electromagnetic radiation spectrum\" />\n";
4973  }
4975  {
4976  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000805\" name=\"emission spectrum\" />\n";
4977  }
4979  {
4980  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000806\" name=\"absorption spectrum\" />\n";
4981  }
4983  {
4984  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000789\" name=\"enhanced multiply charged spectrum\" />\n";
4985  }
4987  {
4988  os << "\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000789\" name=\"time-delayed fragmentation spectrum\" />\n";
4989  }
4990  else //FORCED
4991  {
4992  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000294\" name=\"mass spectrum\" />\n";
4993  }
4994 
4995  //scan polarity
4997  {
4998  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000129\" name=\"negative scan\" />\n";
4999  }
5001  {
5002  os << "\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000130\" name=\"positive scan\" />\n";
5003  }
5004 
5005  writeUserParam_(os, spec, 4, "/mzML/run/spectrumList/spectrum/cvParam/@accession", validator);
5006  //--------------------------------------------------------------------------------------------
5007  //scan list
5008  //--------------------------------------------------------------------------------------------
5009  os << "\t\t\t\t<scanList count=\"" << (std::max)((Size)1, spec.getAcquisitionInfo().size()) << "\">\n";
5010  ControlledVocabulary::CVTerm ai_term = getChildWithName_("MS:1000570", spec.getAcquisitionInfo().getMethodOfCombination());
5011  if (ai_term.id != "")
5012  {
5013  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << ai_term.id << "\" name=\"" << ai_term.name << "\" />\n";
5014  }
5015  else
5016  {
5017  os << "\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000795\" name=\"no combination\" />\n";
5018  }
5019  writeUserParam_(os, spec.getAcquisitionInfo(), 5, "/mzML/run/spectrumList/spectrum/scanList/cvParam/@accession", validator);
5020 
5021  //--------------------------------------------------------------------------------------------
5022  //scan
5023  //--------------------------------------------------------------------------------------------
5024  for (Size j = 0; j < spec.getAcquisitionInfo().size(); ++j)
5025  {
5026  const Acquisition& ac = spec.getAcquisitionInfo()[j];
5027  os << "\t\t\t\t\t<scan ";
5028  if (ac.getIdentifier() != "")
5029  os << "externalSpectrumID=\"" << ac.getIdentifier() << "\"";
5030  os << ">\n";
5031  if (j == 0)
5032  {
5033  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000016\" name=\"scan start time\" value=\"" << spec.getRT() << "\" unitAccession=\"UO:0000010\" unitName=\"second\" unitCvRef=\"UO\" />\n";
5034  }
5035  writeUserParam_(os, ac, 6, "/mzML/run/spectrumList/spectrum/scanList/scan/cvParam/@accession", validator);
5036  //scan windows
5037  if (j == 0 && spec.getInstrumentSettings().getScanWindows().size() != 0)
5038  {
5039  os << "\t\t\t\t\t\t<scanWindowList count=\"" << spec.getInstrumentSettings().getScanWindows().size() << "\">\n";
5040  for (Size k = 0; k < spec.getInstrumentSettings().getScanWindows().size(); ++k)
5041  {
5042  os << "\t\t\t\t\t\t\t<scanWindow>\n";
5043  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000501\" name=\"scan window lower limit\" value=\"" << spec.getInstrumentSettings().getScanWindows()[k].begin << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
5044  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000500\" name=\"scan window upper limit\" value=\"" << spec.getInstrumentSettings().getScanWindows()[k].end << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
5045  writeUserParam_(os, spec.getInstrumentSettings().getScanWindows()[k], 8, "/mzML/run/spectrumList/spectrum/scanList/scan/scanWindowList/scanWindow/cvParam/@accession", validator);
5046  os << "\t\t\t\t\t\t\t</scanWindow>\n";
5047  }
5048  os << "\t\t\t\t\t\t</scanWindowList>\n";
5049  }
5050  os << "\t\t\t\t\t</scan>\n";
5051  }
5052  //fallback if we have no acquisition information (a dummy scan is created for RT and so on)
5053  if (spec.getAcquisitionInfo().empty())
5054  {
5055  os << "\t\t\t\t\t<scan>\n";
5056  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000016\" name=\"scan start time\" value=\"" << spec.getRT() << "\" unitAccession=\"UO:0000010\" unitName=\"second\" unitCvRef=\"UO\" />\n";
5057  //scan windows
5058  if (spec.getInstrumentSettings().getScanWindows().size() != 0)
5059  {
5060  os << "\t\t\t\t\t\t<scanWindowList count=\"" << spec.getInstrumentSettings().getScanWindows().size() << "\">\n";
5061  for (Size j = 0; j < spec.getInstrumentSettings().getScanWindows().size(); ++j)
5062  {
5063  os << "\t\t\t\t\t\t\t<scanWindow>\n";
5064  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000501\" name=\"scan window lower limit\" value=\"" << spec.getInstrumentSettings().getScanWindows()[j].begin << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
5065  os << "\t\t\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000500\" name=\"scan window upper limit\" value=\"" << spec.getInstrumentSettings().getScanWindows()[j].end << "\" unitAccession=\"MS:1000040\" unitName=\"m/z\" unitCvRef=\"MS\" />\n";
5066  writeUserParam_(os, spec.getInstrumentSettings().getScanWindows()[j], 8, "/mzML/run/spectrumList/spectrum/scanList/scan/scanWindowList/scanWindow/cvParam/@accession", validator);
5067  os << "\t\t\t\t\t\t\t</scanWindow>\n";
5068  }
5069  os << "\t\t\t\t\t\t</scanWindowList>\n";
5070  }
5071  os << "\t\t\t\t\t</scan>\n";
5072  }
5073  os << "\t\t\t\t</scanList>\n";
5074 
5075  //--------------------------------------------------------------------------------------------
5076  //precursor list
5077  //--------------------------------------------------------------------------------------------
5078  if (!spec.getPrecursors().empty())
5079  {
5080  os << "\t\t\t<precursorList count=\"" << spec.getPrecursors().size() << "\">\n";
5081  for (Size p = 0; p != spec.getPrecursors().size(); ++p)
5082  {
5083  writePrecursor_(os, spec.getPrecursors()[p], validator);
5084  }
5085  os << "\t\t\t</precursorList>\n";
5086  }
5087 
5088  //--------------------------------------------------------------------------------------------
5089  //product list
5090  //--------------------------------------------------------------------------------------------
5091  if (spec.getProducts().size() != 0)
5092  {
5093  os << "\t\t\t\t<productList count=\"" << spec.getProducts().size() << "\">\n";
5094  for (Size p = 0; p < spec.getProducts().size(); ++p)
5095  {
5096  writeProduct_(os, spec.getProducts()[p], validator);
5097  }
5098  os << "\t\t\t\t</productList>\n";
5099  }
5100 
5101  //--------------------------------------------------------------------------------------------
5102  //binary data array list
5103  //--------------------------------------------------------------------------------------------
5104  if (spec.size() != 0)
5105  {
5106  String encoded_string;
5107  os << "\t\t\t\t<binaryDataArrayList count=\"" << (2 + spec.getFloatDataArrays().size() + spec.getStringDataArrays().size() + spec.getIntegerDataArrays().size()) << "\">\n";
5108 
5109  writeContainerData<SpectrumType>(os, options_, spec, "mz");
5110  writeContainerData<SpectrumType>(os, options_, spec, "intensity");
5111 
5112  String compression_term = MzMLHandlerHelper::getCompressionTerm_(options_, options_.getNumpressConfigurationIntensity(), false);
5113  //write float data array
5114  for (Size m = 0; m < spec.getFloatDataArrays().size(); ++m)
5115  {
5116  const typename SpectrumType::FloatDataArray& array = spec.getFloatDataArrays()[m];
5117  std::vector<double> data64_to_encode(array.size());
5118  for (Size p = 0; p < array.size(); ++p)
5119  data64_to_encode[p] = array[p];
5120  // TODO also encode float data arrays using numpress?
5121  decoder_.encode(data64_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, options_.getCompression());
5122  String data_processing_ref_string = "";
5123  if (array.getDataProcessing().size() != 0)
5124  {
5125  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + s + "_bi_" + m + "\"";
5126  }
5127  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5128  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000523\" name=\"64-bit float\" />\n";
5129  os << "\t\t\t\t\t\t" << compression_term << "\n";
5130  ControlledVocabulary::CVTerm bi_term = getChildWithName_("MS:1000513", array.getName());
5131  if (bi_term.id != "")
5132  {
5133  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << bi_term.id << "\" name=\"" << bi_term.name << "\" />\n";
5134  }
5135  else
5136  {
5137  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5138  }
5139  writeUserParam_(os, array, 6, "/mzML/run/spectrumList/spectrum/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5140  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5141  os << "\t\t\t\t\t</binaryDataArray>\n";
5142  }
5143  //write integer data array
5144  for (Size m = 0; m < spec.getIntegerDataArrays().size(); ++m)
5145  {
5146  const typename SpectrumType::IntegerDataArray& array = spec.getIntegerDataArrays()[m];
5147  std::vector<Int64> data64_to_encode(array.size());
5148  for (Size p = 0; p < array.size(); ++p)
5149  data64_to_encode[p] = array[p];
5150  decoder_.encodeIntegers(data64_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, options_.getCompression());
5151  String data_processing_ref_string = "";
5152  if (array.getDataProcessing().size() != 0)
5153  {
5154  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + s + "_bi_" + m + "\"";
5155  }
5156  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5157  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000522\" name=\"64-bit integer\" />\n";
5158  os << "\t\t\t\t\t\t" << compression_term << "\n";
5159  ControlledVocabulary::CVTerm bi_term = getChildWithName_("MS:1000513", array.getName());
5160  if (bi_term.id != "")
5161  {
5162  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << bi_term.id << "\" name=\"" << bi_term.name << "\" />\n";
5163  }
5164  else
5165  {
5166  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5167  }
5168  writeUserParam_(os, array, 6, "/mzML/run/spectrumList/spectrum/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5169  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5170  os << "\t\t\t\t\t</binaryDataArray>\n";
5171  }
5172  //write string data arrays
5173  for (Size m = 0; m < spec.getStringDataArrays().size(); ++m)
5174  {
5175  const typename SpectrumType::StringDataArray& array = spec.getStringDataArrays()[m];
5176  std::vector<String> data_to_encode;
5177  data_to_encode.resize(array.size());
5178  for (Size p = 0; p < array.size(); ++p)
5179  data_to_encode[p] = array[p];
5180  decoder_.encodeStrings(data_to_encode, encoded_string, options_.getCompression());
5181  String data_processing_ref_string = "";
5182  if (array.getDataProcessing().size() != 0)
5183  {
5184  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + s + "_bi_" + m + "\"";
5185  }
5186  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5187  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001479\" name=\"null-terminated ASCII string\" />\n";
5188  os << "\t\t\t\t\t\t" << compression_term << "\n";
5189  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5190  writeUserParam_(os, array, 6, "/mzML/run/spectrumList/spectrum/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5191  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5192  os << "\t\t\t\t\t</binaryDataArray>\n";
5193  }
5194  os << "\t\t\t\t</binaryDataArrayList>\n";
5195  }
5196 
5197  os << "\t\t\t</spectrum>\n";
5198  }
5199 
5200  template <typename MapType>
5202  const ChromatogramType& chromatogram, Size c, Internal::MzMLValidator& validator)
5203  {
5204  long offset = os.tellp();
5205  chromatograms_offsets.push_back(make_pair(chromatogram.getNativeID(), offset + 6));
5206 
5207  // TODO native id with chromatogram=?? prefix?
5208  // IMPORTANT make sure the offset (above) corresponds to the start of the <chromatogram tag
5209  os << " <chromatogram id=\"" << writeXMLEscape(chromatogram.getNativeID()) << "\" index=\"" << c << "\" defaultArrayLength=\"" << chromatogram.size() << "\">" << "\n";
5210 
5211  // write cvParams (chromatogram type)
5213  {
5214  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000810\" name=\"mass chromatogram\" />\n";
5215  }
5217  {
5218  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000235\" name=\"total ion current chromatogram\" />\n";
5219  }
5221  {
5222  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000627\" name=\"selected ion current chromatogram\" />\n";
5223  }
5225  {
5226  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000628\" name=\"basepeak chromatogram\" />\n";
5227  }
5229  {
5230  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001472\" name=\"selected ion monitoring chromatogram\" />\n";
5231  }
5233  {
5234  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001473\" name=\"selected reaction monitoring chromatogram\" />\n";
5235  }
5237  {
5238  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000811\" name=\"electromagnetic radiation chromatogram\" />\n";
5239  }
5241  {
5242  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000812\" name=\"absorption chromatogram\" />\n";
5243  }
5245  {
5246  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000813\" name=\"emission chromatogram\" />\n";
5247  }
5248  else
5249  {
5250  // TODO
5251  }
5252  writePrecursor_(os, chromatogram.getPrecursor(), validator);
5253  writeProduct_(os, chromatogram.getProduct(), validator);
5254 
5255  //--------------------------------------------------------------------------------------------
5256  //binary data array list
5257  //--------------------------------------------------------------------------------------------
5258  String compression_term;
5259  String encoded_string;
5260  os << "\t\t\t\t<binaryDataArrayList count=\"" << (2 + chromatogram.getFloatDataArrays().size() + chromatogram.getStringDataArrays().size() + chromatogram.getIntegerDataArrays().size()) << "\">\n";
5261 
5262  writeContainerData<ChromatogramType>(os, options_, chromatogram, "time");
5263  writeContainerData<ChromatogramType>(os, options_, chromatogram, "intensity");
5264 
5265  compression_term = MzMLHandlerHelper::getCompressionTerm_(options_, options_.getNumpressConfigurationIntensity(), false);
5266  //write float data array
5267  for (Size m = 0; m < chromatogram.getFloatDataArrays().size(); ++m)
5268  {
5269  const typename ChromatogramType::FloatDataArray& array = chromatogram.getFloatDataArrays()[m];
5270  std::vector<double> data64_to_encode(array.size());
5271  for (Size p = 0; p < array.size(); ++p)
5272  data64_to_encode[p] = array[p];
5273  // TODO also encode float data arrays using numpress?
5274  decoder_.encode(data64_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, options_.getCompression());
5275  String data_processing_ref_string = "";
5276  if (array.getDataProcessing().size() != 0)
5277  {
5278  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + c + "_bi_" + m + "\"";
5279  }
5280  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5281  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000523\" name=\"64-bit float\" />\n";
5282  os << "\t\t\t\t\t\t" << compression_term << "\n";
5283  ControlledVocabulary::CVTerm bi_term = getChildWithName_("MS:1000513", array.getName());
5284  if (bi_term.id != "")
5285  {
5286  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << bi_term.id << "\" name=\"" << bi_term.name << "\" />\n";
5287  }
5288  else
5289  {
5290  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5291  }
5292  writeUserParam_(os, array, 6, "/mzML/run/chromatogramList/chromatogram/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5293  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5294  os << "\t\t\t\t\t</binaryDataArray>\n";
5295  }
5296  //write integer data array
5297  for (Size m = 0; m < chromatogram.getIntegerDataArrays().size(); ++m)
5298  {
5299  const typename ChromatogramType::IntegerDataArray& array = chromatogram.getIntegerDataArrays()[m];
5300  std::vector<Int64> data64_to_encode(array.size());
5301  for (Size p = 0; p < array.size(); ++p)
5302  data64_to_encode[p] = array[p];
5303  decoder_.encodeIntegers(data64_to_encode, Base64::BYTEORDER_LITTLEENDIAN, encoded_string, options_.getCompression());
5304  String data_processing_ref_string = "";
5305  if (array.getDataProcessing().size() != 0)
5306  {
5307  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + c + "_bi_" + m + "\"";
5308  }
5309  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5310  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000522\" name=\"64-bit integer\" />\n";
5311  os << "\t\t\t\t\t\t" << compression_term << "\n";
5312  ControlledVocabulary::CVTerm bi_term = getChildWithName_("MS:1000513", array.getName());
5313  if (bi_term.id != "")
5314  {
5315  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"" << bi_term.id << "\" name=\"" << bi_term.name << "\" />\n";
5316  }
5317  else
5318  {
5319  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5320  }
5321  writeUserParam_(os, array, 6, "/mzML/run/chromatogramList/chromatogram/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5322  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5323  os << "\t\t\t\t\t</binaryDataArray>\n";
5324  }
5325  //write string data arrays
5326  for (Size m = 0; m < chromatogram.getStringDataArrays().size(); ++m)
5327  {
5328  const typename ChromatogramType::StringDataArray& array = chromatogram.getStringDataArrays()[m];
5329  std::vector<String> data_to_encode;
5330  data_to_encode.resize(array.size());
5331  for (Size p = 0; p < array.size(); ++p)
5332  data_to_encode[p] = array[p];
5333  decoder_.encodeStrings(data_to_encode, encoded_string, options_.getCompression());
5334  String data_processing_ref_string = "";
5335  if (array.getDataProcessing().size() != 0)
5336  {
5337  data_processing_ref_string = String("dataProcessingRef=\"dp_sp_") + c + "_bi_" + m + "\"";
5338  }
5339  os << "\t\t\t\t\t<binaryDataArray arrayLength=\"" << array.size() << "\" encodedLength=\"" << encoded_string.size() << "\" " << data_processing_ref_string << ">\n";
5340  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1001479\" name=\"null-terminated ASCII string\" />\n";
5341  os << "\t\t\t\t\t\t" << compression_term << "\n";
5342  os << "\t\t\t\t\t\t<cvParam cvRef=\"MS\" accession=\"MS:1000786\" name=\"non-standard data array\" value=\"" << array.getName() << "\" />\n";
5343  writeUserParam_(os, array, 6, "/mzML/run/chromatogramList/chromatogram/binaryDataArrayList/binaryDataArray/cvParam/@accession", validator);
5344  os << "\t\t\t\t\t\t<binary>" << encoded_string << "</binary>\n";
5345  os << "\t\t\t\t\t</binaryDataArray>\n";
5346  }
5347  os << "\t\t\t\t</binaryDataArrayList>\n";
5348  os << "\t\t\t</chromatogram>" << "\n";
5349  }
5350 
5351  } // namespace Internal
5352 } // namespace OpenMS
5353 
5354 #endif
const String & getPathToFile() const
returns the file path
const String & getAddress() const
returns the address
String chop(Size n) const
Returns a substring where n characters were removed from the end of the string.
Sustained off-resonance irradiation.
Definition: Precursor.h:73
Definition: ChromatogramSettings.h:72
const double k
const DataValue & getMetaValue(const String &name) const
returns the value corresponding to a string
Pulse counting.
Definition: IonDetector.h:85
Cyclotron.
Definition: MassAnalyzer.h:67
general spectrum type
Definition: InstrumentSettings.h:56
const String & getNativeID() const
returns the native identifier for the spectrum, used by the acquisition software. ...
Description of the applied preprocessing steps.
Definition: DataProcessing.h:51
Conversion to mzXML format.
Definition: DataProcessing.h:78
const String & getCustomizations() const
returns a description of customizations
resonance enhanced multiphoton ionization
Definition: IonSource.h:117
ChecksumType getChecksumType() const
returns the checksum type
atmospheric pressure ionisation
Definition: IonSource.h:94
fast atom bombardment
Definition: IonSource.h:86
Class to encode and decode data encoded with MSNumpress.
Definition: MSNumpressCoder.h:53
Open split.
Definition: IonSource.h:60
NumpressCompression np_compression
check error tolerance after encoding, guarantee abs(1.0-(encoded/decoded)) <= this, 0=do not guarantee anything
Definition: MSNumpressCoder.h:69
neutralization reionization mass spectrometry
Definition: IonSource.h:114
void setMetaValue(const String &name, const DataValue &value)
sets the DataValue corresponding to a name
Definition: Sample.h:65
Conversion dynode electron multiplier.
Definition: IonDetector.h:59
postacceleration detector
Definition: IonDetector.h:72
static const VersionDetails EMPTY
Definition: VersionInfo.h:93
PeakFileOptions options_
Options that can be set for loading/storing.
Definition: MzMLHandler.h:857
Description of a MS instrument.
Definition: Instrument.h:64
bool hasUnit() const
Check if the value has a unit.
Definition: DataValue.h:370
bool hasMZRange() const
returns true if an MZ range has been set
Peak picking (conversion from raw to peak data)
Definition: DataProcessing.h:67
void populateSpectraWithData()
Populate all spectra on the stack with data from input.
Definition: MzMLHandler.h:320
integer value
Definition: DataValue.h:69
Infusion.
Definition: IonSource.h:69
double getIsolationWindowLowerOffset() const
Returns the lower offset from the target m/z.
const String & getNameOfFile() const
returns the file name
bool getSortChromatogramsByRT() const
gets whether or not peaks in chromatograms should be sorted
fringing field
Definition: Instrument.h:82
static String getXRefTypeName(XRefType type)
Baseline reduction.
Definition: DataProcessing.h:66
String accession
Definition: SemanticValidator.h:75
Representation of a CV term.
Definition: ControlledVocabulary.h:60
surface ionization
Definition: IonSource.h:129
std::vector< SpectrumData > spectrum_data_
Vector of spectrum data stored for later parallel processing.
Definition: MzMLHandler.h:904
atmospheric pressure chemical ionization
Definition: IonSource.h:99
String writeCV_(const ControlledVocabulary::CVTerm &c, const DataValue &metaValue) const
Helper method to write an CV based on a meta value.
Definition: MzMLHandler.h:3458
A more convenient string class.
Definition: String.h:57
Multiphoton ionization.
Definition: IonSource.h:108
kinetic energy analyzer
Definition: Instrument.h:83
Precursor meta information.
Definition: Precursor.h:56
Class to encode and decode Base64.
Definition: Base64.h:64
const String & getNumber() const
returns the sample number (default: "")
dynode
Definition: IonDetector.h:68
Exception that is thrown if the parsing is ended by some event (e.g. if only a prefix of the XML file...
Definition: XMLHandler.h:104
void warning(const xercesc::SAXParseException &exception)
const std::vector< IonSource > & getIonSources() const
returns a const reference to the ion source list
bool getAlwaysAppendData() const
returns whether or not to always append the data to the given map (even if a consumer is given) ...
dissociative ionization
Definition: IonSource.h:124
ControlledVocabulary cv_
Controlled vocabulary (psi-ms from OpenMS/share/OpenMS/CV/psi-ms.obo)
Definition: MzMLHandler.h:951
bool encloses(const PositionType &position) const
Checks whether this range contains a certain point.
Definition: DRange.h:172
UInt getMSLevel() const
Returns the MS level.
Definition: MSSpectrum.h:259
InletType getInletType() const
returns the inlet type
Plasma desorption.
Definition: Precursor.h:68
time lag focusing
Definition: Instrument.h:78
String version_
Schema version.
Definition: XMLHandler.h:190
Infrared multiphoton dissociation.
Definition: Precursor.h:72
bool hasIntensityRange() const
returns true if an intensity range has been set
IntensityType getIntensity() const
Definition: Peak1D.h:109
Product meta information.
Definition: Product.h:49
void set(UInt month, UInt day, UInt year, UInt hour, UInt minute, UInt second)
sets data from six integers
liquid secondary ionization
Definition: IonSource.h:125
Electrostatic energy analyzer.
Definition: MassAnalyzer.h:64
bool has(const Key &key) const
Test whether the map contains the given key.
Definition: Map.h:109
Message-Digest algorithm 5.
Definition: SourceFile.h:56
Conversion to mzML format.
Definition: DataProcessing.h:77
Faraday cup.
Definition: IonDetector.h:58
charge exchange ionization
Definition: IonSource.h:122
Surface enhanced neat desorption.
Definition: IonSource.h:105
double getMass() const
returns the mass (in gram) (default: 0.0)
Fast ion bombardment.
Definition: IonSource.h:106
String id
Identifier.
Definition: ControlledVocabulary.h:81
spark ionization
Definition: IonSource.h:128
bool rt_set_
Definition: MzMLHandler.h:948
void writeDataProcessing_(std::ostream &os, const String &id, const std::vector< DataProcessing > &dps, Internal::MzMLValidator &validator)
Helper method that writes a data processing list.
Definition: MzMLHandler.h:3644
Membrane separator.
Definition: IonSource.h:59
const DRange< 1 > & getIntensityRange() const
returns the intensity range
Contact person information.
Definition: ContactPerson.h:50
const String & getNativeIDType() const
Returns the native ID type of the spectra.
bool hasSuffix(const String &string) const
true if String ends with string, false otherwise
static const DataValue EMPTY
Empty data value for comparisons.
Definition: DataValue.h:63
Data necessary to generate a single spectrum.
Definition: MzMLHandler.h:895
Semantically validates MzXML files.
Definition: MzMLValidator.h:52
Fourier transform ion cyclotron resonance mass spectrometer.
Definition: MassAnalyzer.h:62
Data filtering or extraction.
Definition: DataProcessing.h:71
photoionization
Definition: IonSource.h:115
Pulsed q dissociation.
Definition: Precursor.h:78
virtual void startElement(const XMLCh *const , const XMLCh *const , const XMLCh *const qname, const xercesc::Attributes &attributes)
Parsing method for opening tags.
Definition: MzMLHandler.h:1034
const std::vector< MassAnalyzer > & getMassAnalyzers() const
returns a const reference to the mass analyzer list
Thermo spray.
Definition: IonSource.h:68
String toString() const
Conversion to String.
Unknown scan method.
Definition: InstrumentSettings.h:55
SpectrumType spec_
The current spectrum.
Definition: MzMLHandler.h:862
Enhanced multiply charged scan.
Definition: InstrumentSettings.h:65
Surface enhanced laser desorption ionization.
Definition: IonSource.h:104
penning ionization
Definition: IonSource.h:126
const AcquisitionInfo & getAcquisitionInfo() const
returns a const reference to the acquisition info
CoordinateType getMZ() const
Non-mutable access to m/z.
Definition: Peak1D.h:114
Negative polarity.
Definition: IonSource.h:144
bool hasRTRange() const
returns true if an RT range has been set
IonizationMethod getIonizationMethod() const
returns the ionization method
std::vector< BinaryData > data
Definition: MzMLHandler.h:915
associative ionization
Definition: IonSource.h:119
AnalyzerType getType() const
returns the analyzer type
IonOpticsType getIonOptics() const
returns the ion optics type
const StringDataArrays & getStringDataArrays() const
Returns a const reference to the string meta data arrays.
Definition: MSChromatogram.h:262
array detector
Definition: IonDetector.h:66
Int getCharge() const
Non-mutable access to the charge.
Base class for XML handlers.
Definition: XMLHandler.h:99
Electron transfer dissociation.
Definition: Precursor.h:77
void populateSpectraWithData_(std::vector< MzMLHandlerHelper::BinaryData > &input_data, Size &default_arr_length, const PeakFileOptions &peak_file_options, SpectrumType &spectrum)
Fill a single spectrum with data from input.
Definition: MzMLHandler.h:446
Emission scan.
Definition: InstrumentSettings.h:68
bool getSortSpectraByMZ() const
gets whether or not peaks in spectra should be sorted
bool getIntensity32Bit() const
ptrdiff_t SignedSize
Signed Size type e.g. used as pointer difference.
Definition: Types.h:128
field ionization
Definition: IonSource.h:111
const std::vector< IonDetector > & getIonDetectors() const
returns a const reference to the ion detector list
Description of a file location, used to store the origin of (meta) data.
Definition: SourceFile.h:47
Constant neutral loss scan Synonyms: 'CNG scan'.
Definition: InstrumentSettings.h:63
double getAccuracy() const
returns the mass accuracy i.e. how much the theoretical mass may differ from the measured mass (in pp...
flowing afterglow
Definition: IonSource.h:110
MS2+ mass spectrum, is a "mass spectrum".
Definition: InstrumentSettings.h:58
Binary data representation.
Definition: MzMLHandlerHelper.h:58
Raw data (also called profile data)
Definition: SpectrumSettings.h:75
Little endian type.
Definition: Base64.h:79
Axial ejection linear ion trap.
Definition: MassAnalyzer.h:59
Time-delayed fragmentation scan.
Definition: InstrumentSettings.h:66
Micro electrospray ionization.
Definition: IonSource.h:103
electron multiplier tube
Definition: IonDetector.h:75
Calibration of m/z positions.
Definition: DataProcessing.h:69
Description of the software used for processing.
Definition: Software.h:49
const double c
glow discharge ionization
Definition: IonSource.h:112
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
Definition: Sample.h:65
Flow injection analysis.
Definition: IonSource.h:66
bool getCompression() const
const IntegerDataArrays & getIntegerDataArrays() const
Returns a const reference to the integer meta data arrays.
Definition: MSSpectrum.h:322
static String find(const String &filename, StringList directories=StringList())
Looks up the location of the file filename.
Time-of-flight.
Definition: MassAnalyzer.h:60
std::vector< std::pair< std::string, long > > spectra_offsets
Definition: MzMLHandler.h:926
const String & getUnit() const
Return the unit associated to this DataValue.
Quadrupole ion trap / Paul ion trap.
Definition: MassAnalyzer.h:57
MzMLHandler(const MapType &exp, const String &filename, const String &version, const ProgressLogger &logger)
Constructor for a write-only handler.
Definition: MzMLHandler.h:153
first stability region
Definition: Instrument.h:81
Recalculation of precursor m/z.
Definition: DataProcessing.h:65
channeltron
Definition: IonDetector.h:63
ChromatogramType chromatogram_
The current chromatogram.
Definition: MzMLHandler.h:864
Focal plane array.
Definition: IonDetector.h:57
Definition: ControlledVocabulary.h:66
void writeContainerData(std::ostream &os, const PeakFileOptions &pf_options_, const ContainerT &container, String array_type)
Definition: MzMLHandler.h:268
electron ionization
Definition: IonSource.h:84
void populateChromatogramsWithData()
Populate all chromatograms on the stack with data from input.
Definition: MzMLHandler.h:385
bool obsolete
Flag that indicates of the term is obsolete.
Definition: ControlledVocabulary.h:84
Configuration class for MSNumpress.
Definition: MSNumpressCoder.h:65
Int getOrder() const
returns the position of this part in the whole Instrument.
Map< String, SourceFile > source_files_
The source files: id => SourceFile.
Definition: MzMLHandler.h:876
const ProgressLogger & logger_
Progress logger.
Definition: MzMLHandler.h:934
Retention time alignment of different maps.
Definition: DataProcessing.h:68
ion-to-photon detector
Definition: IonDetector.h:70
Map< String, Software > software_
The software list: id => Software.
Definition: MzMLHandler.h:880
double getActivationEnergy() const
returns the activation energy (in electronvolt)
#define LOG_ERROR
Macro to be used if non-fatal error are reported (processing continues)
Definition: LogStream.h:447
void writeHeader_(std::ostream &os, const MapType &exp, std::vector< std::vector< DataProcessing > > &dps, Internal::MzMLValidator &validator)
Definition: MzMLHandler.h:3958
static void decodeBase64Arrays(std::vector< BinaryData > &data_)
SpectrumType getType() const
returns the spectrum type
const std::vector< DataProcessing > & getDataProcessing() const
returns a const reference to the description of the applied processing
const String & getIdentifier() const
return the identifier/index/number of the acquisition
double toDouble() const
Conversion to double.
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:57
double getIsolationWindowUpperOffset() const
Returns the upper offset from the target m/z.
bool getZoomScan() const
return if this scan is a zoom (enhanced resolution) scan
Conversion to DTA format.
Definition: DataProcessing.h:79
ScanMode getScanMode() const
returns the scan mode
double getTOFTotalPathLength() const
returns the path length for a TOF mass analyzer (in meter)
negative ion chemical ionization
Definition: IonSource.h:113
const std::set< ActivationMethod > & getActivationMethods() const
returns a const reference to the activation methods
double getMZ() const
returns the target m/z
virtual void endElement(const XMLCh *const , const XMLCh *const , const XMLCh *const qname)
Parsing method for closing tags.
Definition: MzMLHandler.h:1454
String unit_accession
Definition: SemanticValidator.h:79
MSExperiment< Peak1D > MapType
Definition: PeakPickerIterative.cpp:87
Selected reaction monitoring scan Synonyms: 'Multiple reaction monitoring scan', 'SRM scan', 'MRM scan'.
Definition: InstrumentSettings.h:60
Representation of a controlled vocabulary.
Definition: ControlledVocabulary.h:54
double getMagneticFieldStrength() const
returns the strength of the magnetic field (in T)
Size default_array_length
Definition: MzMLHandler.h:898
Definition: ChromatogramSettings.h:69
Size default_array_length_
The default number of peaks in the current spectrum.
Definition: MzMLHandler.h:868
Data necessary to generate a single chromatogram.
Definition: MzMLHandler.h:913
collision quadrupole
Definition: Instrument.h:76
SpectrumType spectrum
Definition: MzMLHandler.h:899
void load(const String &filename, CVMappings &cv_mappings, bool strip_namespaces=false)
loads CvMappings from the given file
XML handler for MzMLFile.
Definition: MzMLHandler.h:108
Particle beam.
Definition: IonSource.h:58
Definition: ControlledVocabulary.h:67
reflectron
Definition: Instrument.h:79
desorption ionization
Definition: IonSource.h:109
void loadFromOBO(const String &name, const String &filename)
Loads the CV from an OBO file.
void writeSourceFile_(std::ostream &os, const String &id, const SourceFile &software, Internal::MzMLValidator &validator)
Helper method that writes a source file.
Definition: MzMLHandler.h:3599
Int toInt() const
Conversion to int.
Definition: ControlledVocabulary.h:75
bool has_unit_accession
Definition: SemanticValidator.h:80
General data processing (if no other term applies)
Definition: DataProcessing.h:60
plasma desorption
Definition: IonSource.h:91
const Precursor & getPrecursor() const
returns a const reference to the precursors
Direct.
Definition: IonSource.h:55
const std::vector< ScanWindow > & getScanWindows() const
returns a const reference to the m/z scan windows
const SourceFile & getSourceFile() const
returns a const reference to the source file
Representation of a parsed CV term.
Definition: SemanticValidator.h:73
MapType * exp_
map pointer for reading
Definition: MzMLHandler.h:852
bool skip_spectrum_
Definition: MzMLHandler.h:945
Definition: ChromatogramSettings.h:76
magnetic deflection
Definition: Instrument.h:74
Linear ion trap.
Definition: MassAnalyzer.h:69
Map< String, std::vector< DataProcessing > > processing_
The data processing list: id => Instrument.
Definition: MzMLHandler.h:884
flame ionization
Definition: IonSource.h:90
Electron capture dissociation.
Definition: Precursor.h:71
Smoothing of the signal to reduce noise.
Definition: DataProcessing.h:63
photodiode array detector
Definition: IonDetector.h:73
Transient recorder.
Definition: IonDetector.h:88
Septum.
Definition: IonSource.h:62
Base64 decoder_
Decoder/Encoder for Base64-data in MzML.
Definition: MzMLHandler.h:931
DataType valueType() const
returns the type of value stored
Definition: DataValue.h:351
const String & getContactInfo() const
returns miscellaneous info about the contact person
Nano electrospray ionization.
Definition: IonSource.h:102
const DRange< 1 > & getRTRange() const
returns the RT range
Map< String, Sample > samples_
The sample list: id => Sample.
Definition: MzMLHandler.h:878
Nanospray inlet.
Definition: IonSource.h:73
double getIsolationWindowLowerOffset() const
returns the lower offset from the target m/z
MapType::ChromatogramPeakType ChromatogramPeakType
Chromatogram peak type.
Definition: MzMLHandler.h:253
Unknown.
Definition: IonDetector.h:54
static field
Definition: Instrument.h:84
void writeBinaryDataArray(std::ostream &os, const PeakFileOptions &pf_options_, std::vector< DataType > data_to_encode, bool is32bit, String array_type)
Definition: MzMLHandler.h:776
Definition: ControlledVocabulary.h:65
atmospheric pressure photo ionization
Definition: IonSource.h:100
String default_processing_
id of the default data processing (used when no processing is defined)
Definition: MzMLHandler.h:886
Deisotoping.
Definition: DataProcessing.h:62
electrospray ionisation
Definition: IonSource.h:83
PeakFileOptions & getOptions()
Get the peak file options.
Definition: MzMLHandler.h:228
secondary ion MS
Definition: IonSource.h:92
Radial ejection linear ion trap.
Definition: MassAnalyzer.h:58
Normalization of intensity values.
Definition: DataProcessing.h:70
Selected ion monitoring scan Synonyms: 'Multiple ion monitoring scan', 'SIM scan', 'MIM scan'.
Definition: InstrumentSettings.h:59
String & trim()
removes whitespaces (space, tab, line feed, carriage return) at the beginning and the end of the stri...
Interfaces::IMSDataConsumer< MapType > * consumer_
Consumer class to work on spectra.
Definition: MzMLHandler.h:937
delayed extraction
Definition: Instrument.h:75
void setSoftware(const Software &software)
sets the software used for processing
CVMappings mapping_
Definition: MzMLHandler.h:952
A 1-dimensional raw data point or peak.
Definition: Peak1D.h:55
Surface-induced dissociation.
Definition: Precursor.h:69
Scan window description.
Definition: ScanWindow.h:47
inductive detector
Definition: IonDetector.h:74
double getRT() const
Definition: MSSpectrum.h:243
static void writeFooter_(std::ostream &os, const PeakFileOptions &options_, std::vector< std::pair< std::string, long > > &spectra_offsets, std::vector< std::pair< std::string, long > > &chromatograms_offsets)
Write the mzML footer the appropriate compression term given the PeakFileOptions and the NumpressConf...
autoionization
Definition: IonSource.h:121
ReflectronState getReflectronState() const
returns the reflectron state (for TOF)
full scan mass spectrum, is a "mass spectrum" Synonyms: 'full spectrum', 'Q1 spectrum', 'Q3 spectrum', 'Single-Stage Mass Spectrometry'
Definition: InstrumentSettings.h:57
static void computeDataProperties_(std::vector< BinaryData > &data_, bool &precision_64, SignedSize &index, String index_name)
Peak data (also called centroided data or stick data)
Definition: SpectrumSettings.h:74
Post-source decay.
Definition: Precursor.h:67
chemi-ionization
Definition: IonSource.h:123
XRefType xref_type
xref value-type for the CV-term
Definition: ControlledVocabulary.h:88
Reservoir.
Definition: IonSource.h:63
Meta information about the sample.
Definition: Sample.h:60
Off.
Definition: MassAnalyzer.h:130
einzel lens
Definition: Instrument.h:80
Time-digital converter.
Definition: IonDetector.h:87
MSChromatogram< ChromatogramPeakType > ChromatogramType
Spectrum type.
Definition: MzMLHandler.h:257
Electro spray.
Definition: IonSource.h:67
daly detector
Definition: IonDetector.h:64
Photo multiplier.
Definition: IonDetector.h:56
MSSpectrum< PeakType > SpectrumType
Spectrum type.
Definition: MzMLHandler.h:255
String file_
File name.
Definition: XMLHandler.h:187
std::vector< BinaryData > data_
The spectrum data (or chromatogram data)
Definition: MzMLHandler.h:866
Description of a ion detector (part of a MS Instrument)
Definition: IonDetector.h:47
String name
Definition: SemanticValidator.h:76
double getIsolationWindowUpperOffset() const
returns the upper offset from the target m/z
Information about one raw data spectrum that was combined with several other raw data spectra...
Definition: Acquisition.h:50
String name
Text name.
Definition: ControlledVocabulary.h:80
virtual void writeTo(std::ostream &os)
Writes the contents to a stream.
Definition: MzMLHandler.h:3884
void getKeys(std::vector< String > &keys) const
fills the given vector with a list of all keys for which a value is set
Stored waveform inverse fourier transform.
Definition: MassAnalyzer.h:66
Definition: VersionInfo.h:63
void populateChromatogramsWithData_(std::vector< MzMLHandlerHelper::BinaryData > &input_data, Size &default_arr_length, const PeakFileOptions &peak_file_options, ChromatogramType &inp_chromatogram)
Fill a single chromatogram with data from input.
Definition: MzMLHandler.h:626
Batch (e.g. in MALDI)
Definition: IonSource.h:56
Conversion dynode photo multiplier.
Definition: IonDetector.h:60
static String getCompressionTerm_(const PeakFileOptions &opt, MSNumpressCoder::NumpressConfig np_compression, bool use_numpress=false)
Returns the appropriate compression term given the PeakFileOptions and the NumpressConfig.
const String & getName() const
returns the name of the software
vertical ionization
Definition: IonSource.h:130
void setUnit(const String &unit)
Sets the unit to the given String.
ChromatogramType getChromatogramType() const
returns the chromatogram type, e.g. a SRM chromatogram
MSNumpressCoder::NumpressConfig getNumpressConfigurationMassTime() const
Set numpress configuration options for m/z or rt dimension.
void writePrecursor_(std::ostream &os, const Precursor &precursor, Internal::MzMLValidator &validator)
Helper method that write precursor information from spectra and chromatograms.
Definition: MzMLHandler.h:3767
Unknown.
Definition: MassAnalyzer.h:55
const Product & getProduct() const
returns a const reference to the products
Absorbtion scan.
Definition: InstrumentSettings.h:69
Ion trap.
Definition: MassAnalyzer.h:65
Interface for classes that can store arbitrary meta information (Type-Name-Value tuples).
Definition: MetaInfoInterface.h:56
Invalid conversion exception.
Definition: Exception.h:363
void fatalError(const xercesc::SAXParseException &exception)
Multi-collector.
Definition: IonDetector.h:61
bool isEmpty() const
test if the value is empty
Definition: DataValue.h:360
Consecutive reaction monitoring scan Synonyms: 'CRM scan'.
Definition: InstrumentSettings.h:61
Loading a file.
Definition: XMLHandler.h:118
Analog-digital converter.
Definition: IonDetector.h:86
Determination of the peak charge.
Definition: DataProcessing.h:64
const String & getComment() const
returns the comment (default: "")
Electromagnetic radiation scan Synonyms: 'EMR spectrum'.
Definition: InstrumentSettings.h:67
MSNumpressCoder::NumpressConfig getNumpressConfigurationIntensity() const
Set numpress configuration options for intensity dimension.
bool in_spectrum_list_
Flag that indicates that we're inside a spectrum (in contrast to a chromatogram)
Definition: MzMLHandler.h:870
PeakType PeakType
Peak type.
Definition: MSSpectrum.h:105
Secure Hash Algorithm-1.
Definition: SourceFile.h:55
const String & getFileType() const
returns the file type
Invalid value exception.
Definition: Exception.h:336
laser desorption
Definition: IonSource.h:88
bool getFillData() const
returns whether to fill the actual data into the container (spectrum/chromatogram) ...
void getCounts(Size &spectra_counts, Size &chromatogram_counts)
Get the spectra and chromatogram counts of a file.
Definition: MzMLHandler.h:236
soft ionization
Definition: IonSource.h:127
std::vector< ChromatogramData > chromatogram_data_
Vector of chromatogram data stored for later parallel processing.
Definition: MzMLHandler.h:921
const String & getURL() const
returns the email address
Electron multiplier.
Definition: IonDetector.h:55
Blackbody infrared radiative dissociation.
Definition: Precursor.h:70
const IntegerDataArrays & getIntegerDataArrays() const
Returns a const reference to the integer meta data arrays.
Definition: MSChromatogram.h:274
const StringDataArrays & getStringDataArrays() const
Returns a const reference to the string meta data arrays.
Definition: MSSpectrum.h:310
point collector
Definition: IonDetector.h:71
UInt scan_count
Counting spectra and chromatograms.
Definition: MzMLHandler.h:940
Chromatography (liquid)
Definition: IonSource.h:57
String value
Definition: SemanticValidator.h:77
const String & getFirstName() const
returns the first name of the person
const String & getVersion() const
returns the software version
IonSource::Polarity getPolarity() const
returns the polarity
bool skip_chromatogram_
Flag that indicates whether this spectrum should be skipped (due to options)
Definition: MzMLHandler.h:944
Matrix-assisted laser desorption ionization.
Definition: IonSource.h:107
static VersionDetails create(const String &version)
parse String and return as proper struct
adiabatic ionization
Definition: IonSource.h:118
const String & getMethodOfCombination() const
returns the method of combination
pyrolysis mass spectrometry
Definition: IonSource.h:116
Low-energy collision-induced dissociation.
Definition: Precursor.h:75
The interface of a consumer of spectra and chromatograms.
Definition: IMSDataConsumer.h:68
Precursor ion scan.
Definition: InstrumentSettings.h:64
String prefix(SizeType length) const
returns the prefix of length length
Positive polarity.
Definition: IonSource.h:143
const String & getChecksum() const
returns the file's checksum
Definition: ChromatogramSettings.h:77
void writeSoftware_(std::ostream &os, const String &id, const Software &software, Internal::MzMLValidator &validator)
Helper method that writes a software.
Definition: MzMLHandler.h:3570
DateTime Class.
Definition: DateTime.h:55
Jet separator.
Definition: IonSource.h:61
OPENMS_INT64_TYPE Int64
Signed integer type (64bit)
Definition: Types.h:64
Base class for all classes that want to report their progress.
Definition: ProgressLogger.h:55
UInt selected_ion_count_
Count of selected ions.
Definition: MzMLHandler.h:956
const std::vector< Product > & getProducts() const
returns a const reference to the products
const String & getName() const
returns the name of the instrument
Int getFinalMSExponent() const
returns the final MS exponent
ControlledVocabulary::CVTerm getChildWithName_(const String &parent_accession, const String &name) const
Looks up a child CV term of parent_accession with the name name. If no such term is found...
Definition: MzMLHandler.h:3555
void setIdentifier(const String &identifier)
sets the index/number of the scan
MapType::PeakType PeakType
Peak type.
Definition: MzMLHandler.h:251
void encode(std::vector< FromType > &in, ByteOrder to_byte_order, String &out, bool zlib_compression=false)
Encodes a vector of floating point numbers to a Base64 string.
Definition: Base64.h:207
void setOptions(const PeakFileOptions &opt)
Set the peak file options.
Definition: MzMLHandler.h:222
double value
Definition: DataValue.h:70
Constant neutral gain scan Synonyms: 'CNG scan'.
Definition: InstrumentSettings.h:62
Definition: MSNumpressCoder.h:58
Membrane inlet.
Definition: IonSource.h:72
microchannel plate detector
Definition: IonDetector.h:65
const InstrumentSettings & getInstrumentSettings() const
returns a const reference to the instrument settings of the current spectrum
void writeUserParam_(std::ostream &os, const MetaInfoInterface &meta, UInt indent, String path, Internal::MzMLValidator &validator) const
Writes user terms.
Definition: MzMLHandler.h:3476
void encodeNP(const std::vector< double > &in, String &result, bool zlib_compression, const NumpressConfig &config)
Encodes a vector of floating point numbers into a Base64 string using numpress.
Definition: MSNumpressCoder.h:106
thermal ionization
Definition: IonSource.h:93
Conversion to mzData format.
Definition: DataProcessing.h:76
std::vector< Int > & getPossibleChargeStates()
Mutable access to possible charge states.
static bool handleBinaryDataArrayCVParam(std::vector< BinaryData > &data_, const String &accession, const String &value, const String &name)
void writeSpectrum_(std::ostream &os, const SpectrumType &spec, Size s, Internal::MzMLValidator &validator, bool renew_native_ids, std::vector< std::vector< DataProcessing > > &dps)
Definition: MzMLHandler.h:4868
bool has_unit_name
Definition: SemanticValidator.h:82
conversion dynode
Definition: IonDetector.h:67
Quadrupole.
Definition: MassAnalyzer.h:56
void fillChromatogramData_()
Fills the current chromatogram with data points and meta data.
Photodissociation.
Definition: Precursor.h:76
Collision-induced dissociation.
Definition: Precursor.h:66
MzMLHandler(MapType &exp, const String &filename, const String &version, ProgressLogger &logger)
Constructor for a read-only handler.
Definition: MzMLHandler.h:116
A 1-dimensional raw data point or peak for chromatograms.
Definition: ChromatogramPeak.h:55
Moving wire.
Definition: IonSource.h:65
Definition: Sample.h:65
Inductively coupled plasma.
Definition: IonSource.h:71
const DRange< 1 > & getMZRange() const
returns the MZ range
std::vector< std::pair< std::string, long > > chromatograms_offsets
Definition: MzMLHandler.h:927
void handleUserParam_(const String &parent_parent_tag, const String &parent_tag, const String &name, const String &type, const String &value)
Handles user terms.
Definition: MzMLHandler.h:3297
MzMLHandlerHelper::BinaryData BinaryData
Definition: MzMLHandler.h:259
void writeProduct_(std::ostream &os, const Product &product, Internal::MzMLValidator &validator)
Helper method that write precursor information from spectra and chromatograms.
Definition: MzMLHandler.h:3871
Map< String, Instrument > instruments_
The data processing list: id => Instrument.
Definition: MzMLHandler.h:882
High-energy collision-induced dissociation.
Definition: Precursor.h:74
field desorption
Definition: IonSource.h:89
const FloatDataArrays & getFloatDataArrays() const
Definition: MSChromatogram.h:250
desorption/ionization on silicon
Definition: IonSource.h:132
String current_id_
Id of the current list. Used for referencing param group, source file, sample, software, ...
Definition: MzMLHandler.h:872
std::vector< BinaryData > data
Definition: MzMLHandler.h:897
const std::vector< Precursor > & getPrecursors() const
returns a const reference to the precursors
Representation of controlled vocabulary mapping rules (for PSI formats)
Definition: CVMappings.h:57
Definition: ControlledVocabulary.h:73
atmospheric pressure matrix-assisted laser desorption ionization
Definition: IonSource.h:131
Options for loading files containing peak data.
Definition: PeakFileOptions.h:48
Map< String, std::vector< SemanticValidator::CVTerm > > ref_param_
The referencing param groups: id => array (accession, value)
Definition: MzMLHandler.h:874
autodetachment
Definition: IonSource.h:120
const FloatDataArrays & getFloatDataArrays() const
Returns a const reference to the float meta data arrays.
Definition: MSSpectrum.h:298
On.
Definition: MassAnalyzer.h:129
const String & getInstitution() const
returns the affiliation
Definition: Sample.h:65
Int getOrder() const
returns the position of this part in the whole Instrument.
const String & getNativeID() const
returns the native identifier for the spectrum, used by the acquisition software. ...
Unknown spectrum type.
Definition: SpectrumSettings.h:73
void writeChromatogram_(std::ostream &os, const ChromatogramType &chromatogram, Size c, Internal::MzMLValidator &validator)
Definition: MzMLHandler.h:5201
bool skip_data
Definition: MzMLHandler.h:900
const String & getLastName() const
returns the last name of the person
void setMSDataConsumer(Interfaces::IMSDataConsumer< MapType > *consumer)
Set the IMSDataConsumer consumer which will consume the read data.
Definition: MzMLHandler.h:243
int Int
Signed integer type.
Definition: Types.h:96
focal plane collector
Definition: IonDetector.h:69
bool getMz32Bit() const
Map class based on the STL map (containing several convenience functions)
Definition: Map.h:51
Description of a mass analyzer (part of a MS Instrument)
Definition: MassAnalyzer.h:48
Description of an ion source (part of a MS Instrument)
Definition: IonSource.h:47
Charge deconvolution.
Definition: DataProcessing.h:61
selected ion flow tube
Definition: Instrument.h:77
const MapType * cexp_
map pointer for writing
Definition: MzMLHandler.h:854
const String & getName() const
returns the sample name (default: "")
const String & getEmail() const
returns the email address
General file format conversion (if no other term applies)
Definition: DataProcessing.h:75
ChromatogramType chromatogram
Definition: MzMLHandler.h:917
void handleCVParam_(const String &parent_parent_tag, const String &parent_tag, const String &accession, const String &name, const String &value, const String &unit_accession="")
Handles CV terms.
Definition: MzMLHandler.h:1558
surface-assisted laser desorption ionization
Definition: IonSource.h:133
Definition: Sample.h:65
chemical ionisation
Definition: IonSource.h:85
virtual ~MzMLHandler()
Destructor.
Definition: MzMLHandler.h:190
double getConcentration() const
returns the concentration (in g/l) (default: 0.0)
SampleState getState() const
returns the state of aggregation (default: SAMPLENULL)
UInt chromatogram_count
Definition: MzMLHandler.h:941
bool validateCV_(const ControlledVocabulary::CVTerm &c, const String &path, const Internal::MzMLValidator &validator) const
Helper method to validate if the given CV is allowed in the current location (path) ...
Definition: MzMLHandler.h:3445
bool hasPrefix(const String &string) const
true if String begins with string, false otherwise
Parse Error exception.
Definition: Exception.h:608
virtual void characters(const XMLCh *const chars, const XMLSize_t length)
Parsing method for character data.
Definition: MzMLHandler.h:1003
Orbitrap.
Definition: MassAnalyzer.h:68
Size default_array_length
Definition: MzMLHandler.h:916
Moving belt.
Definition: IonSource.h:64
Magnetic sector.
Definition: MassAnalyzer.h:61
Continuous flow fast atom bombardment.
Definition: IonSource.h:70
double getVolume() const
returns the volume (in ml) (default: 0.0)
Unknown.
Definition: IonSource.h:82
Definition: Sample.h:65
Used to load CvMapping files.
Definition: CVMappingFile.h:57

OpenMS / TOPP release 2.0.0 Documentation generated on Sat May 16 2015 16:13:28 using doxygen 1.8.9.1