NTupleProjector.cxx
Go to the documentation of this file.
1 
12 #ifdef _MSC_VER
13 #include "msdevstudio/MSconfig.h"
14 #endif
15 
16 #include "NTupleProjector.h"
17 
18 #include "axes/AxisModelBase.h"
19 
20 #include "datasrcs/NTuple.h"
21 #include "datasrcs/TupleCut.h"
22 
23 #include <algorithm>
24 #include <functional>
25 #include <stdexcept>
26 #include <climits>
27 
28 #include <cassert>
29 
30 #ifdef ITERATOR_MEMBER_DEFECT
31 using namespace std;
32 #else
33 using std::distance;
34 using std::find;
35 using std::max;
36 using std::max_element;
37 using std::min;
38 using std::min_element;
39 using std::runtime_error;
40 using std::string;
41 using std::vector;
42 #endif
43 
44 using namespace hippodraw;
45 
46 NTupleProjector::NTupleProjector ( unsigned int columns )
47  : ProjectorBase (),
48  m_is_valid ( true ),
49  m_columns ( columns, UINT_MAX ),
50  m_cut_list(0), // Null pointer.
51  m_min_bindings ( 0 )
52 {
53  m_ntuple = new NTuple ( true );
54 }
55 
57  : ProjectorBase ( projector ),
58  m_is_valid ( projector.m_is_valid ),
59  m_binding_options ( projector.m_binding_options ),
60  m_bindings ( projector.m_bindings),
61  m_columns ( projector.m_columns ),
62  m_ntuple ( projector.m_ntuple ),
63  m_min_bindings ( projector.m_min_bindings )
64 {
65  if ( m_ntuple->isNull () ) {
66  m_ntuple = new NTuple ( true );
67  }
69 }
70 
72 {
73  if ( m_ntuple->isNull () ) {
74  delete m_ntuple;
75  }
76  else {
77  DataSource * source = const_cast < DataSource * > ( m_ntuple );
78  source -> removeObserver ( this );
79  }
80 }
81 
83 {
84  setDirty ( true );
85  notifyObservers ();
86 }
87 
88 void
90 willDelete ( const Observable * observee )
91 {
92  if ( observee == m_ntuple ) {
93  m_ntuple = new NTuple ( true ); // a null ntuple
94  }
95 }
96 
97 const vector< string > & NTupleProjector::bindingOptions () const
98 {
99  return m_binding_options;
100 }
101 
102 unsigned int NTupleProjector::
103 indexOfBindingOption ( const std::string & axis ) const
104 {
105  vector< string >::const_iterator first
106  = find ( m_binding_options.begin(),
107  m_binding_options.end(),
108  axis );
109  if ( first == m_binding_options.end () ) {
110  std::string what = std::string("NTupleProjector::indexOfBindingOption: ")
111  + std::string("no such binding option: ") + axis;
112  throw runtime_error( what );
113  }
114 
115 #ifdef DISTANCE_DEFECT
116  return first - m_binding_options.begin();
117 #else
118  return distance ( m_binding_options.begin(), first );
119 #endif
120 }
121 
122 const std::vector < std::string > &
125 {
126  m_bindings.clear();
127  size_t size = m_columns.size ();
128  for ( size_t i = 0; i < size; i++ ) {
129  int column = m_columns[i];
130  if ( column >= 0 ) {
131  const string & label = m_ntuple->getLabelAt ( column );
132  m_bindings.push_back ( label );
133  } else {
134  const string label = "nil";
135  m_bindings.push_back ( label );
136  }
137  }
138 
139  return m_bindings;
140 }
141 
142 int
144 indexOf ( const std::string & label ) const
145 {
146  return m_ntuple->indexOf ( label );
147 }
148 
150 {
151 }
152 
154 {
155 }
156 
157 bool
159 acceptRow ( unsigned int i, const CutList_t & cut_list ) const
160 {
161  // measured with gprof to be faster this way then using iterators.
162  bool accept = true;
163 
164  if ( cut_list.empty() == false ) {
165  unsigned int size = cut_list.size();
166  unsigned int j = 0;
167  while ( j < size ) {
168  const TupleCut * cut = cut_list[j++];
169  if ( cut != 0 ) {
170  if ( cut -> acceptRow ( m_ntuple, i ) == false ) {
171  accept = false;
172  break;
173  }
174  }
175  }
176  }
177 
178  return accept;
179 }
180 
181 void
183 setAxisBinding ( int axis, const std::string & label )
184 {
185  if ( label == "nil" ) {
186  m_columns[axis] = UINT_MAX;
187  }
188  else {
189  m_ntuple -> throwIfInvalidLabel ( label );
190  int column = m_ntuple->indexOf ( label );
191  m_columns[axis] = column;
192  }
193  m_is_valid = true;
194  setDirty ( true );
195 }
196 
197 void NTupleProjector::setAxisBinding ( const std::string & axis,
198  const std::string & label )
199 {
200  unsigned int index = indexOfBindingOption ( axis );
201 
202  setAxisBinding ( index, label );
203 }
204 
205 void
207 setAxisBindings ( const std::vector< std::string > & labels )
208 {
209  size_t size = labels.size();
210 
211  if ( size < m_min_bindings ) {
212  string what ( "NTupleProjector::setAxisBindings: " );
213  what += "insufficient number of labels";
214  throw runtime_error ( what );
215  }
216 
217  size_t cols = m_columns.size ();
218  for ( unsigned int i = 0; i < cols; i++ ) {
219  if ( i < size ) {
220  const string & label = labels[i];
221  setAxisBinding ( i, label );
222  }
223  else {
224  const string nil ( "nil" );
225  setAxisBinding ( i, nil );
226  }
227  }
228  m_is_valid = true;
229 }
230 
231 void NTupleProjector::setNTuple ( const DataSource * ntuple )
232 {
233  assert ( ntuple != 0 );
234 
235  if ( m_ntuple->isNull () ) {
236  delete m_ntuple;
237  m_ntuple = 0;
238  }
239 
240  if ( m_ntuple != 0 ) {
241  DataSource * nt = const_cast < DataSource * > ( m_ntuple );
242  nt->removeObserver ( this );
243  }
244  m_ntuple = ntuple;
245  changedNTuple();
246  m_is_valid = true;
247  setDirty ( true );
248 }
249 
250 
251 const string & NTupleProjector::getTitle() const
252 {
253  return m_ntuple->title();
254 }
255 
256 const std::string & NTupleProjector::getXLabel() const
257 {
258  return m_ntuple->getLabelAt( m_columns[0] );
259 }
260 
261 const string & NTupleProjector::getYLabel ( bool ) const
262 {
263  return m_ntuple->getLabelAt( m_columns[1] );
264 }
265 
267 {
268  assert ( !( data < 0 ) &&
269  static_cast<size_t> ( data ) < m_ntuple->columns () );
270  assert ( !( error < 0 ) &&
271  static_cast<size_t> ( error ) < m_ntuple->columns () );
272 
273  double lo = DBL_MAX;
274  double hi = DBL_MIN;
275 
276  unsigned int size = m_ntuple -> rows ();
277  for ( unsigned int row = 0; row < size; row++ ) {
278  double value = m_ntuple -> valueAt ( row, data );
279  double err = m_ntuple -> valueAt ( row, error );
280  lo = min ( value - err, lo );
281  hi = max ( value + err, hi );
282  }
283 
284  double pos = getPosWithError( data, error );
285 
286  return Range ( lo, hi, pos );
287 }
288 
289 Range
291 dataRange ( int column ) const
292 {
293  assert ( m_ntuple );
294  assert ( !( column < 0 ) &&
295  static_cast<size_t> (column) < m_ntuple->columns() );
296 
297  Range range;
298  bool isValid = m_ntuple -> fillRange ( column, range );
299  m_is_valid &= isValid;
300 
301  return range;
302 }
303 
304 double NTupleProjector::getPosWithError ( int data, int error ) const
305 {
306  assert ( !( data < 0 ) &&
307  static_cast<size_t> ( data ) < m_ntuple->columns () );
308  assert ( !( error < 0 ) &&
309  static_cast<size_t> ( error ) < m_ntuple->columns () );
310 
311  double pos = DBL_MAX;
312 
313  unsigned int size = m_ntuple -> rows ();
314  for ( unsigned int row = 0; row < size; row++ ) {
315  double value = m_ntuple -> valueAt ( row, data );
316  double err = m_ntuple -> valueAt ( row, error );
317  if ( value > 0. ) {
318  double x = value - err;
319  if ( x > 0.0 ) {
320  pos = min ( x, pos );
321  }
322  else {
323  if ( value != 0.0 ) pos = min ( 0.1 * value, pos );
324  }
325  }
326  }
327 
328  return pos;
329 }
330 
331 double
333 getPos ( int column ) const
334 {
335  assert ( m_ntuple );
336  assert ( !( column < 0 ) &&
337  static_cast<size_t> (column) < m_ntuple->columns() );
338 
339  double pos = DBL_MAX;
340 
341  unsigned int size = m_ntuple -> rows ();
342 
343  for ( unsigned int row = 0; row < size; row++ ) {
344  double value = m_ntuple -> valueAt ( row, column );
345  if ( value < pos && value > 0.0 ) pos = value;
346  }
347 
348  return pos;
349 }
350 
351 void NTupleProjector::addCut ( const TupleCut * cut )
352 {
353  m_cut_list.push_back ( cut );
354 }
355 
357 {
358  CutList_t ::iterator first
359  = find ( m_cut_list.begin(), m_cut_list.end(), cut );
360  assert ( first != m_cut_list.end() );
361 
362  m_cut_list.erase ( first );
363 }
364 
365 const vector < const TupleCut * > & NTupleProjector::getCutList () const
366 {
367  return m_cut_list;
368 }
369 
370 int
373 {
374  unsigned int size = m_ntuple->rows ();
375  int number = 0;
376  for ( unsigned int i = 0; i < size; i++ ) {
377  if ( acceptRow ( i, m_cut_list ) &&
378  inRange ( i ) )
379  {
380  number++;
381  }
382  }
383 
384  return number;
385 }
386 
387 int
389 getUnderflow () const
390 {
391  return -1;
392 }
393 
394 int
396 getOverflow () const
397 {
398  return -1;
399 }
400 
401 
402 bool
404 inRange ( int row ) const
405 {
406  unsigned int size = m_columns.size(); // number of bound columns
407  bool yes = true;
408  for ( unsigned int i = 0; i < size; i++ ) {
409  if ( m_columns[i] == UINT_MAX ) break;
410 
411  AxisModelBase * axis_model = 0;
412  if ( i == 0 ) axis_model = m_x_axis;
413  else if ( i == 1 ) axis_model = m_y_axis;
414  else if ( i == 2 ) axis_model = m_z_axis;
415  if ( axis_model == 0 ) break;
416 
417  unsigned int column = m_columns[i];
418  const Range & range = axis_model->getRange ( false );
419  double value = m_ntuple -> valueAt ( row, column );
420  if ( range.excludes ( value ) ) return false;
421  }
422 
423  return yes;
424 }
425 
428 const DataSource *
430 getNTuple () const
431 {
432  return m_ntuple;
433 }
434 
437 DataSource *
439 {
440  return const_cast < DataSource * > ( m_ntuple );
441 }
442 
443 const string & NTupleProjector::getNTupleName () const
444 {
445  return m_ntuple->getName ();
446 }
447 
448 double
451 {
452 
453  double sum = 0.0;
454  double number = 0.0;
455 
456  string label = "";
457 
458  // Get the axis label.
459  switch ( axis ) {
460  case Axes::X:
461  label = getXLabel();
462  break;
463  case Axes::Y:
464  label = getYLabel();
465  break;
466  case Axes::Z:
467  label = getZLabel();
468  break;
469  default:
470  break;
471  }
472 
473  // Get the NTuple for this NTupleProjector.
474  const DataSource * tuple = getNTuple();
475  if ( tuple -> empty () ) {
476  return 0.0;
477  }
478  // Check if the label is valid for the NTuple.
479 // if(!tuple->isFilled(label)) return 0.0;
480 
481  // Get the column corresponding to the label.
482  unsigned int column = tuple -> indexOf ( label );
483  // Get the range of projected values.
484  const Range & r = getRange ( axis );
485  unsigned int size = m_ntuple -> rows ();
486  for ( unsigned int i = 0; i < size; i++ ) {
487  // Check if row i is eliminated because of a cut.
488  if ( !acceptRow ( i, m_cut_list ) )continue;
489  double value = m_ntuple -> valueAt ( i, column );
490  // Add the current value only if it is within the range.
491  if ( r.includes ( value ) ) {
492  sum += value;
493  number ++;
494  }
495 
496  }
497 
498  return (sum / number);
499 }
500 
501 bool
503 isEmpty () const
504 {
505  return m_ntuple -> empty ();
506 }
507 
508 NTuple *
511 {
512  unsigned int columns = m_ntuple->columns();
513 
514  NTuple * ntuple = new NTuple ( columns );
515 
516  const vector < string > & labels = m_ntuple->getLabels();
517  ntuple->setLabels ( labels );
518 
519  unsigned int size = m_ntuple->rows();
520  ntuple -> reserve ( size );
521  return ntuple;
522 }
523 
524 void
526 fillNTuple ( NTuple * ntuple, const CutList_t & cut_list ) const
527 {
528  unsigned int size = m_ntuple->rows();
529 
530  for ( unsigned int i = 0; i < size; i++ ) {
531  if ( acceptRow ( i, cut_list ) ) { //&& inRange(i) ) {
532  const vector < double > & row = m_ntuple -> getRow ( i );
533  ntuple -> addRow ( row );
534  }
535  }
536 }
537 
538 NTuple *
541 {
542  NTuple * ntuple = createEmptyNTuple ();
543  fillNTuple ( ntuple, m_cut_list );
544 
545  return ntuple;
546 }
547 
548 void
550 fillColumnAfterCuts(const std::string & column,
551  std::vector<double> & columnData) const {
552 
553  const std::vector<double> & coldata(m_ntuple->getColumn(column));
554 
555  size_t nrows = m_ntuple->rows();
556  for ( size_t i = 0 ; i < nrows ; i++ ) {
557  if ( acceptRow( i, m_cut_list ) ) {
558  columnData.push_back( coldata[i] );
559  }
560  }
561 }
562 
563 NTuple *
565 createNTupleWith ( const std::vector < TupleCut > & tuple_cuts ) const
566 {
567  NTuple * ntuple = createEmptyNTuple ();
568  vector < const TupleCut * > cut_list;
569  for ( unsigned int i = 0; i < tuple_cuts.size(); i++ ) {
570  const TupleCut & cut = tuple_cuts[i];
571  cut_list.push_back ( & cut );
572  }
573  fillNTuple ( ntuple, cut_list );
574 
575  return ntuple;
576 }
577 
578 bool
580 isDataValid () const
581 {
582  return m_is_valid;
583 }
584 
585 bool
588 {
589  return true;
590 }

Generated for HippoDraw Class Library by doxygen