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

Generated for HippoDraw Class Library by doxygen