~ubuntu-branches/ubuntu/wily/openms/wily

« back to all changes in this revision

Viewing changes to include/OpenMS/FORMAT/HANDLERS/MzDataHandler.h

  • Committer: Package Import Robot
  • Author(s): Filippo Rusconi
  • Date: 2012-11-12 15:58:12 UTC
  • Revision ID: package-import@ubuntu.com-20121112155812-vr15wtg9b50cuesg
Tags: upstream-1.9.0
ImportĀ upstreamĀ versionĀ 1.9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: C++; tab-width: 2; -*-
 
2
// vi: set ts=2:
 
3
//
 
4
// --------------------------------------------------------------------------
 
5
//                   OpenMS Mass Spectrometry Framework
 
6
// --------------------------------------------------------------------------
 
7
//  Copyright (C) 2003-2011 -- Oliver Kohlbacher, Knut Reinert
 
8
//
 
9
//  This library is free software; you can redistribute it and/or
 
10
//  modify it under the terms of the GNU Lesser General Public
 
11
//  License as published by the Free Software Foundation; either
 
12
//  version 2.1 of the License, or (at your option) any later version.
 
13
//
 
14
//  This library is distributed in the hope that it will be useful,
 
15
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
//  Lesser General Public License for more details.
 
18
//
 
19
//  You should have received a copy of the GNU Lesser General Public
 
20
//  License along with this library; if not, write to the Free Software
 
21
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
22
//
 
23
// --------------------------------------------------------------------------
 
24
// $Maintainer: Andreas Bertsch $
 
25
// $Authors: Marc Sturm $
 
26
// --------------------------------------------------------------------------
 
27
 
 
28
#ifndef OPENMS_FORMAT_HANDLERS_MZDATAHANDLER_H
 
29
#define OPENMS_FORMAT_HANDLERS_MZDATAHANDLER_H
 
30
 
 
31
#include <OpenMS/CONCEPT/Exception.h>
 
32
#include <OpenMS/CONCEPT/ProgressLogger.h>
 
33
#include <OpenMS/FORMAT/HANDLERS/XMLHandler.h>
 
34
#include <OpenMS/FORMAT/PeakFileOptions.h>
 
35
#include <OpenMS/FORMAT/Base64.h>
 
36
#include <OpenMS/KERNEL/MSExperiment.h>
 
37
 
 
38
#include <sstream>
 
39
 
 
40
namespace OpenMS
 
41
{
 
42
        namespace Internal
 
43
        {
 
44
                /**
 
45
                        @brief XML handler for MzDataFile
 
46
                        
 
47
                        MapType has to be a MSExperiment or have the same interface.
 
48
                        Do not use this class. It is only needed in MzDataFile.
 
49
                        
 
50
                        @improvement Add implementation and tests of 'supDataArray' to store IntegerDataArray and StringDataArray of MSSpectrum (Hiwi)
 
51
                */
 
52
                template <typename MapType>
 
53
                class MzDataHandler
 
54
                        : public XMLHandler
 
55
                {
 
56
                 public:
 
57
      /**@name Constructors and destructor */
 
58
      //@{
 
59
      /// Constructor for a write-only handler
 
60
      MzDataHandler(MapType& exp, const String& filename, const String& version, ProgressLogger& logger)
 
61
                                : XMLHandler(filename, version),
 
62
                                        exp_(&exp),
 
63
                                        cexp_(0),
 
64
                                        peak_count_(0),
 
65
                                        meta_id_descs_(),
 
66
                                        decoder_(),
 
67
                                        skip_spectrum_(false),
 
68
                                        logger_(logger)
 
69
                {
 
70
                                init_();                                
 
71
                        }
 
72
 
 
73
      /// Constructor for a read-only handler
 
74
      MzDataHandler(const MapType& exp, const String& filename, const String& version, const ProgressLogger& logger)
 
75
                                : XMLHandler(filename, version),
 
76
                                        exp_(0),
 
77
                                        cexp_(&exp),
 
78
                                        peak_count_(0),
 
79
                                        meta_id_descs_(),
 
80
                                        decoder_(),
 
81
                                        skip_spectrum_(false),
 
82
                                        logger_(logger)
 
83
                {
 
84
                                init_();                                
 
85
                        }
 
86
 
 
87
      /// Destructor
 
88
      virtual ~MzDataHandler()
 
89
      {
 
90
      }
 
91
      //@}
 
92
 
 
93
 
 
94
                        // Docu in base class
 
95
      virtual void endElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname);
 
96
                        
 
97
                        // Docu in base class
 
98
      virtual void startElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname, const xercesc::Attributes& attributes);
 
99
                        
 
100
                        // Docu in base class
 
101
      virtual void characters(const XMLCh* const chars, const XMLSize_t length);
 
102
 
 
103
                /// Writes the contents to a stream
 
104
                        void writeTo(std::ostream& os);
 
105
                
 
106
                        ///Sets the options
 
107
                        void setOptions(const PeakFileOptions& options)
 
108
                        { 
 
109
                                options_ = options; 
 
110
                        }
 
111
                
 
112
                private:
 
113
                        void init_()
 
114
                        {
 
115
                                cv_terms_.resize(19);
 
116
                                // SampleState
 
117
                                String(";Solid;Liquid;Gas;Solution;Emulsion;Suspension").split(';',cv_terms_[0]);
 
118
                                // IonizationMode
 
119
                                String(";PositiveIonMode;NegativeIonMode").split(';',cv_terms_[1]);
 
120
                                // ResolutionMethod
 
121
                                String(";FWHM;TenPercentValley;Baseline").split(';',cv_terms_[2]);
 
122
                                // ResolutionType
 
123
                                String(";Constant;Proportional").split(';',cv_terms_[3]);
 
124
                                // ScanFunction
 
125
                                // is no longer used cv_terms_[4] is empty now
 
126
                                // ScanDirection
 
127
                                String(";Up;Down").split(';',cv_terms_[5]);
 
128
                                // ScanLaw
 
129
                                String(";Exponential;Linear;Quadratic").split(';',cv_terms_[6]);
 
130
                                // PeakProcessing
 
131
                                String(";CentroidMassSpectrum;ContinuumMassSpectrum").split(';',cv_terms_[7]);
 
132
                                // ReflectronState
 
133
                                String(";On;Off;None").split(';',cv_terms_[8]);
 
134
                                // AcquisitionMode
 
135
                                String(";PulseCounting;ADC;TDC;TransientRecorder").split(';',cv_terms_[9]);
 
136
                                // IonizationType
 
137
                                String(";ESI;EI;CI;FAB;TSP;LD;FD;FI;PD;SI;TI;API;ISI;CID;CAD;HN;APCI;APPI;ICP").split(';',cv_terms_[10]);
 
138
                                // InletType
 
139
                                String(";Direct;Batch;Chromatography;ParticleBeam;MembraneSeparator;OpenSplit;JetSeparator;Septum;Reservoir;MovingBelt;MovingWire;FlowInjectionAnalysis;ElectrosprayInlet;ThermosprayInlet;Infusion;ContinuousFlowFastAtomBombardment;InductivelyCoupledPlasma").split(';',cv_terms_[11]);
 
140
                                // TandemScanningMethod
 
141
                                // is no longer used cv_terms_[12] is empty now
 
142
                                // DetectorType
 
143
                                String(";EM;Photomultiplier;FocalPlaneArray;FaradayCup;ConversionDynodeElectronMultiplier;ConversionDynodePhotomultiplier;Multi-Collector;ChannelElectronMultiplier").split(';',cv_terms_[13]);
 
144
                                // AnalyzerType
 
145
                                String(";Quadrupole;PaulIonTrap;RadialEjectionLinearIonTrap;AxialEjectionLinearIonTrap;TOF;Sector;FourierTransform;IonStorage").split(';',cv_terms_[14]);
 
146
                                // EnergyUnits
 
147
                                // is no longer used cv_terms_[15] is empty now
 
148
                                // ScanMode
 
149
                                // is no longer used cv_terms_[16] is empty now
 
150
                                // Polarity
 
151
                                // is no longer used cv_terms_[17] is empty now
 
152
                                // ActivationMethod
 
153
                                String("CID;PSD;PD;SID").split(';',cv_terms_[18]);                      
 
154
                        }
 
155
 
 
156
 
 
157
                 protected:
 
158
      
 
159
      /// Peak type
 
160
      typedef typename MapType::PeakType PeakType;
 
161
      /// Spectrum type
 
162
                        typedef MSSpectrum<PeakType> SpectrumType;
 
163
                        
 
164
                        /// map pointer for reading
 
165
                        MapType* exp_;
 
166
                        /// map pointer for writing
 
167
                        const MapType* cexp_;
 
168
                        
 
169
                        ///Options that can be set for loading/storing
 
170
                        PeakFileOptions options_;
 
171
                
 
172
                        /**@name temporary datastructures to hold parsed data */
 
173
                        //@{
 
174
                        /// The number of peaks in the current spectrum
 
175
                        UInt peak_count_;
 
176
                        /// The current spectrum
 
177
                        SpectrumType spec_;
 
178
                        /// An array of pairs MetaInfodescriptions and their ids
 
179
                        std::vector< std::pair<String, MetaInfoDescription> > meta_id_descs_;
 
180
                        /// encoded data which is read and has to be decoded
 
181
                        std::vector<String> data_to_decode_;
 
182
                        /// floating point numbers which have to be encoded and written
 
183
                        std::vector<Real> data_to_encode_;
 
184
                        std::vector<std::vector<Real> > decoded_list_;
 
185
                        std::vector<std::vector<DoubleReal> > decoded_double_list_;
 
186
                        std::vector<String> precisions_;
 
187
                        std::vector<String> endians_;
 
188
                        //@}
 
189
 
 
190
                        /// Decoder/Encoder for Base64-data in MzData
 
191
                        Base64 decoder_;
 
192
 
 
193
                        /// Flag that indicates whether this spectrum should be skipped (due to options)
 
194
                        bool skip_spectrum_;
 
195
                        
 
196
                        /// Progress logger
 
197
                        const ProgressLogger& logger_;
 
198
 
 
199
                        /// fills the current spectrum with peaks and meta data
 
200
                        void fillData_();
 
201
 
 
202
                        ///@name cvParam and userParam handling methods (for mzData and FeatureXML)
 
203
                        //@{
 
204
                        /**  
 
205
                                @brief write cvParam containing strings to stream
 
206
                                
 
207
                                @p value string value
 
208
                                @p acc accession number defined by ontology
 
209
                                @p name term defined by ontology
 
210
                                @p indent number of tabs used in front of tag
 
211
                                
 
212
                                Example:
 
213
                                &lt;cvParam cvLabel="psi" accession="PSI:@p acc" name="@p name" value="@p value"/&gt;
 
214
                        */
 
215
                        inline void writeCVS_(std::ostream& os, DoubleReal value, const String& acc, const String& name, UInt indent=4) const
 
216
                        {
 
217
                                if (value!=0.0)
 
218
                                {
 
219
                                        os << String(indent,'\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:" << acc << "\" name=\"" << name << "\" value=\"" << value << "\"/>\n";
 
220
                                }
 
221
                        }
 
222
                        /**  
 
223
                                @brief write cvParam containing strings to stream
 
224
                                
 
225
                                @p value string value
 
226
                                @p acc accession number defined by ontology
 
227
                                @p name term defined by ontology
 
228
                                @p indent number of tabs used in front of tag
 
229
                                
 
230
                                Example:
 
231
                                &lt;cvParam cvLabel="psi" accession="PSI:@p acc" name="@p name" value="@p value"/&gt;
 
232
                        */
 
233
                        inline void writeCVS_(std::ostream& os, const String& value, const String& acc, const String& name, UInt indent=4) const
 
234
                        {
 
235
                                if (value!="")
 
236
                                {
 
237
                                        os << String(indent,'\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:" << acc << "\" name=\"" << name << "\" value=\"" << value << "\"/>\n";
 
238
                                }
 
239
                        }
 
240
 
 
241
                        /**  
 
242
                                @brief write cvParam element to stream
 
243
 
 
244
                                @p os Output stream
 
245
                                @p value enumeration value      
 
246
                                @p map index if the terms in cv_terms_
 
247
                                @p acc accession number defined by ontology
 
248
                                @p name term defined by ontology
 
249
                                @p indent number of tabs used in front of tag
 
250
                                
 
251
                                Example:
 
252
                                &lt;cvParam cvLabel="psi" accession="PSI:@p acc" name="@p name" value=""/&gt;
 
253
                        */
 
254
                        inline void writeCVS_(std::ostream& os, UInt value, UInt map, const String& acc, const String& name, UInt indent=4)
 
255
                        {
 
256
                                //abort when receiving a wrong map index
 
257
                                if (map>=cv_terms_.size())
 
258
                                {
 
259
                                        warning(STORE, String("Cannot find map '") + map + "' needed to write CV term '" + name + "' with accession '" + acc + "'.");
 
260
                                        return;
 
261
                                }
 
262
                                //abort when receiving a wrong term index
 
263
                                if (value>=cv_terms_[map].size())
 
264
                                {
 
265
                                        warning(STORE, String("Cannot find value '") + value + "' needed to write CV term '" + name + "' with accession '" + acc + "'.");
 
266
                                        return;
 
267
                                }
 
268
                                writeCVS_(os, cv_terms_[map][value], acc, name, indent);
 
269
                        }
 
270
                        
 
271
                        ///Writing the MetaInfo as UserParam to the file
 
272
                        inline void writeUserParam_(std::ostream& os, const MetaInfoInterface& meta, UInt indent=4)
 
273
                        {
 
274
                                std::vector<String> keys;
 
275
                                meta.getKeys(keys);
 
276
                                for (std::vector<String>::const_iterator it = keys.begin(); it!=keys.end(); ++it)
 
277
                                {
 
278
                                        if ( (*it)[0] != '#')  // internally used meta info start with '#'
 
279
                                        {
 
280
                                                os << String(indent,'\t') << "<userParam name=\"" << *it << "\" value=\"" << meta.getMetaValue(*it) << "\"/>\n";
 
281
                                        }
 
282
                                }
 
283
                        }
 
284
                        /** 
 
285
                                @brief read attributes of MzData's cvParamType
 
286
 
 
287
                                Example:
 
288
                                &lt;cvParam cvLabel="psi" accession="PSI:1000001" name="@p name" value="@p value"/&gt;
 
289
                                @p name and sometimes @p value are defined in the MzData ontology.
 
290
                        */
 
291
                        void cvParam_(const String& name, const String& value);
 
292
                        //@}
 
293
 
 
294
                        /**
 
295
                                @brief write binary data to stream (first one)
 
296
                        
 
297
                                The @p name and @p id are only used if the @p tag is @em supDataArrayBinary or @em supDataArray.
 
298
                        */
 
299
                        inline void writeBinary_(std::ostream& os, Size size, const String& tag, const String& name="", SignedSize id=-1)
 
300
                        {
 
301
                                os      << "\t\t\t<" << tag;
 
302
                                if (tag=="supDataArrayBinary" || tag=="supDataArray")
 
303
                                {
 
304
                                        os << " id=\"" << id << "\"";
 
305
                                }
 
306
                                os << ">\n";
 
307
                                if (tag=="supDataArrayBinary" || tag=="supDataArray")
 
308
                                {
 
309
                                        os << "\t\t\t\t<arrayName>" << name << "</arrayName>\n";
 
310
                                }
 
311
 
 
312
                                String str;                             
 
313
                                decoder_.encode(data_to_encode_, Base64::BYTEORDER_LITTLEENDIAN, str);
 
314
                                data_to_encode_.clear();
 
315
                                os << "\t\t\t\t<data precision=\"32\" endian=\"little\" length=\""
 
316
                                         << size << "\">"
 
317
                                         << str
 
318
                                         << "</data>\n\t\t\t</" << tag << ">\n";
 
319
                        }
 
320
                        
 
321
                        //Data processing auxilary variable
 
322
                        DataProcessing data_processing_;
 
323
                        
 
324
                };
 
325
 
 
326
                //--------------------------------------------------------------------------------
 
327
 
 
328
                template <typename MapType>
 
329
                void MzDataHandler<MapType>::characters(const XMLCh* const chars, const XMLSize_t /*length*/)
 
330
                {
 
331
                        // skip current spectrum
 
332
                        if (skip_spectrum_) return;
 
333
                        
 
334
                        char* transcoded_chars = sm_.convert(chars);
 
335
                        
 
336
                        //current tag
 
337
                        const String& current_tag = open_tags_.back();
 
338
                        
 
339
                        //determine the parent tag
 
340
                        String parent_tag;
 
341
                        if (open_tags_.size()>1) parent_tag = *(open_tags_.end()-2);
 
342
                        
 
343
                        
 
344
                        if (current_tag=="sampleName")
 
345
                        {
 
346
                                exp_->getSample().setName( sm_.convert(chars) );
 
347
                        }
 
348
                        else if (current_tag=="instrumentName")
 
349
                        {
 
350
                                exp_->getInstrument().setName(sm_.convert(chars));
 
351
                        }
 
352
                        else if (current_tag=="version")
 
353
                        {
 
354
                                data_processing_.getSoftware().setVersion( sm_.convert(chars) );
 
355
                        }
 
356
                        else if (current_tag=="institution")
 
357
                        {
 
358
                                exp_->getContacts().back().setInstitution( sm_.convert(chars) );
 
359
                        }
 
360
                        else if (current_tag=="contactInfo")
 
361
                        {
 
362
                                exp_->getContacts().back().setContactInfo( sm_.convert(chars) );
 
363
                        }
 
364
                        else if (current_tag=="name" && parent_tag=="contact")
 
365
                        {
 
366
                                exp_->getContacts().back().setName(sm_.convert(chars));
 
367
                        }
 
368
                        else if (current_tag=="name" && parent_tag=="software")
 
369
                        {
 
370
                                data_processing_.getSoftware().setName( sm_.convert(chars) );
 
371
                        }
 
372
                        else if (current_tag=="comments" && parent_tag=="software")
 
373
                        {
 
374
                                data_processing_.getSoftware().setMetaValue("comment", String(sm_.convert(chars)) );
 
375
                        }
 
376
                        else if (current_tag == "comments" && parent_tag=="spectrumDesc")
 
377
                        {
 
378
                                spec_.setComment( transcoded_chars );
 
379
                        }
 
380
                        else if (current_tag == "data")
 
381
                        {
 
382
                                //chars may be split to several chunks => concatenate them
 
383
                                data_to_decode_.back() += transcoded_chars;
 
384
                        }
 
385
                        else if (current_tag == "arrayName" && parent_tag=="supDataArrayBinary")
 
386
                        {
 
387
                                spec_.getFloatDataArrays().back().setName(transcoded_chars);
 
388
                        }
 
389
                        else if (current_tag=="nameOfFile" && parent_tag == "sourceFile")
 
390
                        {
 
391
                                exp_->getSourceFiles().back().setNameOfFile( sm_.convert(chars) );
 
392
                        }
 
393
                        else if (current_tag == "nameOfFile" && parent_tag == "supSourceFile")
 
394
                        {
 
395
                                //ignored
 
396
                        }
 
397
                        else if (current_tag=="pathToFile" && parent_tag == "sourceFile")
 
398
                        {
 
399
                                exp_->getSourceFiles().back().setPathToFile( sm_.convert(chars) );
 
400
                        }
 
401
                        else if (current_tag == "pathToFile" && parent_tag == "supSourceFile")
 
402
                        {
 
403
                                //ignored
 
404
                        }
 
405
                        else if (current_tag=="fileType" && parent_tag == "sourceFile")
 
406
                        {
 
407
                                exp_->getSourceFiles().back().setFileType( sm_.convert(chars) );
 
408
                        }
 
409
                        else if (current_tag == "fileType" && parent_tag == "supSourceFile")
 
410
                        {
 
411
                                //ignored
 
412
                        }
 
413
                        else
 
414
                        {
 
415
                                String trimmed_transcoded_chars = transcoded_chars;
 
416
                                trimmed_transcoded_chars.trim();
 
417
                                if (trimmed_transcoded_chars!="")
 
418
                                {
 
419
                                        warning(LOAD, String("Unhandled character content in tag '") + current_tag + "': " + trimmed_transcoded_chars);
 
420
                                }
 
421
                        }
 
422
                }
 
423
 
 
424
                template <typename MapType>
 
425
                void MzDataHandler<MapType>::startElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname, const xercesc::Attributes& attributes)
 
426
                {
 
427
                        static const XMLCh* s_name = xercesc::XMLString::transcode("name");
 
428
                        static const XMLCh* s_accession = xercesc::XMLString::transcode("accession");
 
429
                        static const XMLCh* s_value = xercesc::XMLString::transcode("value");
 
430
                        static const XMLCh* s_id = xercesc::XMLString::transcode("id");
 
431
                        static const XMLCh* s_count = xercesc::XMLString::transcode("count");
 
432
                        static const XMLCh* s_spectrumtype = xercesc::XMLString::transcode("spectrumType");
 
433
                        static const XMLCh* s_methodofcombination = xercesc::XMLString::transcode("methodOfCombination");
 
434
                        static const XMLCh* s_acqnumber = xercesc::XMLString::transcode("acqNumber");
 
435
                        static const XMLCh* s_mslevel = xercesc::XMLString::transcode("msLevel");
 
436
                        static const XMLCh* s_mzrangestart = xercesc::XMLString::transcode("mzRangeStart");
 
437
                        static const XMLCh* s_mzrangestop = xercesc::XMLString::transcode("mzRangeStop");
 
438
                        static const XMLCh* s_supdataarrayref = xercesc::XMLString::transcode("supDataArrayRef");
 
439
                        static const XMLCh* s_precision = xercesc::XMLString::transcode("precision");
 
440
                        static const XMLCh* s_endian = xercesc::XMLString::transcode("endian");
 
441
                        static const XMLCh* s_length = xercesc::XMLString::transcode("length");
 
442
                        static const XMLCh* s_comment = xercesc::XMLString::transcode("comment");
 
443
                        static const XMLCh* s_accessionnumber = xercesc::XMLString::transcode("accessionNumber");
 
444
 
 
445
                        String tag = sm_.convert(qname);
 
446
                        open_tags_.push_back(tag);
 
447
                        //std::cout << "Start: '" << tag << "'" << std::endl;
 
448
                        
 
449
                        //determine the parent tag
 
450
                        String parent_tag;
 
451
                        if (open_tags_.size()>1) parent_tag = *(open_tags_.end()-2);
 
452
                                                        
 
453
                        //do nothing until a new spectrum is reached
 
454
                        if (tag!="spectrum" && skip_spectrum_) return;
 
455
 
 
456
 
 
457
                        // Do something depending on the tag
 
458
                        if (tag=="sourceFile")
 
459
                        {
 
460
                                exp_->getSourceFiles().push_back(SourceFile());
 
461
                        }
 
462
                        if (tag=="contact")
 
463
                        {
 
464
                                exp_->getContacts().resize(exp_->getContacts().size()+1);
 
465
                        }
 
466
                        else if (tag=="source")
 
467
                        {
 
468
                                exp_->getInstrument().getIonSources().resize(1);
 
469
                        }
 
470
                        else if (tag=="detector")
 
471
                        {
 
472
                                exp_->getInstrument().getIonDetectors().resize(1);
 
473
                        }
 
474
                        else if (tag=="analyzer")
 
475
                        {
 
476
                                exp_->getInstrument().getMassAnalyzers().resize(exp_->getInstrument().getMassAnalyzers().size()+1);
 
477
                        }
 
478
                        else if (tag=="software")
 
479
                        {
 
480
                                data_processing_ = DataProcessing();
 
481
                                if (attributes.getIndex(sm_.convert("completionTime"))!=-1)
 
482
                                {
 
483
                                        data_processing_.setCompletionTime( asDateTime_(sm_.convert(attributes.getValue(sm_.convert("completionTime")))) );
 
484
                                }
 
485
                        }
 
486
                        else if (tag=="precursor")
 
487
                        {
 
488
                                spec_.getPrecursors().push_back(Precursor());
 
489
                        }
 
490
                        else if (tag=="cvParam")
 
491
                        {
 
492
                                String accession = attributeAsString_(attributes, s_accession);
 
493
                                String value = "";
 
494
                                optionalAttributeAsString_(value, attributes, s_value);
 
495
                                cvParam_(accession, value);
 
496
                        }
 
497
                        else if (tag=="supDataDesc")
 
498
                        {
 
499
                                String comment;
 
500
                                if (optionalAttributeAsString_(comment, attributes, s_comment))
 
501
                                {
 
502
                                        meta_id_descs_.back().second.setMetaValue("comment",comment);
 
503
                                }
 
504
                        }
 
505
                        else if (tag=="userParam")
 
506
                        {
 
507
                                String name = attributeAsString_(attributes, s_name);
 
508
                                String value = "";
 
509
                                optionalAttributeAsString_(value, attributes, s_value);
 
510
                                
 
511
                                if(parent_tag=="spectrumInstrument")
 
512
                                {
 
513
                                        spec_.getInstrumentSettings().setMetaValue(name, value);
 
514
                                }
 
515
                                else if(parent_tag=="acquisition")
 
516
                                {
 
517
                                        spec_.getAcquisitionInfo().back().setMetaValue(name, value);
 
518
                                }
 
519
                                else if (parent_tag=="ionSelection")
 
520
                                {
 
521
                                        spec_.getPrecursors().back().setMetaValue(name, value);
 
522
                                }
 
523
                                else if (parent_tag=="activation")
 
524
                                {
 
525
                                        spec_.getPrecursors().back().setMetaValue(name, value);
 
526
                                }
 
527
                                else if (parent_tag=="supDataDesc")
 
528
                                {
 
529
                                        meta_id_descs_.back().second.setMetaValue(name, value);
 
530
                                }
 
531
                                else if (parent_tag=="detector")
 
532
                                {
 
533
                                        exp_->getInstrument().getIonDetectors().back().setMetaValue(name,value);
 
534
                                }
 
535
                                else if (parent_tag=="source")
 
536
                                {
 
537
                                        exp_->getInstrument().getIonSources().back().setMetaValue(name,value);
 
538
                                }
 
539
                                else if (parent_tag=="sampleDescription")
 
540
                                {
 
541
                                        exp_->getSample().setMetaValue(name,value);
 
542
                                }
 
543
                                else if (parent_tag=="analyzer")
 
544
                                {
 
545
                                        exp_->getInstrument().getMassAnalyzers().back().setMetaValue(name,value);
 
546
                                }
 
547
                                else if (parent_tag=="additional")
 
548
                                {
 
549
                                        exp_->getInstrument().setMetaValue(name,value);
 
550
                                }
 
551
                                else if (parent_tag=="processingMethod")
 
552
                                {
 
553
                                        data_processing_.setMetaValue(name,value);                      
 
554
                                }
 
555
                                else
 
556
                                {
 
557
                                        warning(LOAD, "Invalid userParam: name=\"" + name + ", value=\"" + value + "\"");
 
558
                                }
 
559
                        }
 
560
                        else if (tag=="supDataArrayBinary")
 
561
                        {
 
562
                                
 
563
                                //create FloatDataArray
 
564
                                typename MapType::SpectrumType::FloatDataArray mda;
 
565
                                //Assign the right MetaInfoDescription ("supDesc" tag)
 
566
                                String id = attributeAsString_(attributes, s_id);
 
567
                                for (Size i=0;i<meta_id_descs_.size(); ++i)
 
568
                                {
 
569
                                        if (meta_id_descs_[i].first==id)
 
570
                                        {
 
571
                                                mda.MetaInfoDescription::operator=(meta_id_descs_[i].second);
 
572
                                                break;
 
573
                                        }
 
574
                                }
 
575
                                //append FloatDataArray
 
576
                                spec_.getFloatDataArrays().push_back(mda);
 
577
                        }
 
578
                        else if (tag=="spectrum")
 
579
                        {
 
580
                                spec_ = SpectrumType();
 
581
                                spec_.setNativeID(String("spectrum=") + attributeAsString_(attributes, s_id));
 
582
                                spec_.getDataProcessing().push_back(data_processing_);
 
583
                        }
 
584
                        else if (tag=="spectrumList")
 
585
                        {
 
586
                                if (options_.getMetadataOnly()) throw EndParsingSoftly(__FILE__,__LINE__,__PRETTY_FUNCTION__);
 
587
                        //std::cout << Date::now() << " Reserving space for spectra" << std::endl;
 
588
                        UInt count = attributeAsInt_(attributes, s_count);
 
589
                        exp_->reserve(count);
 
590
                        logger_.startProgress(0,count,"loading mzData file");
 
591
                        //std::cout << Date::now() << " done" << std::endl;
 
592
                        }
 
593
                        else if (tag=="mzData")
 
594
                        {
 
595
                                //handle file id
 
596
                                exp_->setIdentifier(attributeAsString_(attributes, s_accessionnumber));
 
597
                        }
 
598
                        else if (tag=="acqSpecification")
 
599
                        {
 
600
                                String tmp_type = attributeAsString_(attributes, s_spectrumtype);
 
601
                                if  (tmp_type == "discrete")
 
602
                                {
 
603
                                        spec_.setType(SpectrumSettings::PEAKS);
 
604
                                }
 
605
                                else if (tmp_type == "continuous")
 
606
                                {
 
607
                                        spec_.setType(SpectrumSettings::RAWDATA);
 
608
                                }
 
609
                                else
 
610
                                {
 
611
                                        spec_.setType(SpectrumSettings::UNKNOWN);
 
612
                                        warning(LOAD, String("Invalid spectrum type '") + tmp_type + "'.");
 
613
                                }
 
614
                                
 
615
                                spec_.getAcquisitionInfo().setMethodOfCombination(attributeAsString_(attributes, s_methodofcombination));
 
616
                        }
 
617
                        else if (tag=="acquisition")
 
618
                        {
 
619
                                spec_.getAcquisitionInfo().insert(spec_.getAcquisitionInfo().end(), Acquisition());
 
620
                                spec_.getAcquisitionInfo().back().setIdentifier(attributeAsString_(attributes, s_acqnumber));
 
621
                        }
 
622
                        else if (tag=="spectrumInstrument" || tag=="acqInstrument")
 
623
                        {
 
624
                                spec_.setMSLevel(attributeAsInt_(attributes, s_mslevel));
 
625
                                ScanWindow window;
 
626
                                optionalAttributeAsDouble_(window.begin, attributes, s_mzrangestart);
 
627
                                optionalAttributeAsDouble_(window.end, attributes, s_mzrangestop);
 
628
                                if (window.begin!=0.0 || window.end!=0.0)
 
629
                                {
 
630
                                        spec_.getInstrumentSettings().getScanWindows().push_back(window);
 
631
                                }
 
632
                                
 
633
                                if (options_.hasMSLevels() && !options_.containsMSLevel(spec_.getMSLevel()))
 
634
                                {
 
635
                                        skip_spectrum_ = true;
 
636
                                }
 
637
                        }
 
638
                        else if (tag=="supDesc")
 
639
                        {
 
640
                                meta_id_descs_.push_back(std::make_pair(attributeAsString_(attributes, s_supdataarrayref),MetaInfoDescription()));
 
641
                        }
 
642
                        else if (tag=="data")
 
643
                        {
 
644
                                // store precision for later
 
645
                                precisions_.push_back(attributeAsString_(attributes, s_precision));
 
646
                                endians_.push_back(attributeAsString_(attributes, s_endian));
 
647
 
 
648
                                //reserve enough space in spectrum
 
649
                                if (parent_tag=="mzArrayBinary")
 
650
                                {
 
651
                                        peak_count_ = attributeAsInt_(attributes, s_length);
 
652
                                        spec_.reserve(peak_count_);
 
653
                                }                       
 
654
                        }
 
655
                        else if (tag=="mzArrayBinary")
 
656
                        {
 
657
                                data_to_decode_.resize(data_to_decode_.size()+1);
 
658
                        }
 
659
                        else if (tag=="intenArrayBinary")
 
660
                        {
 
661
                                        data_to_decode_.resize(data_to_decode_.size()+1);
 
662
                        }
 
663
                        else if (tag=="arrayName" && parent_tag=="supDataArrayBinary")
 
664
                        {
 
665
                                        // Note: name is set in closing tag as it is CDATA
 
666
                                        data_to_decode_.resize(data_to_decode_.size()+1);
 
667
                        }
 
668
                        //std::cout << "end startelement" << std::endl;
 
669
                }
 
670
 
 
671
 
 
672
                template <typename MapType>
 
673
                void MzDataHandler<MapType>::endElement(const XMLCh* const /*uri*/, const XMLCh* const /*local_name*/, const XMLCh* const qname)
 
674
                {
 
675
                        static UInt scan_count = 0;
 
676
                        
 
677
                        static const XMLCh* s_spectrum = xercesc::XMLString::transcode("spectrum");
 
678
                        static const XMLCh* s_mzdata = xercesc::XMLString::transcode("mzData");
 
679
                        
 
680
                        open_tags_.pop_back();                  
 
681
                        //std::cout << "End: '" << sm_.convert(qname) << "'" << std::endl;
 
682
                        
 
683
                        if(equal_(qname,s_spectrum))
 
684
                        {
 
685
                                if (!skip_spectrum_)
 
686
                                {
 
687
                                        fillData_();
 
688
                                        exp_->push_back(spec_);
 
689
                                }
 
690
                                skip_spectrum_ = false;
 
691
                                logger_.setProgress(++scan_count);
 
692
                                decoded_list_.clear();
 
693
                                decoded_double_list_.clear();
 
694
                                data_to_decode_.clear();
 
695
                                precisions_.clear();
 
696
                                endians_.clear();
 
697
                                meta_id_descs_.clear();
 
698
                        }
 
699
                        else if(equal_(qname,s_mzdata))
 
700
                        {
 
701
                                logger_.endProgress();
 
702
                                scan_count = 0;
 
703
                        }
 
704
 
 
705
                        sm_.clear();
 
706
                }
 
707
 
 
708
                template <typename MapType>
 
709
                void MzDataHandler<MapType>::fillData_()
 
710
                {
 
711
                        std::vector<Real> decoded;
 
712
                        std::vector<DoubleReal> decoded_double;
 
713
                        
 
714
                        // data_to_decode is an encoded spectrum, represented as
 
715
                        // vector of base64-encoded strings:
 
716
                        // Each string represents one property (e.g. mzData) and decodes
 
717
                        // to a vector of property values - one value for every peak in the spectrum.
 
718
                        for (Size i=0; i<data_to_decode_.size(); ++i)
 
719
                        {
 
720
                                //remove whitespaces from binary data
 
721
                                //this should not be necessary, but linebreaks inside the base64 data are unfortunately no exception
 
722
                                data_to_decode_[i].removeWhitespaces();
 
723
                                
 
724
                                if (precisions_[i]=="64")       // precision 64 Bit
 
725
                                {
 
726
                                        if (endians_[i]=="big")
 
727
                                        {
 
728
                                                //std::cout << "nr. " << i << ": decoding as high-precision big endian" << std::endl;
 
729
                                                decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_BIGENDIAN, decoded_double);
 
730
                                        }
 
731
                                        else
 
732
                                        {
 
733
                                                //std::cout << "nr. " << i << ": decoding as high-precision little endian" << std::endl;
 
734
                                                decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_LITTLEENDIAN, decoded_double);
 
735
                                        }
 
736
                                        // push_back the decoded double data - and an empty one into
 
737
                                        // the dingle-precision vector, so that we don't mess up the index
 
738
                                        //std::cout << "list size: " << decoded_double.size() << std::endl;
 
739
                                        decoded_double_list_.push_back(decoded_double);
 
740
                                        decoded_list_.push_back(std::vector<float>());
 
741
                                }
 
742
                                else
 
743
                                {                                                                                       // precision 32 Bit
 
744
                                        if (endians_[i]=="big")
 
745
                                        {
 
746
                                                //std::cout << "nr. " << i << ": decoding as low-precision big endian" << std::endl;
 
747
                                                decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_BIGENDIAN, decoded);
 
748
                                        }
 
749
                                        else
 
750
                                        {
 
751
                                                //std::cout << "nr. " << i << ": decoding as low-precision little endian" << std::endl;
 
752
                                                decoder_.decode(data_to_decode_[i], Base64::BYTEORDER_LITTLEENDIAN, decoded);
 
753
                                        }
 
754
                                        //std::cout << "list size: " << decoded.size() << std::endl;
 
755
                                        decoded_list_.push_back(decoded);
 
756
                                        decoded_double_list_.push_back(std::vector<double>());
 
757
                                }
 
758
                        }
 
759
 
 
760
                        // this works only if MapType::PeakType is a Peak1D or derived from it
 
761
                        {
 
762
                                //store what precision is used for intensity and m/z
 
763
                                bool mz_precision_64 = true;
 
764
                                if (precisions_[0]=="32")
 
765
                                {
 
766
                                        mz_precision_64 = false;
 
767
                                }
 
768
                                bool int_precision_64 = true;
 
769
                                if (precisions_[1]=="32")
 
770
                                {
 
771
                                        int_precision_64 = false;
 
772
                                }
 
773
                                
 
774
                                //reserve space for meta data arrays (peak count)
 
775
                                for (Size i=0;i<spec_.getFloatDataArrays().size();++i)
 
776
                                {
 
777
                                        spec_.getFloatDataArrays()[i].reserve(peak_count_);
 
778
                                }
 
779
                                
 
780
                                //push_back the peaks into the container                                
 
781
                                for (Size n = 0 ; n < peak_count_ ; ++n)
 
782
                                {
 
783
                                        DoubleReal mz = mz_precision_64 ? decoded_double_list_[0][n] : decoded_list_[0][n];
 
784
                                        DoubleReal intensity = int_precision_64 ? decoded_double_list_[1][n] : decoded_list_[1][n];
 
785
                                        if ((!options_.hasMZRange() || options_.getMZRange().encloses(DPosition<1>(mz)))
 
786
                                         && (!options_.hasIntensityRange() || options_.getIntensityRange().encloses(DPosition<1>(intensity))))
 
787
                                        {
 
788
                                                PeakType tmp;
 
789
                                                tmp.setIntensity(intensity);
 
790
                                                tmp.setMZ(mz);
 
791
                                                spec_.push_back(tmp);
 
792
                                                //load data from meta data arrays
 
793
                                                for (Size i=0;i<spec_.getFloatDataArrays().size();++i)
 
794
                                                {
 
795
                                                        spec_.getFloatDataArrays()[i].push_back(precisions_[2+i]=="64" ? decoded_double_list_[2+i][n] : decoded_list_[2+i][n]);
 
796
                                                }
 
797
                                        }
 
798
                                }
 
799
                        }
 
800
                }
 
801
 
 
802
                template <typename MapType>
 
803
                void MzDataHandler<MapType>::writeTo(std::ostream& os)
 
804
                {
 
805
                        logger_.startProgress(0,cexp_->size(),"storing mzData file");
 
806
                        
 
807
                        os << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
 
808
                                 << "<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";
 
809
                        
 
810
                        //---------------------------------------------------------------------------------------------------
 
811
                        //DESCRIPTION
 
812
                        const Sample& sm = cexp_->getSample();
 
813
                        os << "\t<description>\n"
 
814
                                 << "\t\t<admin>\n"
 
815
                                 << "\t\t\t<sampleName>"
 
816
                                 << sm.getName()
 
817
                                 << "</sampleName>\n";
 
818
 
 
819
                        if( sm.getNumber()!="" || sm.getState() || sm.getMass() || sm.getVolume() || sm.getConcentration()      || !sm.isMetaEmpty())
 
820
                        {
 
821
                                os << "\t\t\t<sampleDescription>\n";
 
822
                                writeCVS_(os, sm.getNumber(), "1000001", "SampleNumber");
 
823
                                writeCVS_(os, sm.getState(), 0, "1000003", "SampleState");
 
824
                                writeCVS_(os, sm.getMass(), "1000004", "SampleMass");
 
825
                                writeCVS_(os, sm.getVolume(), "1000005", "SampleVolume");
 
826
                                writeCVS_(os, sm.getConcentration(), "1000006", "SampleConcentration");
 
827
                                writeUserParam_(os, cexp_->getSample());
 
828
                                os << "\t\t\t</sampleDescription>\n";
 
829
                        }
 
830
 
 
831
                        if (cexp_->getSourceFiles().size()>=1)
 
832
                        {
 
833
                                os << "\t\t\t<sourceFile>\n"
 
834
                                         << "\t\t\t\t<nameOfFile>" << cexp_->getSourceFiles()[0].getNameOfFile() << "</nameOfFile>\n"
 
835
                                         << "\t\t\t\t<pathToFile>" << cexp_->getSourceFiles()[0].getPathToFile() << "</pathToFile>\n";
 
836
                                if (cexp_->getSourceFiles()[0].getFileType()!="")
 
837
                                        os << "\t\t\t\t<fileType>" << cexp_->getSourceFiles()[0].getFileType() << "</fileType>\n";
 
838
                                os << "\t\t\t</sourceFile>\n";
 
839
                        }
 
840
                        if (cexp_->getSourceFiles().size()>1)
 
841
                        {
 
842
                                warning(STORE, "The MzData format can store only one source file. Only the first one is stored!");
 
843
                        }
 
844
 
 
845
                        for (Size i=0; i < cexp_->getContacts().size(); ++i)
 
846
                        {
 
847
                                os << "\t\t\t<contact>\n"
 
848
                                         << "\t\t\t\t<name>" << cexp_->getContacts()[i].getFirstName() << " " << cexp_->getContacts()[i].getLastName() << "</name>\n"
 
849
                                         << "\t\t\t\t<institution>" << cexp_->getContacts()[i].getInstitution() << "</institution>\n";
 
850
                                if (cexp_->getContacts()[i].getContactInfo()!="")
 
851
                                        os << "\t\t\t\t<contactInfo>" << cexp_->getContacts()[i].getContactInfo() << "</contactInfo>\n";
 
852
                                os << "\t\t\t</contact>\n";
 
853
                        }
 
854
                        //no contacts given => add empty entry as there must be a contact entry
 
855
                        if (cexp_->getContacts().empty())
 
856
                        {
 
857
                                os << "\t\t\t<contact>\n"
 
858
                                         << "\t\t\t\t<name></name>\n"
 
859
                                         << "\t\t\t\t<institution></institution>\n";
 
860
                                os << "\t\t\t</contact>\n";
 
861
                        }
 
862
                        
 
863
                        os << "\t\t</admin>\n";
 
864
                        const Instrument& inst = cexp_->getInstrument();
 
865
                        os << "\t\t<instrument>\n"
 
866
                                 << "\t\t\t<instrumentName>" << inst.getName() << "</instrumentName>\n"
 
867
                                 << "\t\t\t<source>\n";
 
868
                        if (inst.getIonSources().size()>=1)
 
869
                        {
 
870
                                writeCVS_(os, inst.getIonSources()[0].getInletType(),11, "1000007", "InletType");
 
871
                                writeCVS_(os, inst.getIonSources()[0].getIonizationMethod(), 10, "1000008","IonizationType");
 
872
                                writeCVS_(os, inst.getIonSources()[0].getPolarity(), 1, "1000009", "IonizationMode");
 
873
                                writeUserParam_(os, inst.getIonSources()[0]);
 
874
                        }
 
875
                        if (inst.getIonSources().size()>1)
 
876
                        {
 
877
                                warning(STORE, "The MzData format can store only one ion source. Only the first one is stored!");
 
878
                        }
 
879
                        os << "\t\t\t</source>\n";
 
880
                                                
 
881
                        //no analyzer given => add empty entry as there must be one entry
 
882
                        if (inst.getMassAnalyzers().empty())
 
883
                        {
 
884
                                os << "\t\t\t<analyzerList count=\"1\">\n"
 
885
                                   << "\t\t\t\t<analyzer>\n"
 
886
                                   << "\t\t\t\t</analyzer>\n";
 
887
                        }
 
888
                        else
 
889
                        {
 
890
                                os << "\t\t\t<analyzerList count=\"" << inst.getMassAnalyzers().size() << "\">\n";
 
891
                                for (Size i=0; i<inst.getMassAnalyzers().size(); ++i)
 
892
                                {
 
893
                                        os << "\t\t\t\t<analyzer>\n";
 
894
                                        const MassAnalyzer& ana = inst.getMassAnalyzers()[i];
 
895
                                        writeCVS_(os, ana.getType(), 14, "1000010", "AnalyzerType",5);
 
896
                                        writeCVS_(os, ana.getResolution(), "1000011", "MassResolution",5);
 
897
                                        writeCVS_(os, ana.getResolutionMethod(), 2,"1000012", "ResolutionMethod",5);
 
898
                                        writeCVS_(os, ana.getResolutionType(), 3, "1000013", "ResolutionType",5);
 
899
                                        writeCVS_(os, ana.getAccuracy(), "1000014", "Accuracy",5);
 
900
                                        writeCVS_(os, ana.getScanRate(), "1000015", "ScanRate",5);
 
901
                                        writeCVS_(os, ana.getScanTime(), "1000016", "ScanTime",5);
 
902
                                        writeCVS_(os, ana.getScanDirection(), 5,        "1000018", "ScanDirection",5);
 
903
                                        writeCVS_(os, ana.getScanLaw(), 6, "1000019", "ScanLaw",5);
 
904
                                        writeCVS_(os, ana.getReflectronState(), 8, "1000021", "ReflectronState",5);
 
905
                                        writeCVS_(os, ana.getTOFTotalPathLength(), "1000022", "TOFTotalPathLength",5);
 
906
                                        writeCVS_(os, ana.getIsolationWidth(), "1000023", "IsolationWidth",5);
 
907
                                        writeCVS_(os, ana.getFinalMSExponent(), "1000024", "FinalMSExponent",5);
 
908
                                        writeCVS_(os, ana.getMagneticFieldStrength(), "1000025", "MagneticFieldStrength",5);
 
909
                                        writeUserParam_(os, ana, 5);
 
910
                                        os << "\t\t\t\t</analyzer>\n";
 
911
                                }
 
912
                        }
 
913
                        os << "\t\t\t</analyzerList>\n";
 
914
                        
 
915
                        os << "\t\t\t<detector>\n";
 
916
                        if (inst.getIonDetectors().size()>=1)
 
917
                        {
 
918
                                writeCVS_(os, inst.getIonDetectors()[0].getType(), 13, "1000026", "DetectorType");
 
919
                                writeCVS_(os, inst.getIonDetectors()[0].getAcquisitionMode(), 9, "1000027", "DetectorAcquisitionMode");
 
920
                                writeCVS_(os, inst.getIonDetectors()[0].getResolution(), "1000028", "DetectorResolution");
 
921
                                writeCVS_(os, inst.getIonDetectors()[0].getADCSamplingFrequency(), "1000029", "SamplingFrequency");
 
922
                                writeUserParam_(os, inst.getIonDetectors()[0]);
 
923
                        }
 
924
                        if (inst.getIonDetectors().size()>1)
 
925
                        {
 
926
                                warning(STORE, "The MzData format can store only one ion detector. Only the first one is stored!");
 
927
                        }
 
928
                        os << "\t\t\t</detector>\n";
 
929
                        if (inst.getVendor()!="" || inst.getModel()!="" || inst.getCustomizations()!="")
 
930
                        {
 
931
                                os << "\t\t\t<additional>\n";
 
932
                                writeCVS_(os, inst.getVendor(), "1000030", "Vendor");
 
933
                                writeCVS_(os, inst.getModel(), "1000031", "Model");
 
934
                                writeCVS_(os, inst.getCustomizations(), "1000032", "Customization");
 
935
                                writeUserParam_(os, inst);
 
936
                                os << "\t\t\t</additional>\n";
 
937
                        }
 
938
                        os << "\t\t</instrument>\n";
 
939
                        
 
940
                        //the data processing information of the first spectrum is used for the whole file
 
941
                        if (cexp_->size()==0 || (*cexp_)[0].getDataProcessing().empty())
 
942
                        {
 
943
                                os << "\t\t<dataProcessing>\n"
 
944
                                         << "\t\t\t<software>\n"
 
945
                                         << "\t\t\t\t<name></name>\n"
 
946
                                         << "\t\t\t\t<version></version>\n"
 
947
                                         << "\t\t\t</software>\n"
 
948
                                         << "\t\t</dataProcessing>\n";
 
949
                        }
 
950
                        else
 
951
                        {
 
952
                                const DataProcessing& data_processing = (*cexp_)[0].getDataProcessing()[0];
 
953
                                os << "\t\t<dataProcessing>\n"
 
954
                                         << "\t\t\t<software";
 
955
                                if (data_processing.getCompletionTime()!=DateTime())
 
956
                                {
 
957
                                        os << " completionTime=\"" << data_processing.getCompletionTime().get().substitute(' ','T') << "\"";
 
958
                                }
 
959
                                os << ">\n"
 
960
                                         << "\t\t\t\t<name>" << data_processing.getSoftware().getName() << "</name>\n"
 
961
                                         << "\t\t\t\t<version>" << data_processing.getSoftware().getVersion() << "</version>\n";
 
962
                                os << "\t\t\t</software>\n"
 
963
                                         << "\t\t\t<processingMethod>\n";
 
964
                                if(data_processing.getProcessingActions().count(DataProcessing::DEISOTOPING)==1)
 
965
                                {
 
966
                                        os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"Deisotoping\" accession=\"PSI:1000033\" />\n";
 
967
                                }
 
968
                                if(data_processing.getProcessingActions().count(DataProcessing::CHARGE_DECONVOLUTION)==1)
 
969
                                {
 
970
                                        os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"ChargeDeconvolution\" accession=\"PSI:1000034\" />\n";
 
971
                                }
 
972
                                if(data_processing.getProcessingActions().count(DataProcessing::PEAK_PICKING)==1)
 
973
                                {
 
974
                                        os << "\t\t\t\t<cvParam cvLabel=\"psi\" name=\"Centroid Mass Spectrum\" accession=\"PSI:1000127\"/>\n";
 
975
                                }
 
976
                                writeUserParam_(os, data_processing);
 
977
                                os << "\t\t\t</processingMethod>\n"
 
978
                                         << "\t\t</dataProcessing>\n";
 
979
                        }
 
980
                        os << "\t</description>\n";
 
981
 
 
982
                        //---------------------------------------------------------------------------------------------------
 
983
                        //ACTUAL DATA
 
984
                        if (cexp_->size()!=0)
 
985
                        {
 
986
                                //check if the nativeID of all spectra are numbers or numbers prefixed with 'spectrum='
 
987
                                //If not we need to renumber all spectra.
 
988
                                bool all_numbers = true;
 
989
                                bool all_empty = true;
 
990
                                bool all_prefixed_numbers = true;
 
991
                                for (Size s=0; s<cexp_->size(); s++)
 
992
                                {
 
993
                                        String native_id = (*cexp_)[s].getNativeID();
 
994
                                        if (!native_id.hasPrefix("spectrum="))
 
995
                                        {
 
996
                                                all_prefixed_numbers = false;
 
997
                                        }
 
998
                                        else
 
999
                                        {
 
1000
                                                native_id = native_id.substr(9);
 
1001
                                        }
 
1002
                                        try
 
1003
                                        {
 
1004
                                                native_id.toInt();
 
1005
                                        }
 
1006
                                        catch (Exception::ConversionError&)
 
1007
                                        {
 
1008
                                                all_numbers = false;
 
1009
                                                all_prefixed_numbers = false;
 
1010
                                                if (native_id!="")
 
1011
                                                {
 
1012
                                                        all_empty = false;
 
1013
                                                }
 
1014
                                        }
 
1015
                                }
 
1016
                                //If we need to renumber and the nativeIDs were not empty, warn the user
 
1017
                                if (!all_numbers && !all_empty)
 
1018
                                {
 
1019
                                        warning(STORE, "Not all spectrum native IDs are numbers or correctly prefixed with 'spectrum='. The spectra are renumbered and the native IDs are lost!");
 
1020
                                }
 
1021
                                //Map to store the last spectrum ID for each MS level (needed to find precursor spectra)
 
1022
                                Map<Int,Size> level_id; 
 
1023
                                
 
1024
                                os << "\t<spectrumList count=\"" << cexp_->size() << "\">\n";
 
1025
                                for (Size s=0; s<cexp_->size(); ++s)
 
1026
                                {
 
1027
                                        logger_.setProgress(s);
 
1028
                                        const SpectrumType& spec = (*cexp_)[s];
 
1029
                                        
 
1030
                                        Size spectrum_id = s+1;
 
1031
                                        if (all_prefixed_numbers)
 
1032
                                        {
 
1033
                                                spectrum_id = spec.getNativeID().substr(9).toInt();
 
1034
                                        }
 
1035
                                        else if (all_numbers)
 
1036
                                        {
 
1037
                                                spectrum_id = spec.getNativeID().toInt();
 
1038
                                        }
 
1039
                                        os << "\t\t<spectrum id=\"" << spectrum_id << "\">\n"
 
1040
                                                 << "\t\t\t<spectrumDesc>\n"
 
1041
                                                 << "\t\t\t\t<spectrumSettings>\n";
 
1042
        
 
1043
                                        if (!spec.getAcquisitionInfo().empty())
 
1044
                                        {
 
1045
                                                os << "\t\t\t\t\t<acqSpecification spectrumType=\"";
 
1046
                                                if (spec.getType()==SpectrumSettings::PEAKS)
 
1047
                                                {
 
1048
                                                        os << "discrete";
 
1049
                                                }
 
1050
                                                else if (spec.getType()==SpectrumSettings::RAWDATA)
 
1051
                                                {
 
1052
                                                        os << "continuous";
 
1053
                                                }
 
1054
                                                else
 
1055
                                                {
 
1056
                                                        warning(STORE, "Spectrum type is unknown, assuming 'discrete'");
 
1057
                                                        os << "discrete";
 
1058
                                                }
 
1059
        
 
1060
                                                os << "\" methodOfCombination=\"" << spec.getAcquisitionInfo().getMethodOfCombination() << "\""
 
1061
                                                   << " count=\"" << spec.getAcquisitionInfo().size() << "\">\n";
 
1062
                                                for (Size i=0; i<spec.getAcquisitionInfo().size(); ++i)
 
1063
                                                {
 
1064
                                                        const Acquisition& ac = spec.getAcquisitionInfo()[i];
 
1065
                                                        Int acq_number = 0;
 
1066
                                                        try
 
1067
                                                        {
 
1068
                                                                if (ac.getIdentifier() != "")
 
1069
                                                                {
 
1070
                                                                        acq_number =  ac.getIdentifier().toInt();
 
1071
                                                                }
 
1072
                                                        }
 
1073
                                                        catch(...)
 
1074
                                                        {
 
1075
                                                                warning(STORE, String("Could not convert acquisition identifier '") + ac.getIdentifier() + "' to an integer. Using '0' instead!");
 
1076
                                                                acq_number = 0;
 
1077
                                                        }
 
1078
                                                        os << "\t\t\t\t\t\t<acquisition acqNumber=\"" << acq_number << "\">\n";
 
1079
                                                        writeUserParam_(os, ac, 7);
 
1080
                                                        os << "\t\t\t\t\t\t</acquisition>\n";
 
1081
                                                }
 
1082
                                                os << "\t\t\t\t\t</acqSpecification>\n";
 
1083
                                        }
 
1084
        
 
1085
                                        const InstrumentSettings& iset = spec.getInstrumentSettings();
 
1086
                                        os << "\t\t\t\t\t<spectrumInstrument msLevel=\"" << spec.getMSLevel() << "\"";
 
1087
                                        level_id[spec.getMSLevel()] = spectrum_id;
 
1088
                                        
 
1089
          if ( !iset.getScanWindows().empty() )
 
1090
                                        {
 
1091
                                                os << " mzRangeStart=\"" << iset.getScanWindows()[0].begin << "\" mzRangeStop=\"" << iset.getScanWindows()[0].end << "\"";
 
1092
                                        }
 
1093
          if ( iset.getScanWindows().size() > 1 )
 
1094
                                        {
 
1095
                                                warning(STORE, "The MzData format can store only one scan window for each scan. Only the first one is stored!");
 
1096
                                        }
 
1097
                                        os << ">\n";
 
1098
        
 
1099
                                        //scan mode
 
1100
                                        switch(iset.getScanMode())
 
1101
                                        {
 
1102
                                                case InstrumentSettings::UNKNOWN:
 
1103
                                                        //do nothing here
 
1104
                                                        break;
 
1105
                                                case InstrumentSettings::MASSSPECTRUM:
 
1106
                                                        if (iset.getZoomScan())
 
1107
                                                        {
 
1108
                                                                os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"Zoom\"/>\n";
 
1109
                                                        }
 
1110
                                                        else
 
1111
                                                        {
 
1112
                                                                os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"MassScan\"/>\n";
 
1113
                                                        }
 
1114
                                                        break;
 
1115
                                                case InstrumentSettings::SIM:
 
1116
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"SelectedIonDetection\"/>\n";
 
1117
                                                        break;
 
1118
                                                case InstrumentSettings::SRM:
 
1119
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"SelectedReactionMonitoring\"/>\n";
 
1120
                                                        break;
 
1121
                                                case InstrumentSettings::CRM:
 
1122
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConsecutiveReactionMonitoring\"/>\n";
 
1123
                                                        break;
 
1124
                                                case InstrumentSettings::CNG:
 
1125
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConstantNeutralGainScan\"/>\n";
 
1126
                                                        break;
 
1127
                                                case InstrumentSettings::CNL:
 
1128
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"ConstantNeutralLossScan\"/>\n";
 
1129
                                                        break;
 
1130
                                                case InstrumentSettings::PRECURSOR:
 
1131
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"PrecursorIonScan\"/>\n";
 
1132
                                                        break;
 
1133
                                                case InstrumentSettings::ABSORBTION:
 
1134
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"PhotodiodeArrayDetector\"/>\n";
 
1135
                                                        break;
 
1136
                                                case InstrumentSettings::EMC:
 
1137
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"EnhancedMultiplyChargedScan\"/>\n";
 
1138
                                                        break;
 
1139
                                                case InstrumentSettings::TDF:
 
1140
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"TimeDelayedFragmentationScan\"/>\n";
 
1141
                                                        break;
 
1142
                                                default:
 
1143
                                                        os << "                                         <cvParam cvLabel=\"psi\" accession=\"PSI:1000036\" name=\"ScanMode\" value=\"MassScan\"/>\n";
 
1144
                                                        warning(STORE, String("Scan mode '") + InstrumentSettings::NamesOfScanMode[iset.getScanMode()] + "' not supported by mzData. Using 'MassScan' scan mode!");
 
1145
                                        }
 
1146
                                        
 
1147
                                        //scan polarity
 
1148
                                        if (spec.getInstrumentSettings().getPolarity()==IonSource::POSITIVE)
 
1149
                                        {
 
1150
                                                os << String(6,'\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:1000037\" name=\"Polarity\" value=\"Positive\"/>\n";
 
1151
                                        }
 
1152
                                        else if (spec.getInstrumentSettings().getPolarity()==IonSource::NEGATIVE)
 
1153
                                        {
 
1154
                                                os << String(6,'\t') << "<cvParam cvLabel=\"psi\" accession=\"PSI:1000037\" name=\"Polarity\" value=\"Negative\"/>\n";
 
1155
                                        }
 
1156
                                        
 
1157
                                        //Retiontion time already in TimeInSeconds
 
1158
                                        writeCVS_(os, spec.getRT(), "1000039", "TimeInSeconds",6);
 
1159
                                        writeUserParam_(os, spec.getInstrumentSettings(), 6);
 
1160
                                        os      << "\t\t\t\t\t</spectrumInstrument>\n\t\t\t\t</spectrumSettings>\n";
 
1161
        
 
1162
                                        if (spec.getPrecursors().size()!=0)
 
1163
                                        {
 
1164
                                                Int precursor_ms_level = spec.getMSLevel()-1;
 
1165
                                                SignedSize precursor_id = -1;
 
1166
                                                if (level_id.has(precursor_ms_level))
 
1167
                                                {
 
1168
                                                        precursor_id = level_id[precursor_ms_level];
 
1169
                                                }
 
1170
                                                os << "\t\t\t\t<precursorList count=\"" << spec.getPrecursors().size() << "\">\n";
 
1171
                                                for (Size i=0; i< spec.getPrecursors().size(); ++i)
 
1172
                                                {
 
1173
                                                        const Precursor& precursor = spec.getPrecursors()[i];
 
1174
                                                        os << "\t\t\t\t\t<precursor msLevel=\"" << precursor_ms_level << "\" spectrumRef=\"" << precursor_id << "\">\n";
 
1175
                                                        os << "\t\t\t\t\t\t<ionSelection>\n";
 
1176
                                                        if (precursor != Precursor())
 
1177
                                                        {
 
1178
                                                                writeCVS_(os, precursor.getMZ(), "1000040", "MassToChargeRatio",7);
 
1179
                                                                writeCVS_(os, precursor.getCharge(), "1000041", "ChargeState",7);
 
1180
                                                                writeCVS_(os, precursor.getIntensity(), "1000042", "Intensity",7);
 
1181
                                                                os << "\t\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000043\" name=\"IntensityUnit\" value=\"NumberOfCounts\"/>\n";
 
1182
                                                                writeUserParam_(os, precursor, 7);
 
1183
                                                        }
 
1184
                                                        os << "\t\t\t\t\t\t</ionSelection>\n";
 
1185
                                                        os << "\t\t\t\t\t\t<activation>\n";
 
1186
                                                        if (precursor != Precursor())
 
1187
                                                        {
 
1188
                                                                if (precursor.getActivationMethods().size()>0)
 
1189
                                                                {
 
1190
                                                                        writeCVS_(os, *(precursor.getActivationMethods().begin()), 18, "1000044", "ActivationMethod",7);
 
1191
                                                                }
 
1192
                                                                writeCVS_(os, precursor.getActivationEnergy(), "1000045", "CollisionEnergy",7);
 
1193
                                                                os << "\t\t\t\t\t\t\t<cvParam cvLabel=\"psi\" accession=\"PSI:1000046\" name=\"EnergyUnit\" value=\"eV\"/>\n";
 
1194
                                                        }
 
1195
                                                        os << "\t\t\t\t\t\t</activation>\n";
 
1196
                                                        os << "\t\t\t\t\t</precursor>\n";
 
1197
                                                }
 
1198
                                                os << "\t\t\t\t</precursorList>\n";
 
1199
                                        }
 
1200
                                        os << "\t\t\t</spectrumDesc>\n";
 
1201
        
 
1202
                                        // write the supplementary data?
 
1203
                                        if (options_.getWriteSupplementalData())
 
1204
                                        {
 
1205
                                                //write meta data array descriptions
 
1206
                                                for (Size i=0; i<spec.getFloatDataArrays().size(); ++i)
 
1207
                                                {
 
1208
                                                        const MetaInfoDescription& desc = spec.getFloatDataArrays()[i];
 
1209
                                                        os << "\t\t\t<supDesc supDataArrayRef=\"" << (i+1) << "\">\n";
 
1210
                                                        if (!desc.isMetaEmpty())
 
1211
                                                        {
 
1212
                                                                os << "\t\t\t\t<supDataDesc>\n";
 
1213
                                                                writeUserParam_(os, desc, 5);
 
1214
                                                                os << "\t\t\t\t</supDataDesc>\n";
 
1215
                                                        }
 
1216
                                                        os << "\t\t\t</supDesc>\n";
 
1217
                                                }
 
1218
                                        }
 
1219
                                        
 
1220
                                        //write m/z and intensity arrays
 
1221
                                        data_to_encode_.clear();
 
1222
                                        for (Size i=0; i<spec.size(); i++)
 
1223
                                        {
 
1224
                                                data_to_encode_.push_back(spec[i].getPosition()[0]);
 
1225
                                        }
 
1226
                                        
 
1227
                                        writeBinary_(os,spec.size(),"mzArrayBinary");
 
1228
        
 
1229
                                        // intensity
 
1230
                                        data_to_encode_.clear();
 
1231
                                        for (Size i=0; i<spec.size(); i++)
 
1232
                                        {
 
1233
                                                data_to_encode_.push_back(spec[i].getIntensity());
 
1234
                                        }
 
1235
                                        
 
1236
                                        writeBinary_(os,spec.size(),"intenArrayBinary");
 
1237
        
 
1238
                                        // write the supplementary data?
 
1239
                                        if (options_.getWriteSupplementalData())
 
1240
                                        {
 
1241
                                                //write supplemental data arrays
 
1242
                                                for (Size i=0; i<spec.getFloatDataArrays().size(); ++i)
 
1243
                                                {
 
1244
                                                        const typename MapType::SpectrumType::FloatDataArray& mda = spec.getFloatDataArrays()[i];
 
1245
                                                        //check if spectrum and meta data array have the same length
 
1246
                                                        if (mda.size()!=spec.size())
 
1247
                                                        {
 
1248
                                                                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() +" .");
 
1249
                                                        }
 
1250
                                                        //encode meta data array
 
1251
                                                        data_to_encode_.clear();
 
1252
                                                        for (Size j=0; j<mda.size(); j++)
 
1253
                                                        {
 
1254
                                                                data_to_encode_.push_back (mda[j]);
 
1255
                                                        }
 
1256
                                                        //write meta data array
 
1257
                                                        writeBinary_(os,mda.size(),"supDataArrayBinary",mda.getName(),i+1);
 
1258
                                                }
 
1259
                                        }
 
1260
        
 
1261
                                        os <<"\t\t</spectrum>\n";
 
1262
                                }
 
1263
                        }
 
1264
                        else
 
1265
                        {
 
1266
                                os << "\t<spectrumList count=\"1\">\n";
 
1267
                                os <<"\t\t<spectrum id=\"1\">\n";
 
1268
                                os <<"\t\t\t<spectrumDesc>\n";
 
1269
                                os <<"\t\t\t\t<spectrumSettings>\n";
 
1270
                                os <<"\t\t\t\t\t<spectrumInstrument msLevel=\"1\"/>\n";
 
1271
                                os <<"\t\t\t\t</spectrumSettings>\n";
 
1272
                                os <<"\t\t\t</spectrumDesc>\n";
 
1273
                                os <<"\t\t\t<mzArrayBinary>\n";
 
1274
                                os <<"\t\t\t\t<data length=\"0\" endian=\"little\" precision=\"32\"></data>\n";
 
1275
                                os <<"\t\t\t</mzArrayBinary>\n";
 
1276
                                os <<"\t\t\t<intenArrayBinary>\n";
 
1277
                                os <<"\t\t\t\t<data length=\"0\" endian=\"little\" precision=\"32\"></data>\n";
 
1278
                                os <<"\t\t\t</intenArrayBinary>\n";
 
1279
                                os <<"\t\t</spectrum>\n";
 
1280
                        }
 
1281
                        os << "\t</spectrumList>\n</mzData>\n";
 
1282
                        
 
1283
                        logger_.endProgress();
 
1284
                }
 
1285
 
 
1286
                template <typename MapType>
 
1287
                void MzDataHandler<MapType>::cvParam_(const String& accession, const String& value)
 
1288
                {
 
1289
                        String error = "";
 
1290
 
 
1291
                        //determine the parent tag
 
1292
                        String parent_tag;
 
1293
                        if (open_tags_.size()>1) parent_tag = *(open_tags_.end()-2);
 
1294
                        
 
1295
                        if(parent_tag=="spectrumInstrument")
 
1296
                        {
 
1297
                                if (accession=="PSI:1000036") //Scan Mode
 
1298
                                {
 
1299
                                        if (value=="Zoom")
 
1300
                                        {
 
1301
                                                spec_.getInstrumentSettings().setZoomScan(true);
 
1302
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
 
1303
                                        }
 
1304
                                        else if (value=="MassScan")
 
1305
                                        {
 
1306
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
 
1307
                                        }
 
1308
                                        else if (value=="SelectedIonDetection")
 
1309
                                        {
 
1310
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SIM);
 
1311
                                        }
 
1312
                                        else if (value=="SelectedReactionMonitoring")
 
1313
                                        {
 
1314
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::SRM);
 
1315
                                        }
 
1316
                                        else if (value=="ConsecutiveReactionMonitoring")
 
1317
                                        {
 
1318
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CRM);
 
1319
                                        }
 
1320
                                        else if (value=="ConstantNeutralGainScan")
 
1321
                                        {
 
1322
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNG);
 
1323
                                        }
 
1324
                                        else if (value=="ConstantNeutralLossScan")
 
1325
                                        {
 
1326
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::CNL);
 
1327
                                        }
 
1328
                                        else if (value=="ProductIonScan")
 
1329
                                        {
 
1330
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
 
1331
                                                spec_.setMSLevel(2);
 
1332
                                        }
 
1333
                                        else if (value=="PrecursorIonScan")
 
1334
                                        {
 
1335
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::PRECURSOR);
 
1336
                                        }
 
1337
                                        else if (value=="EnhancedResolutionScan")
 
1338
                                        {
 
1339
                                                spec_.getInstrumentSettings().setZoomScan(true);
 
1340
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
 
1341
                                        }
 
1342
                                        else
 
1343
                                        {
 
1344
                                                spec_.getInstrumentSettings().setScanMode(InstrumentSettings::MASSSPECTRUM);
 
1345
                                                warning(LOAD, String("Unknown scan mode '") + value + "'. Assuming full scan");
 
1346
                                        }
 
1347
                                }
 
1348
                                else if (accession=="PSI:1000038") //Time in minutes
 
1349
                                {
 
1350
                                        spec_.setRT(asDouble_(value)*60); //Minutes to seconds
 
1351
                                        if (options_.hasRTRange() && !options_.getRTRange().encloses(DPosition<1>(spec_.getRT())))
 
1352
                                        {
 
1353
                                                skip_spectrum_=true;
 
1354
                                        }
 
1355
                                }
 
1356
                                else if (accession=="PSI:1000039") //Time in seconds
 
1357
                                {
 
1358
                                        spec_.setRT(asDouble_(value));
 
1359
                                        if (options_.hasRTRange() && !options_.getRTRange().encloses(DPosition<1>(spec_.getRT())))
 
1360
                                        {
 
1361
                                                skip_spectrum_=true;
 
1362
                                        }
 
1363
                                }
 
1364
                                else if (accession=="PSI:1000037") //Polarity
 
1365
                                {
 
1366
                                        if (value=="Positive" || value=="positive" || value=="+") //be flexible here, actually only the first one is correct
 
1367
                                        {
 
1368
                                                spec_.getInstrumentSettings().setPolarity(IonSource::POSITIVE);
 
1369
                                        }
 
1370
                                        else if (value=="Negative" || value=="negative" || value=="-") //be flexible here, actually only the first one is correct
 
1371
                                        {
 
1372
                                                spec_.getInstrumentSettings().setPolarity(IonSource::NEGATIVE);
 
1373
                                        }
 
1374
                                        else
 
1375
                                        {
 
1376
                                                warning(LOAD, String("Invalid scan polarity (PSI:1000037) detected: \"") + value + "\". Valid are 'Positive' or 'Negative'.");
 
1377
                                        }
 
1378
                                }
 
1379
                                else 
 
1380
                                {
 
1381
                                error = "SpectrumDescription.SpectrumSettings.SpectrumInstrument";
 
1382
                                }
 
1383
                        }
 
1384
                        else if(parent_tag=="ionSelection")
 
1385
                        {
 
1386
                                if (accession=="PSI:1000040") //m/z
 
1387
                                {
 
1388
                                        spec_.getPrecursors().back().setMZ(asDouble_(value));                   
 
1389
                                }
 
1390
                                else if (accession=="PSI:1000041") //Charge
 
1391
                                {
 
1392
                                        if (spec_.getPrecursors().back().getCharge() != 0)
 
1393
                                        {
 
1394
                                                warning(LOAD, String("Multiple precursor charges detected, expected only one! Ignoring this charge settings! accession=\"") + accession + "\", value=\"" + value + "\"");
 
1395
                                                spec_.getPrecursors().back().setCharge(0);
 
1396
                                        }
 
1397
                                        else
 
1398
                                        {
 
1399
                                                spec_.getPrecursors().back().setCharge(asInt_(value));
 
1400
                                        }
 
1401
                                }
 
1402
                                else if (accession=="PSI:1000042") //Intensity
 
1403
                                {
 
1404
                                        spec_.getPrecursors().back().setIntensity(asDouble_(value));            
 
1405
                                }
 
1406
                                else if (accession=="PSI:1000043") //Intensity unit
 
1407
                                {
 
1408
                                        //ignored
 
1409
                                }
 
1410
                                else
 
1411
                                {
 
1412
                                        error = "PrecursorList.Precursor.IonSelection.UserParam";
 
1413
                                }
 
1414
                        }
 
1415
                        else if (parent_tag=="activation") 
 
1416
                        {
 
1417
                                if (accession=="PSI:1000044") //activationmethod
 
1418
                                {
 
1419
                                        spec_.getPrecursors().back().getActivationMethods().insert((Precursor::ActivationMethod)cvStringToEnum_(18, value,"activation method"));
 
1420
                                }
 
1421
                                else if (accession=="PSI:1000045") //Energy
 
1422
                                {
 
1423
                                        spec_.getPrecursors().back().setActivationEnergy( asDouble_(value) );
 
1424
                                }
 
1425
                                else if (accession=="PSI:1000046") //Energy unit
 
1426
                                {
 
1427
                                        //ignored - we assume electronvolt
 
1428
                                }
 
1429
                                else 
 
1430
                                {
 
1431
                                        error = "PrecursorList.Precursor.Activation.UserParam";
 
1432
                                }
 
1433
                        }
 
1434
                        else if (parent_tag=="supDataDesc") 
 
1435
                        {
 
1436
                                //no terms defined in ontology
 
1437
                                error = "supDataDesc.UserParam";
 
1438
                        }
 
1439
                        else if (parent_tag=="acquisition")
 
1440
                        {
 
1441
                                 //no terms defined in ontology
 
1442
                                 error = "spectrumDesc.spectrumSettings.acquisitionSpecification.acquisition.UserParam";
 
1443
                        }
 
1444
                        else if (parent_tag=="detector")
 
1445
                        {
 
1446
                                if (accession=="PSI:1000026")
 
1447
                                {
 
1448
                                        exp_->getInstrument().getIonDetectors().back().setType( (IonDetector::Type)cvStringToEnum_(13,value, "detector type") );
 
1449
                                }
 
1450
                                else if (accession=="PSI:1000028")
 
1451
                                {
 
1452
                                        exp_->getInstrument().getIonDetectors().back().setResolution( asDouble_(value) );
 
1453
                                }
 
1454
                                else if (accession=="PSI:1000029")
 
1455
                                {
 
1456
                                        exp_->getInstrument().getIonDetectors().back().setADCSamplingFrequency( asDouble_(value) );
 
1457
                                }
 
1458
                                else if (accession=="PSI:1000027")
 
1459
                                {
 
1460
                                        exp_->getInstrument().getIonDetectors().back().setAcquisitionMode((IonDetector::AcquisitionMode)cvStringToEnum_(9, value, "acquisition mode") );
 
1461
                                }
 
1462
                                else
 
1463
                                {
 
1464
                                        error = "Description.Instrument.Detector.UserParam";
 
1465
                                }
 
1466
                        }
 
1467
                        else if (parent_tag=="source")
 
1468
                        {
 
1469
                                if (accession=="PSI:1000008")
 
1470
                                {
 
1471
                                        exp_->getInstrument().getIonSources().back().setIonizationMethod( (IonSource::IonizationMethod)cvStringToEnum_(10, value, "ion source") );
 
1472
                                }
 
1473
                                else if (accession=="PSI:1000007")
 
1474
                                {
 
1475
                                        exp_->getInstrument().getIonSources().back().setInletType( (IonSource::InletType)cvStringToEnum_(11, value,"inlet type") );
 
1476
                                }
 
1477
                                else if (accession=="PSI:1000009")
 
1478
                                {
 
1479
                                        exp_->getInstrument().getIonSources().back().setPolarity( (IonSource::Polarity)cvStringToEnum_(1, value,"polarity") );
 
1480
                                }
 
1481
                                else 
 
1482
                                {
 
1483
                                        error = "Description.Instrument.Source.UserParam";
 
1484
                                }
 
1485
                        }
 
1486
                        else if (parent_tag=="sampleDescription")
 
1487
                        {
 
1488
                                if (accession=="PSI:1000001")
 
1489
                                {
 
1490
                                        exp_->getSample().setNumber( value );
 
1491
                                }
 
1492
                                else if (accession=="PSI:1000003")
 
1493
                                {
 
1494
                                        exp_->getSample().setState( (Sample::SampleState)cvStringToEnum_(0, value, "sample state") );
 
1495
                                }
 
1496
                                else if (accession=="PSI:1000004")
 
1497
                                {
 
1498
                                        exp_->getSample().setMass( asDouble_(value) );
 
1499
                                }
 
1500
                                else if (accession=="PSI:1000005")
 
1501
                                {
 
1502
                                        exp_->getSample().setVolume( asDouble_(value) );
 
1503
                                }
 
1504
                                else if (accession=="PSI:1000006")
 
1505
                                {
 
1506
                                        exp_->getSample().setConcentration( asDouble_(value) );
 
1507
                                }
 
1508
                                else 
 
1509
                                {
 
1510
                                        error = "Description.Admin.SampleDescription.UserParam";
 
1511
                                }
 
1512
                        }
 
1513
                        else if (parent_tag=="analyzer")
 
1514
                        {
 
1515
                                if (accession=="PSI:1000010")
 
1516
                                {
 
1517
                                        exp_->getInstrument().getMassAnalyzers().back().setType( (MassAnalyzer::AnalyzerType)cvStringToEnum_(14, value,"analyzer type"));
 
1518
                                }
 
1519
                                else if (accession=="PSI:1000011")
 
1520
                                {
 
1521
                                        exp_->getInstrument().getMassAnalyzers().back().setResolution( asDouble_(value) );
 
1522
                                }
 
1523
                                else if (accession=="PSI:1000012")
 
1524
                                {
 
1525
                                        exp_->getInstrument().getMassAnalyzers().back().setResolutionMethod( (MassAnalyzer::ResolutionMethod)cvStringToEnum_(2, value,"resolution method"));
 
1526
                                }
 
1527
                                else if (accession=="PSI:1000013")
 
1528
                                {
 
1529
                                        exp_->getInstrument().getMassAnalyzers().back().setResolutionType( (MassAnalyzer::ResolutionType)cvStringToEnum_(3, value, "resolution type"));
 
1530
                                }
 
1531
                                else if (accession=="PSI:1000014")
 
1532
                                {
 
1533
                                        exp_->getInstrument().getMassAnalyzers().back().setAccuracy( asDouble_(value) );
 
1534
                                }
 
1535
                                else if (accession=="PSI:1000015")
 
1536
                                {
 
1537
                                        exp_->getInstrument().getMassAnalyzers().back().setScanRate( asDouble_(value) );
 
1538
                                }
 
1539
                                else if (accession=="PSI:1000016")
 
1540
                                {
 
1541
                                        exp_->getInstrument().getMassAnalyzers().back().setScanTime( asDouble_(value) );
 
1542
                                }
 
1543
                                else if (accession=="PSI:1000018")
 
1544
                                {
 
1545
                                        exp_->getInstrument().getMassAnalyzers().back().setScanDirection( (MassAnalyzer::ScanDirection)cvStringToEnum_(5, value, "scan direction"));
 
1546
                                }
 
1547
                                else if (accession=="PSI:1000019")
 
1548
                                {
 
1549
                                        exp_->getInstrument().getMassAnalyzers().back().setScanLaw( (MassAnalyzer::ScanLaw)cvStringToEnum_(6, value, "scan law"));
 
1550
                                }
 
1551
                                else if (accession=="PSI:1000020")
 
1552
                                {
 
1553
                                        // ignored
 
1554
                                }
 
1555
                                else if (accession=="PSI:1000021")
 
1556
                                {
 
1557
                                        exp_->getInstrument().getMassAnalyzers().back().setReflectronState( (MassAnalyzer::ReflectronState)cvStringToEnum_(8, value, "reflectron state"));
 
1558
                                }
 
1559
                                else if (accession=="PSI:1000022")
 
1560
                                {
 
1561
                                        exp_->getInstrument().getMassAnalyzers().back().setTOFTotalPathLength( asDouble_(value) );
 
1562
                                }
 
1563
                                else if (accession=="PSI:1000023")
 
1564
                                {
 
1565
                                        exp_->getInstrument().getMassAnalyzers().back().setIsolationWidth( asDouble_(value) );
 
1566
                                }
 
1567
                                else if (accession=="PSI:1000024")
 
1568
                                {
 
1569
                                        exp_->getInstrument().getMassAnalyzers().back().setFinalMSExponent( asInt_(value) );
 
1570
                                }
 
1571
                                else if (accession=="PSI:1000025")
 
1572
                                {
 
1573
                                        exp_->getInstrument().getMassAnalyzers().back().setMagneticFieldStrength( asDouble_(value) );
 
1574
                                }
 
1575
                                else if (accession=="PSI:1000017")
 
1576
                                {
 
1577
                                        //ignored
 
1578
                                }
 
1579
                                else 
 
1580
                                {
 
1581
                                        error = "AnalyzerList.Analyzer.UserParam";
 
1582
                                }
 
1583
                        }
 
1584
                        else if (parent_tag=="additional")
 
1585
                        {
 
1586
                                if (accession=="PSI:1000030")
 
1587
                                {
 
1588
                                        exp_->getInstrument().setVendor(value);
 
1589
                                }
 
1590
                                else if (accession=="PSI:1000031")
 
1591
                                {
 
1592
                                        exp_->getInstrument().setModel(value);
 
1593
                                }
 
1594
                                else if (accession=="PSI:1000032")
 
1595
                                {
 
1596
                                        exp_->getInstrument().setCustomizations(value);
 
1597
                                }
 
1598
                                else 
 
1599
                                {
 
1600
                                        error = "Description.Instrument.Additional";
 
1601
                                }
 
1602
                        }
 
1603
                        else if (parent_tag=="processingMethod")
 
1604
                        {
 
1605
                                if (accession=="PSI:1000033")
 
1606
                                {
 
1607
                                        data_processing_.getProcessingActions().insert(DataProcessing::DEISOTOPING);
 
1608
                                }
 
1609
                                else if (accession=="PSI:1000034")
 
1610
                                {
 
1611
                                        data_processing_.getProcessingActions().insert(DataProcessing::CHARGE_DECONVOLUTION);
 
1612
                                }
 
1613
                                else if (accession=="PSI:1000127")
 
1614
                                {
 
1615
                                        data_processing_.getProcessingActions().insert(DataProcessing::PEAK_PICKING);
 
1616
                                }
 
1617
                                else if (accession=="PSI:1000035")
 
1618
                                {
 
1619
                                        //ignored
 
1620
                                }
 
1621
                                else 
 
1622
                                {
 
1623
                                        error = "DataProcessing.DataProcessing.UserParam";
 
1624
                                }
 
1625
                        }
 
1626
                        else
 
1627
                        {
 
1628
                                warning(LOAD, String("Unexpected cvParam: accession=\"") + accession + "\" value=\"" + value + "\" in tag " + parent_tag);
 
1629
                        }
 
1630
 
 
1631
                        if (error != "")
 
1632
                        {
 
1633
                                warning(LOAD, String("Invalid cvParam: accession=\"") + accession + "\" value=\"" + value + "\" in " + error);
 
1634
                        }
 
1635
                        //std::cout << "End of MzDataHander::cvParam_" << std::endl;
 
1636
                }
 
1637
                
 
1638
        } // namespace Internal
 
1639
 
 
1640
} // namespace OpenMS
 
1641
 
 
1642
#endif