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

OpenMS / TOPP release 1.11.1 Documentation generated on Thu Nov 14 2013 11:19:18 using doxygen 1.8.5