00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_FORMAT_HANDLERS_MZDATAHANDLER_H
00036 #define OPENMS_FORMAT_HANDLERS_MZDATAHANDLER_H
00037
00038 #include <OpenMS/CONCEPT/Exception.h>
00039 #include <OpenMS/CONCEPT/ProgressLogger.h>
00040 #include <OpenMS/FORMAT/HANDLERS/XMLHandler.h>
00041 #include <OpenMS/FORMAT/OPTIONS/PeakFileOptions.h>
00042 #include <OpenMS/FORMAT/Base64.h>
00043 #include <OpenMS/KERNEL/MSExperiment.h>
00044
00045 #include <sstream>
00046
00047 namespace OpenMS
00048 {
00049 namespace Internal
00050 {
00059 template <typename MapType>
00060 class MzDataHandler :
00061 public XMLHandler
00062 {
00063 public:
00066
00067 MzDataHandler(MapType & exp, const String & filename, const String & version, ProgressLogger & logger) :
00068 XMLHandler(filename, version),
00069 exp_(&exp),
00070 cexp_(0),
00071 peak_count_(0),
00072 meta_id_descs_(),
00073 decoder_(),
00074 skip_spectrum_(false),
00075 logger_(logger)
00076 {
00077 init_();
00078 }
00079
00081 MzDataHandler(const MapType & exp, const String & filename, const String & version, const ProgressLogger & logger) :
00082 XMLHandler(filename, version),
00083 exp_(0),
00084 cexp_(&exp),
00085 peak_count_(0),
00086 meta_id_descs_(),
00087 decoder_(),
00088 skip_spectrum_(false),
00089 logger_(logger)
00090 {
00091 init_();
00092 }
00093
00095 virtual ~MzDataHandler()
00096 {
00097 }
00098
00100
00101
00102
00103 virtual void endElement(const XMLCh * const , const XMLCh * const , const XMLCh * const qname);
00104
00105
00106 virtual void startElement(const XMLCh * const , const XMLCh * const , const XMLCh * const qname, const xercesc::Attributes & attributes);
00107
00108
00109 virtual void characters(const XMLCh * const chars, const XMLSize_t length);
00110
00112 void writeTo(std::ostream & os);
00113
00115 void setOptions(const PeakFileOptions & options)
00116 {
00117 options_ = options;
00118 }
00119
00120 private:
00121 void init_()
00122 {
00123 cv_terms_.resize(19);
00124
00125 String(";Solid;Liquid;Gas;Solution;Emulsion;Suspension").split(';', cv_terms_[0]);
00126
00127 String(";PositiveIonMode;NegativeIonMode").split(';', cv_terms_[1]);
00128
00129 String(";FWHM;TenPercentValley;Baseline").split(';', cv_terms_[2]);
00130
00131 String(";Constant;Proportional").split(';', cv_terms_[3]);
00132
00133
00134
00135 String(";Up;Down").split(';', cv_terms_[5]);
00136
00137 String(";Exponential;Linear;Quadratic").split(';', cv_terms_[6]);
00138
00139 String(";CentroidMassSpectrum;ContinuumMassSpectrum").split(';', cv_terms_[7]);
00140
00141 String(";On;Off;None").split(';', cv_terms_[8]);
00142
00143 String(";PulseCounting;ADC;TDC;TransientRecorder").split(';', cv_terms_[9]);
00144
00145 String(";ESI;EI;CI;FAB;TSP;LD;FD;FI;PD;SI;TI;API;ISI;CID;CAD;HN;APCI;APPI;ICP").split(';', cv_terms_[10]);
00146
00147 String(";Direct;Batch;Chromatography;ParticleBeam;MembraneSeparator;OpenSplit;JetSeparator;Septum;Reservoir;MovingBelt;MovingWire;FlowInjectionAnalysis;ElectrosprayInlet;ThermosprayInlet;Infusion;ContinuousFlowFastAtomBombardment;InductivelyCoupledPlasma").split(';', cv_terms_[11]);
00148
00149
00150
00151 String(";EM;Photomultiplier;FocalPlaneArray;FaradayCup;ConversionDynodeElectronMultiplier;ConversionDynodePhotomultiplier;Multi-Collector;ChannelElectronMultiplier").split(';', cv_terms_[13]);
00152
00153 String(";Quadrupole;PaulIonTrap;RadialEjectionLinearIonTrap;AxialEjectionLinearIonTrap;TOF;Sector;FourierTransform;IonStorage").split(';', cv_terms_[14]);
00154
00155
00156
00157
00158
00159
00160
00161 String("CID;PSD;PD;SID").split(';', cv_terms_[18]);
00162 }
00163
00164 protected:
00165
00167 typedef typename MapType::PeakType PeakType;
00169 typedef MSSpectrum<PeakType> SpectrumType;
00170
00172 MapType * exp_;
00174 const MapType * cexp_;
00175
00177 PeakFileOptions options_;
00178
00181
00182 UInt peak_count_;
00184 SpectrumType spec_;
00186 std::vector<std::pair<String, MetaInfoDescription> > meta_id_descs_;
00188 std::vector<String> data_to_decode_;
00190 std::vector<Real> data_to_encode_;
00191 std::vector<std::vector<Real> > decoded_list_;
00192 std::vector<std::vector<DoubleReal> > decoded_double_list_;
00193 std::vector<String> precisions_;
00194 std::vector<String> endians_;
00196
00198 Base64 decoder_;
00199
00201 bool skip_spectrum_;
00202
00204 const ProgressLogger & logger_;
00205
00207 void fillData_();
00208
00210
00211
00222 inline void writeCVS_(std::ostream & os, DoubleReal value, const String & acc, const String & name, UInt indent = 4) const
00223 {
00224 if (value != 0.0)
00225 {
00226 os << String(indent, '\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:" << acc << "\" name=\"" << name << "\" value=\"" << value << "\"/>\n";
00227 }
00228 }
00229
00241 inline void writeCVS_(std::ostream & os, const String & value, const String & acc, const String & name, UInt indent = 4) const
00242 {
00243 if (value != "")
00244 {
00245 os << String(indent, '\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:" << acc << "\" name=\"" << name << "\" value=\"" << value << "\"/>\n";
00246 }
00247 }
00248
00262 inline void writeCVS_(std::ostream & os, UInt value, UInt map, const String & acc, const String & name, UInt indent = 4)
00263 {
00264
00265 if (map >= cv_terms_.size())
00266 {
00267 warning(STORE, String("Cannot find map '") + map + "' needed to write CV term '" + name + "' with accession '" + acc + "'.");
00268 return;
00269 }
00270
00271 if (value >= cv_terms_[map].size())
00272 {
00273 warning(STORE, String("Cannot find value '") + value + "' needed to write CV term '" + name + "' with accession '" + acc + "'.");
00274 return;
00275 }
00276 writeCVS_(os, cv_terms_[map][value], acc, name, indent);
00277 }
00278
00280 inline void writeUserParam_(std::ostream & os, const MetaInfoInterface & meta, UInt indent = 4)
00281 {
00282 std::vector<String> keys;
00283 meta.getKeys(keys);
00284 for (std::vector<String>::const_iterator it = keys.begin(); it != keys.end(); ++it)
00285 {
00286 if ((*it)[0] != '#')
00287 {
00288 os << String(indent, '\t') << "<userParam name=\"" << *it << "\" value=\"" << meta.getMetaValue(*it) << "\"/>\n";
00289 }
00290 }
00291 }
00292
00300 void cvParam_(const String & name, const String & value);
00302
00308 inline void writeBinary_(std::ostream & os, Size size, const String & tag, const String & name = "", SignedSize id = -1)
00309 {
00310 os << "\t\t\t<" << tag;
00311 if (tag == "supDataArrayBinary" || tag == "supDataArray")
00312 {
00313 os << " id=\"" << id << "\"";
00314 }
00315 os << ">\n";
00316 if (tag == "supDataArrayBinary" || tag == "supDataArray")
00317 {
00318 os << "\t\t\t\t<arrayName>" << name << "</arrayName>\n";
00319 }
00320
00321 String str;
00322 decoder_.encode(data_to_encode_, Base64::BYTEORDER_LITTLEENDIAN, str);
00323 data_to_encode_.clear();
00324 os << "\t\t\t\t<data precision=\"32\" endian=\"little\" length=\""
00325 << size << "\">"
00326 << str
00327 << "</data>\n\t\t\t</" << tag << ">\n";
00328 }
00329
00330
00331 DataProcessing data_processing_;
00332
00333 };
00334
00335
00336
00337 template <typename MapType>
00338 void MzDataHandler<MapType>::characters(const XMLCh * const chars, const XMLSize_t )
00339 {
00340
00341 if (skip_spectrum_)
00342 return;
00343
00344 char * transcoded_chars = sm_.convert(chars);
00345
00346
00347 const String & current_tag = open_tags_.back();
00348
00349
00350 String parent_tag;
00351 if (open_tags_.size() > 1)
00352 parent_tag = *(open_tags_.end() - 2);
00353
00354
00355 if (current_tag == "sampleName")
00356 {
00357 exp_->getSample().setName(sm_.convert(chars));
00358 }
00359 else if (current_tag == "instrumentName")
00360 {
00361 exp_->getInstrument().setName(sm_.convert(chars));
00362 }
00363 else if (current_tag == "version")
00364 {
00365 data_processing_.getSoftware().setVersion(sm_.convert(chars));
00366 }
00367 else if (current_tag == "institution")
00368 {
00369 exp_->getContacts().back().setInstitution(sm_.convert(chars));
00370 }
00371 else if (current_tag == "contactInfo")
00372 {
00373 exp_->getContacts().back().setContactInfo(sm_.convert(chars));
00374 }
00375 else if (current_tag == "name" && parent_tag == "contact")
00376 {
00377 exp_->getContacts().back().setName(sm_.convert(chars));
00378 }
00379 else if (current_tag == "name" && parent_tag == "software")
00380 {
00381 data_processing_.getSoftware().setName(sm_.convert(chars));
00382 }
00383 else if (current_tag == "comments" && parent_tag == "software")
00384 {
00385 data_processing_.getSoftware().setMetaValue("comment", String(sm_.convert(chars)));
00386 }
00387 else if (current_tag == "comments" && parent_tag == "spectrumDesc")
00388 {
00389 spec_.setComment(transcoded_chars);
00390 }
00391 else if (current_tag == "data")
00392 {
00393
00394 data_to_decode_.back() += transcoded_chars;
00395 }
00396 else if (current_tag == "arrayName" && parent_tag == "supDataArrayBinary")
00397 {
00398 spec_.getFloatDataArrays().back().setName(transcoded_chars);
00399 }
00400 else if (current_tag == "nameOfFile" && parent_tag == "sourceFile")
00401 {
00402 exp_->getSourceFiles().back().setNameOfFile(sm_.convert(chars));
00403 }
00404 else if (current_tag == "nameOfFile" && parent_tag == "supSourceFile")
00405 {
00406
00407 }
00408 else if (current_tag == "pathToFile" && parent_tag == "sourceFile")
00409 {
00410 exp_->getSourceFiles().back().setPathToFile(sm_.convert(chars));
00411 }
00412 else if (current_tag == "pathToFile" && parent_tag == "supSourceFile")
00413 {
00414
00415 }
00416 else if (current_tag == "fileType" && parent_tag == "sourceFile")
00417 {
00418 exp_->getSourceFiles().back().setFileType(sm_.convert(chars));
00419 }
00420 else if (current_tag == "fileType" && parent_tag == "supSourceFile")
00421 {
00422
00423 }
00424 else
00425 {
00426 String trimmed_transcoded_chars = transcoded_chars;
00427 trimmed_transcoded_chars.trim();
00428 if (trimmed_transcoded_chars != "")
00429 {
00430 warning(LOAD, String("Unhandled character content in tag '") + current_tag + "': " + trimmed_transcoded_chars);
00431 }
00432 }
00433 }
00434
00435 template <typename MapType>
00436 void MzDataHandler<MapType>::startElement(const XMLCh * const , const XMLCh * const , const XMLCh * const qname, const xercesc::Attributes & attributes)
00437 {
00438 static const XMLCh * s_name = xercesc::XMLString::transcode("name");
00439 static const XMLCh * s_accession = xercesc::XMLString::transcode("accession");
00440 static const XMLCh * s_value = xercesc::XMLString::transcode("value");
00441 static const XMLCh * s_id = xercesc::XMLString::transcode("id");
00442 static const XMLCh * s_count = xercesc::XMLString::transcode("count");
00443 static const XMLCh * s_spectrumtype = xercesc::XMLString::transcode("spectrumType");
00444 static const XMLCh * s_methodofcombination = xercesc::XMLString::transcode("methodOfCombination");
00445 static const XMLCh * s_acqnumber = xercesc::XMLString::transcode("acqNumber");
00446 static const XMLCh * s_mslevel = xercesc::XMLString::transcode("msLevel");
00447 static const XMLCh * s_mzrangestart = xercesc::XMLString::transcode("mzRangeStart");
00448 static const XMLCh * s_mzrangestop = xercesc::XMLString::transcode("mzRangeStop");
00449 static const XMLCh * s_supdataarrayref = xercesc::XMLString::transcode("supDataArrayRef");
00450 static const XMLCh * s_precision = xercesc::XMLString::transcode("precision");
00451 static const XMLCh * s_endian = xercesc::XMLString::transcode("endian");
00452 static const XMLCh * s_length = xercesc::XMLString::transcode("length");
00453 static const XMLCh * s_comment = xercesc::XMLString::transcode("comment");
00454 static const XMLCh * s_accessionnumber = xercesc::XMLString::transcode("accessionNumber");
00455
00456 String tag = sm_.convert(qname);
00457 open_tags_.push_back(tag);
00458
00459
00460
00461 String parent_tag;
00462 if (open_tags_.size() > 1)
00463 parent_tag = *(open_tags_.end() - 2);
00464
00465
00466 if (tag != "spectrum" && skip_spectrum_)
00467 return;
00468
00469
00470
00471 if (tag == "sourceFile")
00472 {
00473 exp_->getSourceFiles().push_back(SourceFile());
00474 }
00475 if (tag == "contact")
00476 {
00477 exp_->getContacts().resize(exp_->getContacts().size() + 1);
00478 }
00479 else if (tag == "source")
00480 {
00481 exp_->getInstrument().getIonSources().resize(1);
00482 }
00483 else if (tag == "detector")
00484 {
00485 exp_->getInstrument().getIonDetectors().resize(1);
00486 }
00487 else if (tag == "analyzer")
00488 {
00489 exp_->getInstrument().getMassAnalyzers().resize(exp_->getInstrument().getMassAnalyzers().size() + 1);
00490 }
00491 else if (tag == "software")
00492 {
00493 data_processing_ = DataProcessing();
00494 if (attributes.getIndex(sm_.convert("completionTime")) != -1)
00495 {
00496 data_processing_.setCompletionTime(asDateTime_(sm_.convert(attributes.getValue(sm_.convert("completionTime")))));
00497 }
00498 }
00499 else if (tag == "precursor")
00500 {
00501 spec_.getPrecursors().push_back(Precursor());
00502 }
00503 else if (tag == "cvParam")
00504 {
00505 String accession = attributeAsString_(attributes, s_accession);
00506 String value = "";
00507 optionalAttributeAsString_(value, attributes, s_value);
00508 cvParam_(accession, value);
00509 }
00510 else if (tag == "supDataDesc")
00511 {
00512 String comment;
00513 if (optionalAttributeAsString_(comment, attributes, s_comment))
00514 {
00515 meta_id_descs_.back().second.setMetaValue("comment", comment);
00516 }
00517 }
00518 else if (tag == "userParam")
00519 {
00520 String name = attributeAsString_(attributes, s_name);
00521 String value = "";
00522 optionalAttributeAsString_(value, attributes, s_value);
00523
00524 if (parent_tag == "spectrumInstrument")
00525 {
00526 spec_.getInstrumentSettings().setMetaValue(name, value);
00527 }
00528 else if (parent_tag == "acquisition")
00529 {
00530 spec_.getAcquisitionInfo().back().setMetaValue(name, value);
00531 }
00532 else if (parent_tag == "ionSelection")
00533 {
00534 spec_.getPrecursors().back().setMetaValue(name, value);
00535 }
00536 else if (parent_tag == "activation")
00537 {
00538 spec_.getPrecursors().back().setMetaValue(name, value);
00539 }
00540 else if (parent_tag == "supDataDesc")
00541 {
00542 meta_id_descs_.back().second.setMetaValue(name, value);
00543 }
00544 else if (parent_tag == "detector")
00545 {
00546 exp_->getInstrument().getIonDetectors().back().setMetaValue(name, value);
00547 }
00548 else if (parent_tag == "source")
00549 {
00550 exp_->getInstrument().getIonSources().back().setMetaValue(name, value);
00551 }
00552 else if (parent_tag == "sampleDescription")
00553 {
00554 exp_->getSample().setMetaValue(name, value);
00555 }
00556 else if (parent_tag == "analyzer")
00557 {
00558 exp_->getInstrument().getMassAnalyzers().back().setMetaValue(name, value);
00559 }
00560 else if (parent_tag == "additional")
00561 {
00562 exp_->getInstrument().setMetaValue(name, value);
00563 }
00564 else if (parent_tag == "processingMethod")
00565 {
00566 data_processing_.setMetaValue(name, value);
00567 }
00568 else
00569 {
00570 warning(LOAD, "Invalid userParam: name=\"" + name + ", value=\"" + value + "\"");
00571 }
00572 }
00573 else if (tag == "supDataArrayBinary")
00574 {
00575
00576
00577 typename MapType::SpectrumType::FloatDataArray mda;
00578
00579 String id = attributeAsString_(attributes, s_id);
00580 for (Size i = 0; i < meta_id_descs_.size(); ++i)
00581 {
00582 if (meta_id_descs_[i].first == id)
00583 {
00584 mda.MetaInfoDescription::operator=(meta_id_descs_[i].second);
00585 break;
00586 }
00587 }
00588
00589 spec_.getFloatDataArrays().push_back(mda);
00590 }
00591 else if (tag == "spectrum")
00592 {
00593 spec_ = SpectrumType();
00594 spec_.setNativeID(String("spectrum=") + attributeAsString_(attributes, s_id));
00595 spec_.getDataProcessing().push_back(data_processing_);
00596 }
00597 else if (tag == "spectrumList")
00598 {
00599 if (options_.getMetadataOnly())
00600 throw EndParsingSoftly(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00601
00602 UInt count = attributeAsInt_(attributes, s_count);
00603 exp_->reserve(count);
00604 logger_.startProgress(0, count, "loading mzData file");
00605
00606 }
00607 else if (tag == "mzData")
00608 {
00609
00610 exp_->setIdentifier(attributeAsString_(attributes, s_accessionnumber));
00611 }
00612 else if (tag == "acqSpecification")
00613 {
00614 String tmp_type = attributeAsString_(attributes, s_spectrumtype);
00615 if (tmp_type == "discrete")
00616 {
00617 spec_.setType(SpectrumSettings::PEAKS);
00618 }
00619 else if (tmp_type == "continuous")
00620 {
00621 spec_.setType(SpectrumSettings::RAWDATA);
00622 }
00623 else
00624 {
00625 spec_.setType(SpectrumSettings::UNKNOWN);
00626 warning(LOAD, String("Invalid spectrum type '") + tmp_type + "'.");
00627 }
00628
00629 spec_.getAcquisitionInfo().setMethodOfCombination(attributeAsString_(attributes, s_methodofcombination));
00630 }
00631 else if (tag == "acquisition")
00632 {
00633 spec_.getAcquisitionInfo().insert(spec_.getAcquisitionInfo().end(), Acquisition());
00634 spec_.getAcquisitionInfo().back().setIdentifier(attributeAsString_(attributes, s_acqnumber));
00635 }
00636 else if (tag == "spectrumInstrument" || tag == "acqInstrument")
00637 {
00638 spec_.setMSLevel(attributeAsInt_(attributes, s_mslevel));
00639 ScanWindow window;
00640 optionalAttributeAsDouble_(window.begin, attributes, s_mzrangestart);
00641 optionalAttributeAsDouble_(window.end, attributes, s_mzrangestop);
00642 if (window.begin != 0.0 || window.end != 0.0)
00643 {
00644 spec_.getInstrumentSettings().getScanWindows().push_back(window);
00645 }
00646
00647 if (options_.hasMSLevels() && !options_.containsMSLevel(spec_.getMSLevel()))
00648 {
00649 skip_spectrum_ = true;
00650 }
00651 }
00652 else if (tag == "supDesc")
00653 {
00654 meta_id_descs_.push_back(std::make_pair(attributeAsString_(attributes, s_supdataarrayref), MetaInfoDescription()));
00655 }
00656 else if (tag == "data")
00657 {
00658
00659 precisions_.push_back(attributeAsString_(attributes, s_precision));
00660 endians_.push_back(attributeAsString_(attributes, s_endian));
00661
00662
00663 if (parent_tag == "mzArrayBinary")
00664 {
00665 peak_count_ = attributeAsInt_(attributes, s_length);
00666 spec_.reserve(peak_count_);
00667 }
00668 }
00669 else if (tag == "mzArrayBinary")
00670 {
00671 data_to_decode_.resize(data_to_decode_.size() + 1);
00672 }
00673 else if (tag == "intenArrayBinary")
00674 {
00675 data_to_decode_.resize(data_to_decode_.size() + 1);
00676 }
00677 else if (tag == "arrayName" && parent_tag == "supDataArrayBinary")
00678 {
00679
00680 data_to_decode_.resize(data_to_decode_.size() + 1);
00681 }
00682
00683 }
00684
00685 template <typename MapType>
00686 void MzDataHandler<MapType>::endElement(const XMLCh * const , const XMLCh * const , const XMLCh * const qname)
00687 {
00688 static UInt scan_count = 0;
00689
00690 static const XMLCh * s_spectrum = xercesc::XMLString::transcode("spectrum");
00691 static const XMLCh * s_mzdata = xercesc::XMLString::transcode("mzData");
00692
00693 open_tags_.pop_back();
00694
00695
00696 if (equal_(qname, s_spectrum))
00697 {
00698 if (!skip_spectrum_)
00699 {
00700 fillData_();
00701 exp_->push_back(spec_);
00702 }
00703 skip_spectrum_ = false;
00704 logger_.setProgress(++scan_count);
00705 decoded_list_.clear();
00706 decoded_double_list_.clear();
00707 data_to_decode_.clear();
00708 precisions_.clear();
00709 endians_.clear();
00710 meta_id_descs_.clear();
00711 }
00712 else if (equal_(qname, s_mzdata))
00713 {
00714 logger_.endProgress();
00715 scan_count = 0;
00716 }
00717
00718 sm_.clear();
00719 }
00720
00721 template <typename MapType>
00722 void MzDataHandler<MapType>::fillData_()
00723 {
00724 std::vector<Real> decoded;
00725 std::vector<DoubleReal> decoded_double;
00726
00727
00728
00729
00730
00731 for (Size i = 0; i < data_to_decode_.size(); ++i)
00732 {
00733
00734
00735 data_to_decode_[i].removeWhitespaces();
00736
00737 if (precisions_[i] == "64")
00738 {
00739 if (endians_[i] == "big")
00740 {
00741
00742 decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_BIGENDIAN, decoded_double);
00743 }
00744 else
00745 {
00746
00747 decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_LITTLEENDIAN, decoded_double);
00748 }
00749
00750
00751
00752 decoded_double_list_.push_back(decoded_double);
00753 decoded_list_.push_back(std::vector<float>());
00754 }
00755 else
00756 {
00757 if (endians_[i] == "big")
00758 {
00759
00760 decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_BIGENDIAN, decoded);
00761 }
00762 else
00763 {
00764
00765 decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_LITTLEENDIAN, decoded);
00766 }
00767
00768 decoded_list_.push_back(decoded);
00769 decoded_double_list_.push_back(std::vector<double>());
00770 }
00771 }
00772
00773
00774 {
00775
00776 bool mz_precision_64 = true;
00777 if (precisions_[0] == "32")
00778 {
00779 mz_precision_64 = false;
00780 }
00781 bool int_precision_64 = true;
00782 if (precisions_[1] == "32")
00783 {
00784 int_precision_64 = false;
00785 }
00786
00787
00788 for (Size i = 0; i < spec_.getFloatDataArrays().size(); ++i)
00789 {
00790 spec_.getFloatDataArrays()[i].reserve(peak_count_);
00791 }
00792
00793
00794 for (Size n = 0; n < peak_count_; ++n)
00795 {
00796 DoubleReal mz = mz_precision_64 ? decoded_double_list_[0][n] : decoded_list_[0][n];
00797 DoubleReal intensity = int_precision_64 ? decoded_double_list_[1][n] : decoded_list_[1][n];
00798 if ((!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(mz)))
00799 && (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(intensity))))
00800 {
00801 PeakType tmp;
00802 tmp.setIntensity(intensity);
00803 tmp.setMZ(mz);
00804 spec_.push_back(tmp);
00805
00806 for (Size i = 0; i < spec_.getFloatDataArrays().size(); ++i)
00807 {
00808 spec_.getFloatDataArrays()[i].push_back(precisions_[2 + i] == "64" ? decoded_double_list_[2 + i][n] : decoded_list_[2 + i][n]);
00809 }
00810 }
00811 }
00812 }
00813 }
00814
00815 template <typename MapType>
00816 void MzDataHandler<MapType>::writeTo(std::ostream & os)
00817 {
00818 logger_.startProgress(0, cexp_->size(), "storing mzData file");
00819
00820 os << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
00821 << "<mzData version=\"1.05\" accessionNumber=\"" << cexp_->getIdentifier() << "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://psidev.sourceforge.net/ms/xml/mzdata/mzdata.xsd\">\n";
00822
00823
00824
00825 const Sample & sm = cexp_->getSample();
00826 os << "\t<description>\n"
00827 << "\t\t<admin>\n"
00828 << "\t\t\t<sampleName>"
00829 << sm.getName()
00830 << "</sampleName>\n";
00831
00832 if (sm.getNumber() != "" || sm.getState() || sm.getMass() || sm.getVolume() || sm.getConcentration() || !sm.isMetaEmpty())
00833 {
00834 os << "\t\t\t<sampleDescription>\n";
00835 writeCVS_(os, sm.getNumber(), "1000001", "SampleNumber");
00836 writeCVS_(os, sm.getState(), 0, "1000003", "SampleState");
00837 writeCVS_(os, sm.getMass(), "1000004", "SampleMass");
00838 writeCVS_(os, sm.getVolume(), "1000005", "SampleVolume");
00839 writeCVS_(os, sm.getConcentration(), "1000006", "SampleConcentration");
00840 writeUserParam_(os, cexp_->getSample());
00841 os << "\t\t\t</sampleDescription>\n";
00842 }
00843
00844 if (cexp_->getSourceFiles().size() >= 1)
00845 {
00846 os << "\t\t\t<sourceFile>\n"
00847 << "\t\t\t\t<nameOfFile>" << cexp_->getSourceFiles()[0].getNameOfFile() << "</nameOfFile>\n"
00848 << "\t\t\t\t<pathToFile>" << cexp_->getSourceFiles()[0].getPathToFile() << "</pathToFile>\n";
00849 if (cexp_->getSourceFiles()[0].getFileType() != "")
00850 os << "\t\t\t\t<fileType>" << cexp_->getSourceFiles()[0].getFileType() << "</fileType>\n";
00851 os << "\t\t\t</sourceFile>\n";
00852 }
00853 if (cexp_->getSourceFiles().size() > 1)
00854 {
00855 warning(STORE, "The MzData format can store only one source file. Only the first one is stored!");
00856 }
00857
00858 for (Size i = 0; i < cexp_->getContacts().size(); ++i)
00859 {
00860 os << "\t\t\t<contact>\n"
00861 << "\t\t\t\t<name>" << cexp_->getContacts()[i].getFirstName() << " " << cexp_->getContacts()[i].getLastName() << "</name>\n"
00862 << "\t\t\t\t<institution>" << cexp_->getContacts()[i].getInstitution() << "</institution>\n";
00863 if (cexp_->getContacts()[i].getContactInfo() != "")
00864 os << "\t\t\t\t<contactInfo>" << cexp_->getContacts()[i].getContactInfo() << "</contactInfo>\n";
00865 os << "\t\t\t</contact>\n";
00866 }
00867
00868 if (cexp_->getContacts().empty())
00869 {
00870 os << "\t\t\t<contact>\n"
00871 << "\t\t\t\t<name></name>\n"
00872 << "\t\t\t\t<institution></institution>\n";
00873 os << "\t\t\t</contact>\n";
00874 }
00875
00876 os << "\t\t</admin>\n";
00877 const Instrument & inst = cexp_->getInstrument();
00878 os << "\t\t<instrument>\n"
00879 << "\t\t\t<instrumentName>" << inst.getName() << "</instrumentName>\n"
00880 << "\t\t\t<source>\n";
00881 if (inst.getIonSources().size() >= 1)
00882 {
00883 writeCVS_(os, inst.getIonSources()[0].getInletType(), 11, "1000007", "InletType");
00884 writeCVS_(os, inst.getIonSources()[0].getIonizationMethod(), 10, "1000008", "IonizationType");
00885 writeCVS_(os, inst.getIonSources()[0].getPolarity(), 1, "1000009", "IonizationMode");
00886 writeUserParam_(os, inst.getIonSources()[0]);
00887 }
00888 if (inst.getIonSources().size() > 1)
00889 {
00890 warning(STORE, "The MzData format can store only one ion source. Only the first one is stored!");
00891 }
00892 os << "\t\t\t</source>\n";
00893
00894
00895 if (inst.getMassAnalyzers().empty())
00896 {
00897 os << "\t\t\t<analyzerList count=\"1\">\n"
00898 << "\t\t\t\t<analyzer>\n"
00899 << "\t\t\t\t</analyzer>\n";
00900 }
00901 else
00902 {
00903 os << "\t\t\t<analyzerList count=\"" << inst.getMassAnalyzers().size() << "\">\n";
00904 for (Size i = 0; i < inst.getMassAnalyzers().size(); ++i)
00905 {
00906 os << "\t\t\t\t<analyzer>\n";
00907 const MassAnalyzer & ana = inst.getMassAnalyzers()[i];
00908 writeCVS_(os, ana.getType(), 14, "1000010", "AnalyzerType", 5);
00909 writeCVS_(os, ana.getResolution(), "1000011", "MassResolution", 5);
00910 writeCVS_(os, ana.getResolutionMethod(), 2, "1000012", "ResolutionMethod", 5);
00911 writeCVS_(os, ana.getResolutionType(), 3, "1000013", "ResolutionType", 5);
00912 writeCVS_(os, ana.getAccuracy(), "1000014", "Accuracy", 5);
00913 writeCVS_(os, ana.getScanRate(), "1000015", "ScanRate", 5);
00914 writeCVS_(os, ana.getScanTime(), "1000016", "ScanTime", 5);
00915 writeCVS_(os, ana.getScanDirection(), 5, "1000018", "ScanDirection", 5);
00916 writeCVS_(os, ana.getScanLaw(), 6, "1000019", "ScanLaw", 5);
00917 writeCVS_(os, ana.getReflectronState(), 8, "1000021", "ReflectronState", 5);
00918 writeCVS_(os, ana.getTOFTotalPathLength(), "1000022", "TOFTotalPathLength", 5);
00919 writeCVS_(os, ana.getIsolationWidth(), "1000023", "IsolationWidth", 5);
00920 writeCVS_(os, ana.getFinalMSExponent(), "1000024", "FinalMSExponent", 5);
00921 writeCVS_(os, ana.getMagneticFieldStrength(), "1000025", "MagneticFieldStrength", 5);
00922 writeUserParam_(os, ana, 5);
00923 os << "\t\t\t\t</analyzer>\n";
00924 }
00925 }
00926 os << "\t\t\t</analyzerList>\n";
00927
00928 os << "\t\t\t<detector>\n";
00929 if (inst.getIonDetectors().size() >= 1)
00930 {
00931 writeCVS_(os, inst.getIonDetectors()[0].getType(), 13, "1000026", "DetectorType");
00932 writeCVS_(os, inst.getIonDetectors()[0].getAcquisitionMode(), 9, "1000027", "DetectorAcquisitionMode");
00933 writeCVS_(os, inst.getIonDetectors()[0].getResolution(), "1000028", "DetectorResolution");
00934 writeCVS_(os, inst.getIonDetectors()[0].getADCSamplingFrequency(), "1000029", "SamplingFrequency");
00935 writeUserParam_(os, inst.getIonDetectors()[0]);
00936 }
00937 if (inst.getIonDetectors().size() > 1)
00938 {
00939 warning(STORE, "The MzData format can store only one ion detector. Only the first one is stored!");
00940 }
00941 os << "\t\t\t</detector>\n";
00942 if (inst.getVendor() != "" || inst.getModel() != "" || inst.getCustomizations() != "")
00943 {
00944 os << "\t\t\t<additional>\n";
00945 writeCVS_(os, inst.getVendor(), "1000030", "Vendor");
00946 writeCVS_(os, inst.getModel(), "1000031", "Model");
00947 writeCVS_(os, inst.getCustomizations(), "1000032", "Customization");
00948 writeUserParam_(os, inst);
00949 os << "\t\t\t</additional>\n";
00950 }
00951 os << "\t\t</instrument>\n";
00952
00953
00954 if (cexp_->size() == 0 || (*cexp_)[0].getDataProcessing().empty())
00955 {
00956 os << "\t\t<dataProcessing>\n"
00957 << "\t\t\t<software>\n"
00958 << "\t\t\t\t<name></name>\n"
00959 << "\t\t\t\t<version></version>\n"
00960 << "\t\t\t</software>\n"
00961 << "\t\t</dataProcessing>\n";
00962 }
00963 else
00964 {
00965 const DataProcessing & data_processing = (*cexp_)[0].getDataProcessing()[0];
00966 os << "\t\t<dataProcessing>\n"
00967 << "\t\t\t<software";
00968 if (data_processing.getCompletionTime() != DateTime())
00969 {
00970 os << " completionTime=\"" << data_processing.getCompletionTime().get().substitute(' ', 'T') << "\"";
00971 }
00972 os << ">\n"
00973 << "\t\t\t\t<name>" << data_processing.getSoftware().getName() << "</name>\n"
00974 << "\t\t\t\t<version>" << data_processing.getSoftware().getVersion() << "</version>\n";
00975 os << "\t\t\t</software>\n"
00976 << "\t\t\t<processingMethod>\n";
00977 if (data_processing.getProcessingActions().count(DataProcessing::DEISOTOPING) == 1)
00978 {
00979 os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"Deisotoping\" accession=\"PSI:1000033\" />\n";
00980 }
00981 if (data_processing.getProcessingActions().count(DataProcessing::CHARGE_DECONVOLUTION) == 1)
00982 {
00983 os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"ChargeDeconvolution\" accession=\"PSI:1000034\" />\n";
00984 }
00985 if (data_processing.getProcessingActions().count(DataProcessing::PEAK_PICKING) == 1)
00986 {
00987 os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"Centroid Mass Spectrum\" accession=\"PSI:1000127\"/>\n";
00988 }
00989 writeUserParam_(os, data_processing);
00990 os << "\t\t\t</processingMethod>\n"
00991 << "\t\t</dataProcessing>\n";
00992 }
00993 os << "\t</description>\n";
00994
00995
00996
00997 if (cexp_->size() != 0)
00998 {
00999
01000
01001 bool all_numbers = true;
01002 bool all_empty = true;
01003 bool all_prefixed_numbers = true;
01004 for (Size s = 0; s < cexp_->size(); s++)
01005 {
01006 String native_id = (*cexp_)[s].getNativeID();
01007 if (!native_id.hasPrefix("spectrum="))
01008 {
01009 all_prefixed_numbers = false;
01010 }
01011 else
01012 {
01013 native_id = native_id.substr(9);
01014 }
01015 try
01016 {
01017 native_id.toInt();
01018 }
01019 catch (Exception::ConversionError &)
01020 {
01021 all_numbers = false;
01022 all_prefixed_numbers = false;
01023 if (native_id != "")
01024 {
01025 all_empty = false;
01026 }
01027 }
01028 }
01029
01030 if (!all_numbers && !all_empty)
01031 {
01032 warning(STORE, "Not all spectrum native IDs are numbers or correctly prefixed with 'spectrum='. The spectra are renumbered and the native IDs are lost!");
01033 }
01034
01035 Map<Int, Size> level_id;
01036
01037 os << "\t<spectrumList count=\"" << cexp_->size() << "\">\n";
01038 for (Size s = 0; s < cexp_->size(); ++s)
01039 {
01040 logger_.setProgress(s);
01041 const SpectrumType & spec = (*cexp_)[s];
01042
01043 Size spectrum_id = s + 1;
01044 if (all_prefixed_numbers)
01045 {
01046 spectrum_id = spec.getNativeID().substr(9).toInt();
01047 }
01048 else if (all_numbers)
01049 {
01050 spectrum_id = spec.getNativeID().toInt();
01051 }
01052 os << "\t\t<spectrum id=\"" << spectrum_id << "\">\n"
01053 << "\t\t\t<spectrumDesc>\n"
01054 << "\t\t\t\t<spectrumSettings>\n";
01055
01056 if (!spec.getAcquisitionInfo().empty())
01057 {
01058 os << "\t\t\t\t\t<acqSpecification spectrumType=\"";
01059 if (spec.getType() == SpectrumSettings::PEAKS)
01060 {
01061 os << "discrete";
01062 }
01063 else if (spec.getType() == SpectrumSettings::RAWDATA)
01064 {
01065 os << "continuous";
01066 }
01067 else
01068 {
01069 warning(STORE, "Spectrum type is unknown, assuming 'discrete'");
01070 os << "discrete";
01071 }
01072
01073 os << "\" methodOfCombination=\"" << spec.getAcquisitionInfo().getMethodOfCombination() << "\""
01074 << " count=\"" << spec.getAcquisitionInfo().size() << "\">\n";
01075 for (Size i = 0; i < spec.getAcquisitionInfo().size(); ++i)
01076 {
01077 const Acquisition & ac = spec.getAcquisitionInfo()[i];
01078 Int acq_number = 0;
01079 try
01080 {
01081 if (ac.getIdentifier() != "")
01082 {
01083 acq_number = ac.getIdentifier().toInt();
01084 }
01085 }
01086 catch (...)
01087 {
01088 warning(STORE, String("Could not convert acquisition identifier '") + ac.getIdentifier() + "' to an integer. Using '0' instead!");
01089 acq_number = 0;
01090 }
01091 os << "\t\t\t\t\t\t<acquisition acqNumber=\"" << acq_number << "\">\n";
01092 writeUserParam_(os, ac, 7);
01093 os << "\t\t\t\t\t\t</acquisition>\n";
01094 }
01095 os << "\t\t\t\t\t</acqSpecification>\n";
01096 }
01097
01098 const InstrumentSettings & iset = spec.getInstrumentSettings();
01099 os << "\t\t\t\t\t<spectrumInstrument msLevel=\"" << spec.getMSLevel() << "\"";
01100 level_id[spec.getMSLevel()] = spectrum_id;
01101
01102 if (!iset.getScanWindows().empty())
01103 {
01104 os << " mzRangeStart=\"" << iset.getScanWindows()[0].begin << "\" mzRangeStop=\"" << iset.getScanWindows()[0].end << "\"";
01105 }
01106 if (iset.getScanWindows().size() > 1)
01107 {
01108 warning(STORE, "The MzData format can store only one scan window for each scan. Only the first one is stored!");
01109 }
01110 os << ">\n";
01111
01112
01113 switch (iset.getScanMode())
01114 {
01115 case InstrumentSettings::UNKNOWN:
01116
01117 break;
01118
01119 case InstrumentSettings::MASSSPECTRUM:
01120 case InstrumentSettings::MS1SPECTRUM:
01121 case InstrumentSettings::MSNSPECTRUM:
01122 if (iset.getZoomScan())
01123 {
01124 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"Zoom\"/>\n";
01125 }
01126 else
01127 {
01128 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"MassScan\"/>\n";
01129 }
01130 break;
01131
01132 case InstrumentSettings::SIM:
01133 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"SelectedIonDetection\"/>\n";
01134 break;
01135
01136 case InstrumentSettings::SRM:
01137 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"SelectedReactionMonitoring\"/>\n";
01138 break;
01139
01140 case InstrumentSettings::CRM:
01141 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConsecutiveReactionMonitoring\"/>\n";
01142 break;
01143
01144 case InstrumentSettings::CNG:
01145 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConstantNeutralGainScan\"/>\n";
01146 break;
01147
01148 case InstrumentSettings::CNL:
01149 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConstantNeutralLossScan\"/>\n";
01150 break;
01151
01152 case InstrumentSettings::PRECURSOR:
01153 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"PrecursorIonScan\"/>\n";
01154 break;
01155
01156 case InstrumentSettings::ABSORBTION:
01157 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"PhotodiodeArrayDetector\"/>\n";
01158 break;
01159
01160 case InstrumentSettings::EMC:
01161 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"EnhancedMultiplyChargedScan\"/>\n";
01162 break;
01163
01164 case InstrumentSettings::TDF:
01165 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"TimeDelayedFragmentationScan\"/>\n";
01166 break;
01167
01168 default:
01169 os << "\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"MassScan\"/>\n";
01170 warning(STORE, String("Scan mode '") + InstrumentSettings::NamesOfScanMode[iset.getScanMode()] + "' not supported by mzData. Using 'MassScan' scan mode!");
01171 }
01172
01173
01174 if (spec.getInstrumentSettings().getPolarity() == IonSource::POSITIVE)
01175 {
01176 os << String(6, '\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:1000037\" name=\"Polarity\" value=\"Positive\"/>\n";
01177 }
01178 else if (spec.getInstrumentSettings().getPolarity() == IonSource::NEGATIVE)
01179 {
01180 os << String(6, '\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:1000037\" name=\"Polarity\" value=\"Negative\"/>\n";
01181 }
01182
01183
01184 writeCVS_(os, spec.getRT(), "1000039", "TimeInSeconds", 6);
01185 writeUserParam_(os, spec.getInstrumentSettings(), 6);
01186 os << "\t\t\t\t\t</spectrumInstrument>\n\t\t\t\t</spectrumSettings>\n";
01187
01188 if (spec.getPrecursors().size() != 0)
01189 {
01190 Int precursor_ms_level = spec.getMSLevel() - 1;
01191 SignedSize precursor_id = -1;
01192 if (level_id.has(precursor_ms_level))
01193 {
01194 precursor_id = level_id[precursor_ms_level];
01195 }
01196 os << "\t\t\t\t<precursorList count=\"" << spec.getPrecursors().size() << "\">\n";
01197 for (Size i = 0; i < spec.getPrecursors().size(); ++i)
01198 {
01199 const Precursor & precursor = spec.getPrecursors()[i];
01200 os << "\t\t\t\t\t<precursor msLevel=\"" << precursor_ms_level << "\" spectrumRef=\"" << precursor_id << "\">\n";
01201 os << "\t\t\t\t\t\t<ionSelection>\n";
01202 if (precursor != Precursor())
01203 {
01204 writeCVS_(os, precursor.getMZ(), "1000040", "MassToChargeRatio", 7);
01205 writeCVS_(os, precursor.getCharge(), "1000041", "ChargeState", 7);
01206 writeCVS_(os, precursor.getIntensity(), "1000042", "Intensity", 7);
01207 os << "\t\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000043\" name=\"IntensityUnit\" value=\"NumberOfCounts\"/>\n";
01208 writeUserParam_(os, precursor, 7);
01209 }
01210 os << "\t\t\t\t\t\t</ionSelection>\n";
01211 os << "\t\t\t\t\t\t<activation>\n";
01212 if (precursor != Precursor())
01213 {
01214 if (precursor.getActivationMethods().size() > 0)
01215 {
01216 writeCVS_(os, *(precursor.getActivationMethods().begin()), 18, "1000044", "ActivationMethod", 7);
01217 }
01218 writeCVS_(os, precursor.getActivationEnergy(), "1000045", "CollisionEnergy", 7);
01219 os << "\t\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000046\" name=\"EnergyUnit\" value=\"eV\"/>\n";
01220 }
01221 os << "\t\t\t\t\t\t</activation>\n";
01222 os << "\t\t\t\t\t</precursor>\n";
01223 }
01224 os << "\t\t\t\t</precursorList>\n";
01225 }
01226 os << "\t\t\t</spectrumDesc>\n";
01227
01228
01229 if (options_.getWriteSupplementalData())
01230 {
01231
01232 for (Size i = 0; i < spec.getFloatDataArrays().size(); ++i)
01233 {
01234 const MetaInfoDescription & desc = spec.getFloatDataArrays()[i];
01235 os << "\t\t\t<supDesc supDataArrayRef=\"" << (i + 1) << "\">\n";
01236 if (!desc.isMetaEmpty())
01237 {
01238 os << "\t\t\t\t<supDataDesc>\n";
01239 writeUserParam_(os, desc, 5);
01240 os << "\t\t\t\t</supDataDesc>\n";
01241 }
01242 os << "\t\t\t</supDesc>\n";
01243 }
01244 }
01245
01246
01247 data_to_encode_.clear();
01248 for (Size i = 0; i < spec.size(); i++)
01249 {
01250 data_to_encode_.push_back(spec[i].getPosition()[0]);
01251 }
01252
01253 writeBinary_(os, spec.size(), "mzArrayBinary");
01254
01255
01256 data_to_encode_.clear();
01257 for (Size i = 0; i < spec.size(); i++)
01258 {
01259 data_to_encode_.push_back(spec[i].getIntensity());
01260 }
01261
01262 writeBinary_(os, spec.size(), "intenArrayBinary");
01263
01264
01265 if (options_.getWriteSupplementalData())
01266 {
01267
01268 for (Size i = 0; i < spec.getFloatDataArrays().size(); ++i)
01269 {
01270 const typename MapType::SpectrumType::FloatDataArray & mda = spec.getFloatDataArrays()[i];
01271
01272 if (mda.size() != spec.size())
01273 {
01274 error(LOAD, String("Length of meta data array (index:'") + i + "' name:'" + mda.getName() + "') differs from spectrum length. meta data array: " + mda.size() + " / spectrum: " + spec.size() + " .");
01275 }
01276
01277 data_to_encode_.clear();
01278 for (Size j = 0; j < mda.size(); j++)
01279 {
01280 data_to_encode_.push_back(mda[j]);
01281 }
01282
01283 writeBinary_(os, mda.size(), "supDataArrayBinary", mda.getName(), i + 1);
01284 }
01285 }
01286
01287 os << "\t\t</spectrum>\n";
01288 }
01289 }
01290 else
01291 {
01292 os << "\t<spectrumList count=\"1\">\n";
01293 os << "\t\t<spectrum id=\"1\">\n";
01294 os << "\t\t\t<spectrumDesc>\n";
01295 os << "\t\t\t\t<spectrumSettings>\n";
01296 os << "\t\t\t\t\t<spectrumInstrument msLevel=\"1\"/>\n";
01297 os << "\t\t\t\t</spectrumSettings>\n";
01298 os << "\t\t\t</spectrumDesc>\n";
01299 os << "\t\t\t<mzArrayBinary>\n";
01300 os << "\t\t\t\t<data length=\"0\" endian=\"little\" precision=\"32\"></data>\n";
01301 os << "\t\t\t</mzArrayBinary>\n";
01302 os << "\t\t\t<intenArrayBinary>\n";
01303 os << "\t\t\t\t<data length=\"0\" endian=\"little\" precision=\"32\"></data>\n";
01304 os << "\t\t\t</intenArrayBinary>\n";
01305 os << "\t\t</spectrum>\n";
01306 }
01307 os << "\t</spectrumList>\n</mzData>\n";
01308
01309 logger_.endProgress();
01310 }
01311
01312 template <typename MapType>
01313 void MzDataHandler<MapType>::cvParam_(const String & accession, const String & value)
01314 {
01315 String error = "";
01316
01317
01318 String parent_tag;
01319 if (open_tags_.size() > 1)
01320 parent_tag = *(open_tags_.end() - 2);
01321
01322 if (parent_tag == "spectrumInstrument")
01323 {
01324 if (accession == "PSI:1000036")
01325 {
01326 if (value == "Zoom")
01327 {
01328 spec_.getInstrumentSettings().setZoomScan(true);
01329 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
01330 }
01331 else if (value == "MassScan")
01332 {
01333 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
01334 }
01335 else if (value == "SelectedIonDetection")
01336 {
01337 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SIM);
01338 }
01339 else if (value == "SelectedReactionMonitoring")
01340 {
01341 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SRM);
01342 }
01343 else if (value == "ConsecutiveReactionMonitoring")
01344 {
01345 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CRM);
01346 }
01347 else if (value == "ConstantNeutralGainScan")
01348 {
01349 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNG);
01350 }
01351 else if (value == "ConstantNeutralLossScan")
01352 {
01353 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNL);
01354 }
01355 else if (value == "ProductIonScan")
01356 {
01357 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MSNSPECTRUM);
01358 spec_.setMSLevel(2);
01359 }
01360 else if (value == "PrecursorIonScan")
01361 {
01362 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::PRECURSOR);
01363 }
01364 else if (value == "EnhancedResolutionScan")
01365 {
01366 spec_.getInstrumentSettings().setZoomScan(true);
01367 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
01368 }
01369 else
01370 {
01371 if (spec_.getMSLevel() >= 2)
01372 {
01373 exp_->back().getInstrumentSettings().setScanMode(InstrumentSettings::MSNSPECTRUM);
01374 }
01375 else
01376 {
01377 spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
01378 warning(LOAD, String("Unknown scan mode '") + value + "'. Assuming full scan");
01379 }
01380 }
01381 }
01382 else if (accession == "PSI:1000038")
01383 {
01384 spec_.setRT(asDouble_(value) * 60);
01385 if (options_.hasRTRange() && !options_.getRTRange().encloses(DPosition<1>(spec_.getRT())))
01386 {
01387 skip_spectrum_ = true;
01388 }
01389 }
01390 else if (accession == "PSI:1000039")
01391 {
01392 spec_.setRT(asDouble_(value));
01393 if (options_.hasRTRange() && !options_.getRTRange().encloses(DPosition<1>(spec_.getRT())))
01394 {
01395 skip_spectrum_ = true;
01396 }
01397 }
01398 else if (accession == "PSI:1000037")
01399 {
01400 if (value == "Positive" || value == "positive" || value == "+")
01401 {
01402 spec_.getInstrumentSettings().setPolarity(IonSource::POSITIVE);
01403 }
01404 else if (value == "Negative" || value == "negative" || value == "-")
01405 {
01406 spec_.getInstrumentSettings().setPolarity(IonSource::NEGATIVE);
01407 }
01408 else
01409 {
01410 warning(LOAD, String("Invalid scan polarity (PSI:1000037) detected: \"") + value + "\". Valid are 'Positive' or 'Negative'.");
01411 }
01412 }
01413 else
01414 {
01415 error = "SpectrumDescription.SpectrumSettings.SpectrumInstrument";
01416 }
01417 }
01418 else if (parent_tag == "ionSelection")
01419 {
01420 if (accession == "PSI:1000040")
01421 {
01422 spec_.getPrecursors().back().setMZ(asDouble_(value));
01423 }
01424 else if (accession == "PSI:1000041")
01425 {
01426 if (spec_.getPrecursors().back().getCharge() != 0)
01427 {
01428 warning(LOAD, String("Multiple precursor charges detected, expected only one! Ignoring this charge settings! accession=\"") + accession + "\", value=\"" + value + "\"");
01429 spec_.getPrecursors().back().setCharge(0);
01430 }
01431 else
01432 {
01433 spec_.getPrecursors().back().setCharge(asInt_(value));
01434 }
01435 }
01436 else if (accession == "PSI:1000042")
01437 {
01438 spec_.getPrecursors().back().setIntensity(asDouble_(value));
01439 }
01440 else if (accession == "PSI:1000043")
01441 {
01442
01443 }
01444 else
01445 {
01446 error = "PrecursorList.Precursor.IonSelection.UserParam";
01447 }
01448 }
01449 else if (parent_tag == "activation")
01450 {
01451 if (accession == "PSI:1000044")
01452 {
01453 spec_.getPrecursors().back().getActivationMethods().insert((Precursor::ActivationMethod)cvStringToEnum_(18, value, "activation method"));
01454 }
01455 else if (accession == "PSI:1000045")
01456 {
01457 spec_.getPrecursors().back().setActivationEnergy(asDouble_(value));
01458 }
01459 else if (accession == "PSI:1000046")
01460 {
01461
01462 }
01463 else
01464 {
01465 error = "PrecursorList.Precursor.Activation.UserParam";
01466 }
01467 }
01468 else if (parent_tag == "supDataDesc")
01469 {
01470
01471 error = "supDataDesc.UserParam";
01472 }
01473 else if (parent_tag == "acquisition")
01474 {
01475
01476 error = "spectrumDesc.spectrumSettings.acquisitionSpecification.acquisition.UserParam";
01477 }
01478 else if (parent_tag == "detector")
01479 {
01480 if (accession == "PSI:1000026")
01481 {
01482 exp_->getInstrument().getIonDetectors().back().setType((IonDetector::Type)cvStringToEnum_(13, value, "detector type"));
01483 }
01484 else if (accession == "PSI:1000028")
01485 {
01486 exp_->getInstrument().getIonDetectors().back().setResolution(asDouble_(value));
01487 }
01488 else if (accession == "PSI:1000029")
01489 {
01490 exp_->getInstrument().getIonDetectors().back().setADCSamplingFrequency(asDouble_(value));
01491 }
01492 else if (accession == "PSI:1000027")
01493 {
01494 exp_->getInstrument().getIonDetectors().back().setAcquisitionMode((IonDetector::AcquisitionMode)cvStringToEnum_(9, value, "acquisition mode"));
01495 }
01496 else
01497 {
01498 error = "Description.Instrument.Detector.UserParam";
01499 }
01500 }
01501 else if (parent_tag == "source")
01502 {
01503 if (accession == "PSI:1000008")
01504 {
01505 exp_->getInstrument().getIonSources().back().setIonizationMethod((IonSource::IonizationMethod)cvStringToEnum_(10, value, "ion source"));
01506 }
01507 else if (accession == "PSI:1000007")
01508 {
01509 exp_->getInstrument().getIonSources().back().setInletType((IonSource::InletType)cvStringToEnum_(11, value, "inlet type"));
01510 }
01511 else if (accession == "PSI:1000009")
01512 {
01513 exp_->getInstrument().getIonSources().back().setPolarity((IonSource::Polarity)cvStringToEnum_(1, value, "polarity"));
01514 }
01515 else
01516 {
01517 error = "Description.Instrument.Source.UserParam";
01518 }
01519 }
01520 else if (parent_tag == "sampleDescription")
01521 {
01522 if (accession == "PSI:1000001")
01523 {
01524 exp_->getSample().setNumber(value);
01525 }
01526 else if (accession == "PSI:1000003")
01527 {
01528 exp_->getSample().setState((Sample::SampleState)cvStringToEnum_(0, value, "sample state"));
01529 }
01530 else if (accession == "PSI:1000004")
01531 {
01532 exp_->getSample().setMass(asDouble_(value));
01533 }
01534 else if (accession == "PSI:1000005")
01535 {
01536 exp_->getSample().setVolume(asDouble_(value));
01537 }
01538 else if (accession == "PSI:1000006")
01539 {
01540 exp_->getSample().setConcentration(asDouble_(value));
01541 }
01542 else
01543 {
01544 error = "Description.Admin.SampleDescription.UserParam";
01545 }
01546 }
01547 else if (parent_tag == "analyzer")
01548 {
01549 if (accession == "PSI:1000010")
01550 {
01551 exp_->getInstrument().getMassAnalyzers().back().setType((MassAnalyzer::AnalyzerType)cvStringToEnum_(14, value, "analyzer type"));
01552 }
01553 else if (accession == "PSI:1000011")
01554 {
01555 exp_->getInstrument().getMassAnalyzers().back().setResolution(asDouble_(value));
01556 }
01557 else if (accession == "PSI:1000012")
01558 {
01559 exp_->getInstrument().getMassAnalyzers().back().setResolutionMethod((MassAnalyzer::ResolutionMethod)cvStringToEnum_(2, value, "resolution method"));
01560 }
01561 else if (accession == "PSI:1000013")
01562 {
01563 exp_->getInstrument().getMassAnalyzers().back().setResolutionType((MassAnalyzer::ResolutionType)cvStringToEnum_(3, value, "resolution type"));
01564 }
01565 else if (accession == "PSI:1000014")
01566 {
01567 exp_->getInstrument().getMassAnalyzers().back().setAccuracy(asDouble_(value));
01568 }
01569 else if (accession == "PSI:1000015")
01570 {
01571 exp_->getInstrument().getMassAnalyzers().back().setScanRate(asDouble_(value));
01572 }
01573 else if (accession == "PSI:1000016")
01574 {
01575 exp_->getInstrument().getMassAnalyzers().back().setScanTime(asDouble_(value));
01576 }
01577 else if (accession == "PSI:1000018")
01578 {
01579 exp_->getInstrument().getMassAnalyzers().back().setScanDirection((MassAnalyzer::ScanDirection)cvStringToEnum_(5, value, "scan direction"));
01580 }
01581 else if (accession == "PSI:1000019")
01582 {
01583 exp_->getInstrument().getMassAnalyzers().back().setScanLaw((MassAnalyzer::ScanLaw)cvStringToEnum_(6, value, "scan law"));
01584 }
01585 else if (accession == "PSI:1000020")
01586 {
01587
01588 }
01589 else if (accession == "PSI:1000021")
01590 {
01591 exp_->getInstrument().getMassAnalyzers().back().setReflectronState((MassAnalyzer::ReflectronState)cvStringToEnum_(8, value, "reflectron state"));
01592 }
01593 else if (accession == "PSI:1000022")
01594 {
01595 exp_->getInstrument().getMassAnalyzers().back().setTOFTotalPathLength(asDouble_(value));
01596 }
01597 else if (accession == "PSI:1000023")
01598 {
01599 exp_->getInstrument().getMassAnalyzers().back().setIsolationWidth(asDouble_(value));
01600 }
01601 else if (accession == "PSI:1000024")
01602 {
01603 exp_->getInstrument().getMassAnalyzers().back().setFinalMSExponent(asInt_(value));
01604 }
01605 else if (accession == "PSI:1000025")
01606 {
01607 exp_->getInstrument().getMassAnalyzers().back().setMagneticFieldStrength(asDouble_(value));
01608 }
01609 else if (accession == "PSI:1000017")
01610 {
01611
01612 }
01613 else
01614 {
01615 error = "AnalyzerList.Analyzer.UserParam";
01616 }
01617 }
01618 else if (parent_tag == "additional")
01619 {
01620 if (accession == "PSI:1000030")
01621 {
01622 exp_->getInstrument().setVendor(value);
01623 }
01624 else if (accession == "PSI:1000031")
01625 {
01626 exp_->getInstrument().setModel(value);
01627 }
01628 else if (accession == "PSI:1000032")
01629 {
01630 exp_->getInstrument().setCustomizations(value);
01631 }
01632 else
01633 {
01634 error = "Description.Instrument.Additional";
01635 }
01636 }
01637 else if (parent_tag == "processingMethod")
01638 {
01639 if (accession == "PSI:1000033")
01640 {
01641 data_processing_.getProcessingActions().insert(DataProcessing::DEISOTOPING);
01642 }
01643 else if (accession == "PSI:1000034")
01644 {
01645 data_processing_.getProcessingActions().insert(DataProcessing::CHARGE_DECONVOLUTION);
01646 }
01647 else if (accession == "PSI:1000127")
01648 {
01649 data_processing_.getProcessingActions().insert(DataProcessing::PEAK_PICKING);
01650 }
01651 else if (accession == "PSI:1000035")
01652 {
01653
01654 }
01655 else
01656 {
01657 error = "DataProcessing.DataProcessing.UserParam";
01658 }
01659 }
01660 else
01661 {
01662 warning(LOAD, String("Unexpected cvParam: accession=\"") + accession + "\" value=\"" + value + "\" in tag " + parent_tag);
01663 }
01664
01665 if (error != "")
01666 {
01667 warning(LOAD, String("Invalid cvParam: accession=\"") + accession + "\" value=\"" + value + "\" in " + error);
01668 }
01669
01670 }
01671
01672 }
01673
01674 }
01675
01676 #endif