Mass++ Common Libraries v2.7.5
 All Classes Namespaces Files Functions Variables Enumerations Macros
PeakElement.cpp
Go to the documentation of this file.
1 
12 #include "stdafx.h"
13 #include "PeakElement.h"
14 
15 #include "Peaks.h"
16 
17 #include <float.h>
18 #include <math.h>
19 
20 using namespace kome::objects;
21 
22 
23 #include <crtdbg.h>
24 #ifdef _DEBUG
25  #define new new( _NORMAL_BLOCK, __FILE__, __LINE__ )
26  #define malloc( s ) _malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ )
27 #endif // _DEBUG
28 
29 
30 // constructor
32  : m_left( -1.0, -1.0 ), m_right( -1.0, -1.0 ), m_apex( -1.0, -1.0 )
33 {
34  // initialize
35  m_peaks = NULL;
36  m_x = -1.0;
37  m_y = -1.0;
38 
39  m_area = - FLT_MAX;
40  m_fwhm = - FLT_MAX;
41 
42  m_charge = -1;
43 
44  m_peakId = -1;
45 }
46 
47 // constructor
49  : m_left( -1.0, -1.0 ), m_right( -1.0, -1.0 ), m_apex( -1.0, -1.0 )
50 {
51  m_peaks = peaks;
52  m_x = -1.0;
53  m_y = -1.0;
54 
55  m_area = - FLT_MAX;
56  m_fwhm = - FLT_MAX;
57 
58  m_charge = -1;
59 
60  // issue peak id
61  if( m_peaks != NULL ){
62  m_peakId = m_peaks->issueId( this );
63  }
64 }
65 
66 // constructor
67 PeakElement::PeakElement( Peaks* peaks, const double x, const double y )
68  : m_x( x ), m_y( y ), m_left( x, 0.0 ), m_right( x, 0.0 ), m_apex( x, y )
69 {
70  m_peaks = peaks;
71 
72  m_area = - FLT_MAX;
73  m_fwhm = - FLT_MAX;
74 
75  m_charge = -1;
76 
77  // issue peak id
78  if( m_peaks != NULL ){
79  m_peakId = m_peaks->issueId( this );
80  }
81 }
82 
83 // destructor
85 }
86 
87 // set x
88 void PeakElement::setX( const double x ) {
89  m_x = x;
90 
91  if( m_left.px < 0.0 ) {
92  m_left.px = x;
93  }
94  if( m_right.px < 0.0 ) {
95  m_right.px = x;
96  }
97 }
98 
99 // get x
101  return m_x;
102 }
103 
104 // set y
105 void PeakElement::setY( const double y ) {
106  m_y = y;
107 
108  if( m_left.py < 0.0 ) {
109  m_left.py = 0.0;
110  }
111  if( m_right.py < 0.0 ) {
112  m_right.py = 0.0;
113  }
114 }
115 
116 // get y
118  return m_y;
119 }
120 
121 // set peak left
122 void PeakElement::setLeft( const double x, const double y ) {
123  if( m_left.px != x || m_left.py != y ) {
124  m_left.px = x;
125  m_left.py = y;
126 
127  m_area = - FLT_MAX;
128  m_apex.px = -1.0;
129  m_apex.py = -1.0;
130  }
131 }
132 
133 // get peak left x
135  return m_left.px;
136 }
137 
138 // get peak left y
140  return m_left.py;
141 }
142 
143 // set peak right
144 void PeakElement::setRight( const double x, const double y ) {
145  if( m_right.px != x || m_right.py != y ) {
146  // set
147  m_right.px = x;
148  m_right.py = y;
149 
150  m_area = - FLT_MAX;
151  m_apex.px = -1.0;
152  m_apex.py = -1.0;
153  }
154 }
155 
156 // get peak right x
158  return m_right.px;
159 }
160 
161 // get peak right y
163  return m_right.py;
164 }
165 
166 // set peak apex
167 void PeakElement::setApex( const double x, const double y ) {
168  m_apex.px = x;
169  m_apex.py = y;
170 }
171 
172 // get peak apex x
174  if( m_apex.px < 0.0 ) {
175  m_peaks->calcArea();
176  }
177  return m_apex.px;
178 }
179 
180 // get peak apex y
182  if( m_apex.px < 0.0 ) {
183  m_peaks->calcArea();
184  }
185  return m_apex.py;
186 }
187 
188 // search apex
190  // left X
191  const double lx = getLeftX();
192  const double rx = getRightX();
193 
194  // index
195  int idx0 = xyData.searchIndex( lx );
196  if( idx0 < 0 ) {
197  idx0 = - idx0 - 2;
198  if( idx0 < 0 ) {
199  idx0 = 0;
200  }
201  }
202  int idx1 = xyData.searchIndex( rx );
203  if( idx1 < 0 ) {
204  idx1 = - idx1 - 1;
205  if( idx1 >= (int)xyData.getLength() ) {
206  idx1 = (int)xyData.getLength() - 1;
207  }
208  }
209 
210  // apex
211  double apexY = 0.0;
212  double apexX = -1.0;
213  for( int i = idx0; i <= idx1; i++ ) {
214  const double x = xyData.getX( i );
215  const double y = xyData.getY( i );
216 
217  if( y > apexY || apexX < 0.0 ) {
218  apexX = x;
219  apexY = y;
220  }
221  }
222 
223  // set
224  if( apexX >= 0.0 ) {
225  m_apex.px = apexX;
226  m_apex.py = apexY;
227  }
228 }
229 
230 // has apex
232  return ( m_apex.px >= 0.0 );
233 }
234 
235 // set area
236 void PeakElement::setArea( const double area ) {
237  m_area = area;
238 }
239 
240 // get peak area
242  if( !hasArea() && m_peaks != NULL ) {
243  m_peaks->calcArea();
244  }
245 
246  return m_area;
247 }
248 
249 // having area value or not
251  return ( m_area > -1000.0 );
252 }
253 
254 // calculate area
256  // calculate area
257  double s = 0.0;
258 
259  // base line
260  const double lx = getLeftX();
261  const double ly = getLeftY();
262  const double rx = getRightX();
263  const double ry = getRightY();
264 
265  const double w = rx - lx;
266  if( w < 0.0000001 ) {
267  return s;
268  }
269 
270  const double a = ( ry - ly ) / w;
271 
272  // index
273  int idx0 = xyData.getNearestIndex( lx );
274  int idx1 = xyData.getNearestIndex( rx );
275 
276  for( int i = idx0; i < idx1 - 1; i++ ) {
277  // coordinates
278  const double x0 = xyData.getX( i );
279  const double x1 = xyData.getX( i + 1 );
280  const double y0 = xyData.getY( i ) - ( a * ( x0 - lx ) + ly );
281  const double y1 = xyData.getY( i + 1 ) - ( a * ( x1 - lx ) + ly );
282 
283  if( y0 >= 0.0 && y1 >= 0.0 ) {
284  s += ( y0 + y1 ) * ( x1 - x0 ) / 2.0; // @date 2011/02/23 <Comment> OKADA : ‘δŒ`‚̖ʐρFiγ’κ(y0){‰Ί’κ(y1)j~‚‚³(x1-x0)€‚Q
285  }
286  // baseline‚̏㑀‚̖ʐς̂݋‚ί‚ι
287  else if( y0 > 0.0 ) { // @date 2011/02/23 <Comment> OKADA : (y1<0.0)‚̏ꍇA
288  s += - y0 * y0 * ( x1 - x0 ) / ( y1 - y0 ) / 2.0; // ŽOŠpŒ`‚̍‚‚³Fy0 * ( x1 - x0 ) / ( y1 - y0 )
289  }
290  else if( y1 > 0.0 ) { // @date 2011/02/23 <Comment> OKADA : (y0<0.0)‚̏ꍇ
291  s += y1 * y1 * ( x1 - x0 ) / ( y1 - y0 ) / 2.0;
292  }
293  }
294 
295  // apex
296  searchApex( xyData );
297 
298  return s;
299 }
300 
301 // set the FWHM
302 void PeakElement::setFwhm( const double fwhm ) {
303  m_fwhm = fwhm;
304 }
305 
306 // get the FWHM
308  if( !hasFwhm() && m_peaks != NULL ) {
309  m_peaks->calcArea();
310  }
311 
312  return m_fwhm;
313 }
314 
315 // having FWHM value or not
317  return ( m_fwhm > -1000.0 );
318 }
319 
320 // calculate FWHM
322  // return value
323  double fwhm = -1.0;
324 
325  // apex
326  if( m_apex.px < 0.0 ) {
327  searchApex( xyData );
328  }
329 
330  const double ax = m_apex.px;
331  const double ay = m_apex.py;
332  if( ax < 0.0 ) {
333  return fwhm;
334  }
335  const double height = ay / 2.0;
336 
337  int idx = xyData.getNearestIndex( ax );
338  if( idx < 0 || ax >= (double)xyData.getLength() ) {
339  return fwhm;
340  }
341 
342  // left
343  double lx = -1.0;
344  double prevX = ax;
345  double prevY = ay;
346  for( int i = idx - 1; i >= 0 && lx < 0.0; i-- ) {
347  const double x = xyData.getX( i );
348  const double y = xyData.getY( i );
349 
350  if( prevY >= height && y <= height ) {
351  if( fabs( y - prevY ) < 0.00001 ) {
352  lx = prevX;
353  }
354  else {
355  lx = ( prevX * ( y - height ) + x * ( height - prevY ) ) / ( y - prevY );
356  }
357  }
358  else if( y > ay ) {
359  i = -1;
360  }
361 
362  prevX = x;
363  prevY = y;
364  }
365 
366  if( lx < 0.0 ) {
367  return fwhm;
368  }
369 
370  // right
371  double rx = -1.0;
372  prevX = ax;
373  prevY = ay;
374  for( int i = idx + 1; i < (int)xyData.getLength() && rx < 0.0; i++ ) {
375  const double x = xyData.getX( i );
376  const double y = xyData.getY( i );
377 
378  if( prevY >= height && y <= height ) {
379  if( fabs( y - prevY ) < 0.00001 ) {
380  rx = prevX;
381  }
382  else {
383  rx = ( prevX * ( y - height ) + x * ( height - prevY ) ) / ( y - prevY );
384  }
385  }
386  else if( y > ay ) {
387  i = (int)xyData.getLength();
388  }
389 
390  prevX = x;
391  prevY = y;
392  }
393 
394  if( rx < 0.0 ) {
395  return fwhm;
396  }
397 
398  fwhm = fabs( rx - lx );
399 
400  return fwhm;
401 }
402 
403 // set peak id
404 void PeakElement::setId( int id ){
405  m_peakId = id;
406 }
407 
408 // get peak id
410  return m_peakId;
411 }
412 
413 // set charge
414 void PeakElement::setCharge( const int charge ) {
415  m_charge = charge;
416 }
417 
418 // get charge
420  return m_charge;
421 }
double calcFwhm(kome::core::XYData &xyData)
calculates FWHM
abstraction class of two dimention coordinate data
Definition: XYData.h:34
double getArea()
gets peak area
int issueId(PeakElement *peakElement)
to issue the peak id
Definition: Peaks.cpp:579
void setX(const double x)
sets x element value
Definition: PeakElement.cpp:88
bool hasFwhm()
judges whether this peak has FWHM value of not
double getX(const unsigned int index)
gets x coordinate
Definition: XYData.cpp:224
void setRight(const double x, const double y)
sets peak right
void searchApex(kome::core::XYData &xyData)
searches apex
void calcArea()
calculates area
Definition: Peaks.cpp:226
virtual ~PeakElement()
destructor
Definition: PeakElement.cpp:84
double calcArea(kome::core::XYData &xyData)
calculates area
kome::core::Point< double > m_left
Definition: PeakElement.h:68
void setArea(const double area)
sets area
double getRightX()
gets x element of peak right
double getY(const unsigned int index)
gets y coordinate
Definition: XYData.cpp:243
double getRightY()
gets y elemtn of peak right
void setFwhm(const double fwhm)
sets the FWHM
interfaces of Peaks class
void setCharge(const int charge)
sets the charge state
interfaces of PeakElement class
#define NULL
Definition: CoreMacros.h:18
double getLeftX()
gets x element of peak left
double getApexX()
gets x element of peak apex
double getY()
gets y element value
kome::core::Point< double > m_apex
Definition: PeakElement.h:74
double getApexY()
gets y element of peak apex
int getId()
gets peak ID
bool hasApex()
judges whether this peak has apex information or not.
void setId(int id)
sets peak ID
void setApex(const double x, const double y)
sets peak apex
void setLeft(const double x, const double y)
sets peak left
double getX()
gets x element value
bool hasArea()
judges whether this peak has area value or not
double getFwhm()
gets the FWHM
kome::core::Point< double > m_right
Definition: PeakElement.h:71
peaks information class
Definition: Peaks.h:35
void setY(const double y)
sets y element value
int getNearestIndex(const double x)
gets nearest index
Definition: XYData.cpp:313
int getCharge()
gets the charge state
int searchIndex(const double x)
searches index of specified x value.
Definition: XYData.cpp:276
unsigned int getLength()
gets the number of points @return the number of points
Definition: XYData.cpp:216
double getLeftY()
gets y element of peak left