Mass++ mzML IO Plugin v2.7.5
 All Classes Namespaces Files Functions Variables Enumerations
MzmlDataHandler.cpp
Go to the documentation of this file.
1 
12 #include "stdafx.h"
13 #include "MzmlDataHandler.h"
14 #include "MzmlSample.h"
15 
16 #include <zlib.h>
17 
18 
19 using namespace kome::io::mzml;
20 
21 
22 #include <crtdbg.h>
23 #ifdef _DEBUG
24  #define new new( _NORMAL_BLOCK, __FILE__, __LINE__ )
25  #define malloc( s ) _malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ )
26 #endif // _DEBUG
27 
28 
29 
30 #define SPEC_TAG_NAME "spectrum"
31 #define CHROM_TAG_NAME "chromatogram"
32 #define ARRAY_TAG_NAME "binaryDataArray"
33 #define PARAM_GROUP_TAG_NAME "referenceableParamGroupRef"
34 #define CV_TAG_NAME "cvParam"
35 #define BINARY_TAG_NAME "binary"
36 
37 #define SPEC_ID_ATTR_NAME "id"
38 #define SPEC_LENGTH_ATTR_NAME "defaultArrayLength"
39 #define CHROM_ID_ATTR_NAME "id"
40 #define CHROM_LENGTH_ATTR_NAME "defaultArrayLength"
41 #define ARRAY_LENGTH_ATTR_NAME "arrayLength"
42 #define PARAM_GROUP_ID_ATTR_NAME "ref"
43 #define CV_ACCESSION_ATTR_NAME "accession"
44 #define CV_UNIT_ATTR_NAME "unitAccession"
45 
46 
47 // constructor
48 MzmlDataHandler::MzmlDataHandler( MzmlSample& sample, const char* id, kome::core::XYData& xyData )
49  : m_sample( sample ), m_id( NVL( id, "" ) ), m_xyData( xyData ) {
50  m_reverseFlg = isbigendian();
52 }
53 
54 // destructor
56 }
57 
58 // set points
60  // points
61  if( m_dataLength > 0 ) {
62  m_xyData.reserve( m_dataLength );
63 
64  for( int i = 0; i < m_dataLength; i++ ) {
65  m_xyData.addPoint( m_xArray[ i ], m_yArray[ i ] );
66  }
67  }
68 
69  // delete arrays
70  if( m_xArray != NULL ) {
71  delete[] m_xArray;
72  m_xArray = NULL;
73  }
74 
75  if( m_yArray != NULL ) {
76  delete m_yArray;
77  m_yArray = NULL;
78  }
79 
80  m_reading = false;
81 }
82 
83 // start document
85  // initialize
86  m_reading = false;
87  m_dataLength = 0;
88  m_available = false;
89 
90  m_xArray = NULL;
91  m_yArray = NULL;
92 }
93 
94 // end document
96  // delete arrays
97  if( m_xArray != NULL ) {
98  delete[] m_xArray;
99  m_xArray = NULL;
100  }
101 
102  if( m_yArray != NULL ) {
103  delete m_yArray;
104  m_yArray = NULL;
105  }
106 }
107 
108 // start element
109 void MzmlDataHandler::onStartElement( const char* name, kome::core::Properties& attrs ) {
110  // each tags
111  if( strcmp( name, SPEC_TAG_NAME ) == 0 ) { // <spectrum>
112  // ID
113  const char* id = attrs.getStringValue( SPEC_ID_ATTR_NAME, "" );
114  if( m_id.compare( id ) == 0 ) {
115  m_reading = true;
116  m_dataLength = attrs.getIntValue( SPEC_LENGTH_ATTR_NAME, 0 );
117  }
118  }
119  else if( strcmp( name, CHROM_TAG_NAME ) == 0 ) { // <chromatogram>
120  // ID
121  const char* id = attrs.getStringValue( CHROM_ID_ATTR_NAME, "" );
122  if( m_id.compare( id ) == 0 ) {
123  m_reading = true;
124  m_dataLength = attrs.getIntValue( CHROM_LENGTH_ATTR_NAME, 0 );
125  }
126  }
127  else if( strcmp( name, ARRAY_TAG_NAME ) == 0 ) { // <binaryDataArray>
128  if( m_reading ) {
129  m_dataLength = attrs.getIntValue( ARRAY_LENGTH_ATTR_NAME, m_dataLength );
130 
131  m_arrayInfo.name.clear();
132  m_arrayInfo.bits = 32;
133  m_arrayInfo.compressed = false;
134  m_arrayInfo.scale = 1.0;
135  m_arrayInfo.isY = false;
136 
137  m_available = false;
138  }
139  }
140  else if( strcmp( name, PARAM_GROUP_TAG_NAME ) == 0 ) { // <referenceableParamGroupRef>
141  if( m_reading ) {
142  const char* id = attrs.getStringValue( PARAM_GROUP_ID_ATTR_NAME, "" );
144  if( info != NULL ) {
145  m_arrayInfo = *info;
146  m_available = true;
147  }
148  }
149  }
150  else if( strcmp( name, CV_TAG_NAME ) == 0 ) { // <cvParam>
151  if( m_reading ) {
152  // accession
153  const char* accession = attrs.getStringValue( CV_ACCESSION_ATTR_NAME, "" );
154 
155  // each accessions
156  if( strcmp( accession, "MS:1000514" ) == 0 ) { // m/z array
157  m_arrayInfo.isY = false;
158  m_arrayInfo.scale = 1.0;
159 
160  m_available = true;
161  }
162  else if( strcmp( accession, "MS:1000595" ) == 0 ) { // RT array
163  m_arrayInfo.isY = false;
164  m_arrayInfo.scale = 1.0;
165 
166  m_available = true;
167 
168  const char* unit = attrs.getStringValue( CV_UNIT_ATTR_NAME, "" );
169  if( strcmp( unit, "UO:0000031" ) != 0 ) { // second
170  m_arrayInfo.scale = 1.0 / 60.0;
171  }
172  }
173  else if( strcmp( accession, "MS:1000515" ) == 0 ) { // intensity array
174  m_arrayInfo.isY = true;
175  m_available = true;
176  }
177  else if( strcmp( accession, "MS:1000521" ) == 0 ) { // 32-bit float
178  m_arrayInfo.bits = 32;
179  }
180  else if( strcmp( accession, "MS:1000523" ) == 0 ) { // 64-bit float
181  m_arrayInfo.bits = 64;
182  }
183  else if( strcmp( accession, "MS:1000576" ) == 0 ) { // no compression
184  m_arrayInfo.compressed = false;
185  }
186  else if( strcmp( accession, "MS:1000574" ) == 0 ) { // zlib compression
187  m_arrayInfo.compressed = true;
188  }
189  }
190  }
191 }
192 
193 // end element
194 void MzmlDataHandler::onEndElement( const char* name, const char* text ) {
195  // each tags
196  if( strcmp( name, SPEC_TAG_NAME ) == 0 ) { // </spectrum>
197  if( m_reading ) {
198  setPoints();
199  }
200  }
201  else if( strcmp( name, CHROM_TAG_NAME ) == 0 ) { // </chromatogram>
202  if( m_reading ) {
203  setPoints();
204  }
205  }
206  else if( strcmp( name, BINARY_TAG_NAME ) == 0 ) { // </binary>
207  if( m_reading && m_available && m_dataLength > 0 ) {
208  // create array
209  double* arr = NULL;
210  if( m_arrayInfo.isY ) {
211  if( m_yArray == NULL ) {
212  m_yArray = new double[ m_dataLength ];
213  }
214  arr = m_yArray;
215  }
216  else {
217  if( m_xArray == NULL ) {
218  m_xArray = new double[ m_dataLength ];
219  }
220  arr = m_xArray;
221  }
222 
223  // get data
224  char* data0 = new char[ strlen( text ) ];
225  unsigned long size0 = kome::core::Base64::decode( (char*)text, strlen( text ), data0, strlen( text ) );
226 
227  unsigned long size1 = m_dataLength * m_arrayInfo.bits / 8;
228  char* data1 = new char[ size1 ];
229 
230  if( m_arrayInfo.compressed ) {
231  uncompress( (Bytef*)data1, &size1, (Bytef*)data0, size0 );
232  }
233  else {
234  memcpy( data1, data0, size1 );
235  }
236 
237  // add to array
238  if( m_arrayInfo.bits == 64 ) { // double
239  double* dArr = (double*)data1;
240  for( int i = 0; i < m_dataLength; i++ ) {
241  arr[ i ] = dArr[ i ] * m_arrayInfo.scale;
242  if( m_reverseFlg ) {
243  memreverse( arr + i, sizeof( double ) );
244  }
245  }
246  }
247  else { // float
248  float* fArr = (float*)data1;
249  for( int i = 0; i < m_dataLength; i++ ) {
250  arr[ i ] = (double)fArr[ i ] * m_arrayInfo.scale;
251  if( m_reverseFlg ) {
252  memreverse( arr + i, sizeof( double ) );
253  }
254  }
255  }
256 
257  // delete
258  delete[] data0;
259  delete[] data1;
260  }
261  m_available = false;
262  }
263 }
kome::core::XYData & m_xyData
interfaces of MzmlDataHandler class
virtual void onEndElement(const char *name, const char *text)
This method is called by end element method. (override method)
virtual void onStartElement(const char *name, kome::core::Properties &attrs)
This method is called by startElement method. (override method)
virtual ~MzmlDataHandler()
destructor
virtual void onEndDocument()
This method is called by endDocument method. (override method)
interfaces of MzmlSample class
ArrayInfo * getArrayInfo(const char *name)
gets array information
Definition: MzmlSample.cpp:111
common header file
MzmlSample::ArrayInfo m_arrayInfo
MzmlDataHandler(MzmlSample &sample, const char *id, kome::core::XYData &xyData)
constructor
virtual void onStartDocument()
This method is called by startDocument method. (override method)
mzML sample class
Definition: MzmlSample.h:26
void setPoints()
set data points