NTupleProjector.cxx

Go to the documentation of this file.
00001 
00012 #ifdef _MSC_VER
00013 #include "msdevstudio/MSconfig.h"
00014 #endif
00015 
00016 #include "NTupleProjector.h"
00017 
00018 #include "axes/AxisModelBase.h"
00019 
00020 #include "datasrcs/NTuple.h"
00021 #include "datasrcs/TupleCut.h"
00022 
00023 #include <algorithm>
00024 #include <functional>
00025 #include <stdexcept>
00026 
00027 #include <cassert>
00028 
00029 #ifdef ITERATOR_MEMBER_DEFECT
00030 using namespace std;
00031 #else
00032 using std::distance;
00033 using std::find;
00034 using std::max;
00035 using std::max_element;
00036 using std::min;
00037 using std::min_element;
00038 using std::runtime_error;
00039 using std::string;
00040 using std::vector;
00041 #endif
00042 
00043 using namespace hippodraw;
00044 
00045 NTupleProjector::NTupleProjector ( unsigned int columns )
00046   : ProjectorBase (),
00047     m_is_valid ( true ),
00048     m_columns ( columns, UINT_MAX ),
00049     m_cut_list(0), // Null pointer.
00050     m_min_bindings ( 0 )
00051 {
00052   m_ntuple = new NTuple ( true );
00053 }
00054 
00055 NTupleProjector::NTupleProjector ( const NTupleProjector & projector )
00056   : ProjectorBase ( projector ),
00057     m_is_valid ( projector.m_is_valid ),
00058     m_binding_options ( projector.m_binding_options ),
00059     m_bindings ( projector.m_bindings),
00060     m_columns ( projector.m_columns ),
00061     m_ntuple ( projector.m_ntuple ),
00062     m_min_bindings ( projector.m_min_bindings )
00063 {
00064   if ( m_ntuple->isNull () ) {
00065     m_ntuple = new NTuple ( true );
00066   }
00067   m_binding_options = projector.m_binding_options;
00068 }
00069 
00070 NTupleProjector::~NTupleProjector ()
00071 {
00072   if ( m_ntuple->isNull () ) {
00073     delete m_ntuple;
00074   }
00075   else {
00076     DataSource * source = const_cast < DataSource * > ( m_ntuple );
00077     source -> removeObserver ( this );
00078   }
00079 }
00080 
00081 void  NTupleProjector::update ( const Observable * )
00082 {
00083   setDirty ( true );
00084   notifyObservers ();
00085 }
00086 
00087 void
00088 NTupleProjector::
00089 willDelete ( const Observable * observee )
00090 {
00091   if ( observee == m_ntuple ) {
00092     m_ntuple = new NTuple ( true ); // a null ntuple
00093   }
00094 }
00095 
00096 const vector< string > & NTupleProjector::bindingOptions () const
00097 {
00098   return m_binding_options;
00099 }
00100 
00101 unsigned int NTupleProjector::
00102 indexOfBindingOption ( const std::string & axis ) const
00103 {
00104   vector< string >::const_iterator first 
00105     = find ( m_binding_options.begin(),
00106              m_binding_options.end(),
00107              axis );
00108   if ( first == m_binding_options.end () ) {
00109      std::string what = std::string("NTupleProjector::indexOfBindingOption: ")
00110         + std::string("no such binding option: ") + axis;
00111      throw runtime_error( what );
00112   }
00113 
00114 #ifdef DISTANCE_DEFECT
00115   return first - m_binding_options.begin();
00116 #else
00117   return distance ( m_binding_options.begin(), first );
00118 #endif
00119 }
00120 
00121 const std::vector < std::string > & 
00122 NTupleProjector::
00123 getAxisBindings () const
00124 {
00125   m_bindings.clear();
00126   size_t size = m_columns.size ();
00127   for ( size_t i = 0; i < size; i++ ) {
00128     int column = m_columns[i];
00129     if ( column >= 0 ) {
00130       const string & label = m_ntuple->getLabelAt ( column );
00131       m_bindings.push_back ( label );
00132     } else {
00133       const string label = "nil";
00134       m_bindings.push_back ( label );
00135     }
00136   }
00137 
00138   return m_bindings;
00139 }
00140 
00141 int 
00142 NTupleProjector::
00143 indexOf ( const std::string & label ) const
00144 {
00145   return m_ntuple->indexOf ( label );
00146 }
00147 
00148 void NTupleProjector::setXErrorOption ( bool )
00149 {
00150 }
00151 
00152 void NTupleProjector::setYErrorOption ( bool )
00153 {
00154 }
00155 
00156 bool
00157 NTupleProjector::
00158 acceptRow ( unsigned int i, const CutList_t & cut_list ) const
00159 {
00160   // measured with gprof to be faster this way then using iterators.
00161   bool accept = true;
00162 
00163   if ( cut_list.empty() == false ) {
00164     unsigned int size = cut_list.size();
00165     unsigned int j = 0;
00166     while ( j < size ) {
00167       const TupleCut * cut = cut_list[j++];
00168       if ( cut != 0 ) {
00169         if ( cut -> acceptRow ( m_ntuple, i ) == false ) {
00170           accept = false;
00171           break;
00172         }
00173       }
00174     }
00175   }
00176 
00177   return accept;
00178 }
00179 
00180 void 
00181 NTupleProjector::
00182 setAxisBinding ( int axis, const std::string & label )
00183 {
00184   if ( label == "nil" ) {
00185     m_columns[axis] = UINT_MAX;
00186   }
00187   else {
00188     m_ntuple -> throwIfInvalidLabel ( label );
00189     int column = m_ntuple->indexOf ( label );
00190     m_columns[axis] = column;
00191   }
00192   m_is_valid = true;
00193   setDirty ( true );
00194 }
00195 
00196 void NTupleProjector::setAxisBinding ( const std::string & axis, 
00197                                        const std::string & label )
00198 {
00199   unsigned int index = indexOfBindingOption ( axis );
00200 
00201   setAxisBinding ( index, label );
00202 }
00203 
00204 void 
00205 NTupleProjector::
00206 setAxisBindings ( const std::vector< std::string > & labels )
00207 {
00208   size_t size = labels.size();
00209 
00210   if ( size < m_min_bindings ) {
00211     string what ( "NTupleProjector::setAxisBindings: " );
00212     what += "insufficient number of labels";
00213     throw runtime_error ( what );
00214   }
00215 
00216   size_t cols = m_columns.size ();
00217   for ( unsigned int i = 0; i < cols; i++ ) {
00218     if ( i < size ) {
00219       const string & label = labels[i];
00220       setAxisBinding ( i, label );
00221     }
00222     else {
00223       const string nil ( "nil" );
00224       setAxisBinding ( i, nil );
00225     }
00226   }
00227   m_is_valid = true;
00228 }
00229 
00230 void NTupleProjector::setNTuple ( const DataSource * ntuple )
00231 {
00232   assert ( ntuple != 0 );
00233 
00234   if ( m_ntuple->isNull () ) {
00235     delete m_ntuple;
00236     m_ntuple = 0;
00237   }
00238 
00239   if ( m_ntuple != 0 ) {
00240     DataSource * nt = const_cast < DataSource * > ( m_ntuple );
00241     nt->removeObserver ( this );
00242   }
00243   m_ntuple = ntuple;
00244   changedNTuple();
00245   m_is_valid = true;
00246   setDirty ( true );
00247 }
00248 
00249 
00250 const string & NTupleProjector::getTitle() const
00251 {
00252   return m_ntuple->title();
00253 }
00254 
00255 const std::string & NTupleProjector::getXLabel() const
00256 {
00257   return m_ntuple->getLabelAt( m_columns[0] );
00258 }
00259 
00260 const string & NTupleProjector::getYLabel ( bool ) const
00261 {
00262   return m_ntuple->getLabelAt( m_columns[1] );
00263 }
00264 
00265 Range NTupleProjector::dataRangeWithError ( int data, int error ) const
00266 {
00267   assert ( !( data < 0 ) &&
00268            static_cast<size_t> ( data ) < m_ntuple->columns () );
00269   assert ( !( error < 0 ) &&
00270            static_cast<size_t> ( error ) < m_ntuple->columns () );
00271   
00272   double lo = DBL_MAX;
00273   double hi = DBL_MIN;
00274 
00275   unsigned int size = m_ntuple -> rows ();
00276   for ( unsigned int row = 0; row < size; row++ ) {
00277     double value = m_ntuple -> valueAt ( row, data );
00278     double err = m_ntuple -> valueAt ( row, error );
00279     lo = min ( value - err, lo );
00280     hi = max ( value + err, hi );
00281   }
00282 
00283   double pos = getPosWithError( data, error );
00284 
00285   return Range ( lo, hi, pos );
00286 }
00287 
00288 Range
00289 NTupleProjector::
00290 dataRange ( int column ) const
00291 {
00292   assert ( m_ntuple );
00293   assert ( !( column < 0 ) &&
00294            static_cast<size_t> (column) < m_ntuple->columns() );
00295 
00296   Range range;
00297   bool isValid = m_ntuple -> fillRange ( column, range );
00298   m_is_valid &= isValid;
00299 
00300   return range;
00301 }
00302 
00303 double NTupleProjector::getPosWithError ( int data, int error ) const
00304 {
00305   assert ( !( data < 0 ) &&
00306            static_cast<size_t> ( data ) < m_ntuple->columns () );
00307   assert ( !( error < 0 ) &&
00308            static_cast<size_t> ( error ) < m_ntuple->columns () );
00309   
00310   double pos = DBL_MAX;
00311  
00312   unsigned int size = m_ntuple -> rows ();
00313   for ( unsigned int row = 0; row < size; row++ ) {
00314     double value = m_ntuple -> valueAt ( row, data ); 
00315     double err   = m_ntuple -> valueAt ( row, error ); 
00316     if ( value > 0. ) {
00317       double x = value - err;
00318       if ( x > 0.0 ) {
00319         pos = min ( x, pos );
00320       }
00321       else {
00322         if ( value != 0.0 ) pos = min ( 0.1 * value, pos );
00323       }
00324     }
00325   }
00326 
00327   return pos;
00328 }
00329 
00330 double
00331 NTupleProjector::
00332 getPos ( int column ) const
00333 {
00334   assert ( m_ntuple );
00335   assert ( !( column < 0 ) &&
00336            static_cast<size_t> (column) < m_ntuple->columns() );
00337 
00338   double pos = DBL_MAX;
00339 
00340   unsigned int size = m_ntuple -> rows ();
00341 
00342   for ( unsigned int row = 0; row < size; row++ ) {
00343     double value = m_ntuple -> valueAt ( row, column );
00344     if ( value < pos && value > 0.0 ) pos = value;
00345   }
00346 
00347   return pos;
00348 }
00349 
00350 void NTupleProjector::addCut ( const TupleCut * cut )
00351 {
00352   m_cut_list.push_back ( cut );
00353 }
00354 
00355 void NTupleProjector::removeCut ( const TupleCut * cut )
00356 {
00357   CutList_t ::iterator first
00358     = find ( m_cut_list.begin(), m_cut_list.end(), cut );
00359   assert ( first != m_cut_list.end() );
00360 
00361   m_cut_list.erase ( first );
00362 }
00363 
00364 const vector < const TupleCut * > & NTupleProjector::getCutList () const
00365 {
00366   return m_cut_list;
00367 }
00368 
00369 int
00370 NTupleProjector::
00371 getNumberOfEntries () const
00372 {
00373   unsigned int size = m_ntuple->rows ();
00374   int number = 0;
00375   for ( unsigned int i = 0; i < size; i++ ) {
00376     if ( acceptRow ( i, m_cut_list ) && 
00377          inRange ( i ) )
00378       {
00379       number++;
00380       }
00381   }
00382 
00383   return number;
00384 }
00385 
00386 int
00387 NTupleProjector::
00388 getUnderflow () const
00389 {
00390   return -1;
00391 }
00392 
00393 int 
00394 NTupleProjector::
00395 getOverflow () const
00396 {
00397   return -1;
00398 }
00399 
00400 
00401 bool
00402 NTupleProjector::
00403 inRange ( int row ) const
00404 {
00405   unsigned int size = m_columns.size(); // number of bound columns
00406   bool yes = true;
00407   for ( unsigned int i = 0; i < size; i++ ) {
00408     if ( m_columns[i] == UINT_MAX ) break;
00409 
00410     AxisModelBase * axis_model = 0;
00411     if ( i == 0 ) axis_model = m_x_axis;
00412     else if ( i == 1 ) axis_model = m_y_axis;
00413     else if ( i == 2 ) axis_model = m_z_axis;
00414     if ( axis_model == 0 ) break;
00415 
00416     unsigned int column = m_columns[i]; 
00417     const Range & range = axis_model->getRange ( false );
00418     double value = m_ntuple -> valueAt ( row, column );
00419     if ( range.excludes ( value ) ) return false;
00420   }
00421 
00422   return yes;
00423 }
00424 
00427 const DataSource * 
00428 NTupleProjector::
00429 getNTuple () const
00430 {
00431   return  m_ntuple;
00432 }
00433 
00436 DataSource * 
00437 NTupleProjector::getNTuple ()
00438 {
00439   return const_cast < DataSource * > ( m_ntuple );
00440 }
00441 
00442 const string & NTupleProjector::getNTupleName () const
00443 {
00444   return m_ntuple->getName ();
00445 }
00446 
00447 double
00448 NTupleProjector::
00449 getAverage ( hippodraw::Axes::Type axis ) const
00450 {
00451 
00452   double sum = 0.0;
00453   double number = 0.0;
00454 
00455   string label = "";
00456   
00457   // Get the axis label.
00458   switch ( axis ) {
00459   case Axes::X:
00460     label = getXLabel();
00461     break;
00462   case Axes::Y:
00463     label = getYLabel();
00464     break;
00465   case Axes::Z:
00466     label = getZLabel();
00467     break;
00468   default:
00469     break;
00470   }
00471   
00472   // Get the NTuple for this NTupleProjector.
00473   const DataSource * tuple = getNTuple();
00474   if ( tuple -> empty () ) {
00475     return 0.0;
00476   }
00477   // Check if the label is valid for the NTuple.
00478 //   if(!tuple->isFilled(label)) return 0.0;
00479    
00480   // Get the column corresponding to the label.
00481   unsigned int column = tuple -> indexOf ( label );
00482   // Get the range of projected values.
00483   const Range & r = getRange ( axis );
00484     unsigned int size = m_ntuple -> rows ();
00485     for  ( unsigned int i = 0; i < size; i++ ) {
00486     // Check if row i is eliminated because of a cut.
00487     if ( !acceptRow ( i, m_cut_list ) )continue;
00488     double value = m_ntuple -> valueAt ( i, column );
00489     // Add the current value only if it is within the range.
00490     if ( r.includes ( value ) ) {
00491         sum += value;
00492         number ++;
00493     }
00494   
00495   }
00496 
00497   return (sum / number);
00498 }
00499 
00500 bool
00501 NTupleProjector::
00502 isEmpty () const
00503 {
00504   return m_ntuple -> empty ();
00505 }
00506 
00507 NTuple *
00508 NTupleProjector::
00509 createEmptyNTuple () const
00510 {
00511   unsigned int columns = m_ntuple->columns();
00512   
00513   NTuple * ntuple = new NTuple ( columns );
00514 
00515   const vector < string > & labels = m_ntuple->getLabels();
00516   ntuple->setLabels ( labels );
00517 
00518   unsigned int size = m_ntuple->rows();
00519   ntuple -> reserve ( size );
00520   return ntuple;
00521 }
00522 
00523 void
00524 NTupleProjector::
00525 fillNTuple ( NTuple * ntuple, const CutList_t & cut_list ) const
00526 {
00527    unsigned int size = m_ntuple->rows();
00528 
00529    for ( unsigned int i = 0; i < size; i++ ) {
00530      if ( acceptRow ( i, cut_list )  ) { //&& inRange(i) ) {
00531          const vector < double > & row = m_ntuple -> getRow ( i );
00532          ntuple -> addRow ( row );
00533       }
00534    }
00535 }
00536 
00537 NTuple * 
00538 NTupleProjector::
00539 getNTupleAfterCuts () const
00540 {
00541   NTuple * ntuple = createEmptyNTuple ();
00542   fillNTuple ( ntuple, m_cut_list );
00543 
00544   return ntuple;
00545 }
00546 
00547 void
00548 NTupleProjector::
00549 fillColumnAfterCuts(const std::string & column,
00550                     std::vector<double> & columnData) const {
00551 
00552    const std::vector<double> & coldata(m_ntuple->getColumn(column));
00553 
00554    size_t nrows = m_ntuple->rows();
00555    for ( size_t i = 0 ; i < nrows ; i++ ) {
00556       if ( acceptRow( i, m_cut_list ) ) {
00557          columnData.push_back( coldata[i] );
00558       }
00559    }
00560 }
00561 
00562 NTuple *
00563 NTupleProjector::
00564 createNTupleWith ( const std::vector < TupleCut > & tuple_cuts ) const
00565 {
00566   NTuple * ntuple = createEmptyNTuple ();
00567   vector < const TupleCut * > cut_list;
00568   for ( unsigned int i = 0; i < tuple_cuts.size(); i++ ) {
00569     const TupleCut & cut = tuple_cuts[i];
00570     cut_list.push_back ( & cut );
00571   }
00572   fillNTuple ( ntuple, cut_list );
00573 
00574   return ntuple;
00575 }
00576 
00577 bool
00578 NTupleProjector::
00579 isDataValid () const
00580 {
00581   return m_is_valid;
00582 }
00583 
00584 bool
00585 NTupleProjector::
00586 hasDataSourceBindings () const
00587 {
00588   return true;
00589 }

Generated for HippoDraw Class Library by doxygen