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

OpenMS / TOPP release 2.0.0 Documentation generated on Tue Nov 1 2016 16:34:46 using doxygen 1.8.11