00001
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #else
00015 #ifdef _MSC_VER
00016 #include "msdevstudio/MSconfig.h"
00017 #endif
00018 #endif
00019
00020 #include "NTupleProjector.h"
00021
00022 #include "axes/AxisModelBase.h"
00023
00024 #include "datasrcs/NTuple.h"
00025 #include "datasrcs/DataSourceException.h"
00026 #include "datasrcs/TupleCut.h"
00027
00028 #include <algorithm>
00029 #include <functional>
00030
00031 using namespace hippodraw;
00032
00033 #ifdef ITERATOR_MEMBER_DEFECT
00034 using namespace std;
00035 #else
00036 using std::distance;
00037 using std::find;
00038 using std::max;
00039 using std::max_element;
00040 using std::min;
00041 using std::min_element;
00042 using std::string;
00043 using std::vector;
00044 #endif
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),
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 );
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 DataSourceException( 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
00160 {
00161
00162 bool accept = true;
00163
00164 if ( m_cut_list.empty() == false ) {
00165 unsigned int size = m_cut_list.size();
00166 unsigned int j = 0;
00167 while ( j < size ) {
00168 if ( m_cut_list[j++] -> acceptRow ( m_ntuple, i ) == false ) {
00169 accept = false;
00170 break;
00171 }
00172 }
00173 }
00174
00175 return accept;
00176 }
00177
00178 void
00179 NTupleProjector::
00180 setAxisBinding ( int axis, const std::string & label )
00181 {
00182 if ( label == "nil" ) {
00183 m_columns[axis] = UINT_MAX;
00184 }
00185 else {
00186 m_ntuple -> throwIfInvalidLabel ( label );
00187 int column = m_ntuple->indexOf ( label );
00188 m_columns[axis] = column;
00189 }
00190 m_is_valid = true;
00191 setDirty ( true );
00192 }
00193
00194 void NTupleProjector::setAxisBinding ( const std::string & axis,
00195 const std::string & label )
00196 {
00197 unsigned int index = indexOfBindingOption ( axis );
00198
00199 setAxisBinding ( index, label );
00200 }
00201
00202 void
00203 NTupleProjector::
00204 setAxisBindings ( const std::vector< std::string > & labels )
00205 {
00206 size_t size = labels.size();
00207
00208 if ( size < m_min_bindings ) {
00209 string what ( "NTupleProjector::setAxisBindings: " );
00210 what += "insufficient number of labels";
00211 throw DataSourceException ( what );
00212 }
00213
00214 size_t cols = m_columns.size ();
00215 for ( unsigned int i = 0; i < cols; i++ ) {
00216 if ( i < size ) {
00217 const string & label = labels[i];
00218 setAxisBinding ( i, label );
00219 }
00220 else {
00221 const string nil ( "nil" );
00222 setAxisBinding ( i, nil );
00223 }
00224 }
00225 m_is_valid = true;
00226 }
00227
00228 void NTupleProjector::setNTuple ( const DataSource * ntuple )
00229 {
00230 assert ( ntuple != 0 );
00231
00232 if ( m_ntuple->isNull () ) {
00233 delete m_ntuple;
00234 m_ntuple = 0;
00235 }
00236
00237 if ( m_ntuple != 0 ) {
00238 DataSource * nt = const_cast < DataSource * > ( m_ntuple );
00239 nt->removeObserver ( this );
00240 }
00241 m_ntuple = ntuple;
00242 changedNTuple();
00243 m_is_valid = true;
00244 setDirty ( true );
00245 }
00246
00247
00248 const string & NTupleProjector::getTitle() const
00249 {
00250 return m_ntuple->title();
00251 }
00252
00253 const std::string & NTupleProjector::getXLabel() const
00254 {
00255 return m_ntuple->getLabelAt( m_columns[0] );
00256 }
00257
00258 const string & NTupleProjector::getYLabel ( bool ) const
00259 {
00260 return m_ntuple->getLabelAt( m_columns[1] );
00261 }
00262
00263 Range NTupleProjector::dataRangeWithError ( int data, int error ) const
00264 {
00265 assert ( !( data < 0 ) &&
00266 static_cast<size_t> ( data ) < m_ntuple->columns () );
00267 assert ( !( error < 0 ) &&
00268 static_cast<size_t> ( error ) < m_ntuple->columns () );
00269
00270 double lo = DBL_MAX;
00271 double hi = DBL_MIN;
00272
00273 unsigned int size = m_ntuple -> rows ();
00274 for ( unsigned int row = 0; row < size; row++ ) {
00275 double value = m_ntuple -> valueAt ( row, data );
00276 double err = m_ntuple -> valueAt ( row, error );
00277 lo = min ( value - err, lo );
00278 hi = max ( value + err, hi );
00279 }
00280
00281 double pos = getPosWithError( data, error );
00282
00283 return Range ( lo, hi, pos );
00284 }
00285
00286 Range
00287 NTupleProjector::
00288 dataRange ( int column ) const
00289 {
00290 assert ( m_ntuple );
00291 assert ( !( column < 0 ) &&
00292 static_cast<size_t> (column) < m_ntuple->columns() );
00293
00294 Range range;
00295 bool isValid = m_ntuple -> fillRange ( column, range );
00296 m_is_valid &= isValid;
00297
00298 return range;
00299 }
00300
00301 double NTupleProjector::getPosWithError ( int data, int error ) const
00302 {
00303 assert ( !( data < 0 ) &&
00304 static_cast<size_t> ( data ) < m_ntuple->columns () );
00305 assert ( !( error < 0 ) &&
00306 static_cast<size_t> ( error ) < m_ntuple->columns () );
00307
00308 double pos = DBL_MAX;
00309
00310 unsigned int size = m_ntuple -> rows ();
00311 for ( unsigned int row = 0; row < size; row++ ) {
00312 double value = m_ntuple -> valueAt ( row, data );
00313 double err = m_ntuple -> valueAt ( row, error );
00314 if ( value > 0. ) {
00315 double x = value - err;
00316 if ( x > 0.0 ) {
00317 pos = min ( x, pos );
00318 }
00319 else {
00320 if ( value != 0.0 ) pos = min ( 0.1 * value, pos );
00321 }
00322 }
00323 }
00324
00325 return pos;
00326 }
00327
00328 double
00329 NTupleProjector::
00330 getPos ( int column ) const
00331 {
00332 assert ( m_ntuple );
00333 assert ( !( column < 0 ) &&
00334 static_cast<size_t> (column) < m_ntuple->columns() );
00335
00336 double pos = DBL_MAX;
00337
00338 unsigned int size = m_ntuple -> rows ();
00339
00340 for ( unsigned int row = 0; row < size; row++ ) {
00341 double value = m_ntuple -> valueAt ( row, column );
00342 if ( value < pos && value > 0.0 ) pos = value;
00343 }
00344
00345 return pos;
00346 }
00347
00348 void NTupleProjector::addCut ( const TupleCut * cut )
00349 {
00350 m_cut_list.push_back ( cut );
00351 }
00352
00353 void NTupleProjector::removeCut ( const TupleCut * cut )
00354 {
00355 vector < const TupleCut * > :: iterator first
00356 = find ( m_cut_list.begin(), m_cut_list.end(), cut );
00357 assert ( first != m_cut_list.end() );
00358
00359 m_cut_list.erase ( first );
00360 }
00361
00362 const vector < const TupleCut * > & NTupleProjector::getCutList () const
00363 {
00364 return m_cut_list;
00365 }
00366
00367 int
00368 NTupleProjector::
00369 getNumberOfEntries () const
00370 {
00371 unsigned int size = m_ntuple->rows ();
00372 int number = 0;
00373 for ( unsigned int i = 0; i < size; i++ ) {
00374 if ( acceptRow ( i ) &&
00375 inRange ( i ) )
00376 {
00377 number++;
00378 }
00379 }
00380
00381 return number;
00382 }
00383
00384 bool
00385 NTupleProjector::
00386 inRange ( int row ) const
00387 {
00388 unsigned int size = m_columns.size();
00389 bool yes = true;
00390 for ( unsigned int i = 0; i < size; i++ ) {
00391 if ( m_columns[i] == UINT_MAX ) break;
00392
00393 AxisModelBase * axis_model = 0;
00394 if ( i == 0 ) axis_model = m_x_axis;
00395 else if ( i == 1 ) axis_model = m_y_axis;
00396 else if ( i == 2 ) axis_model = m_z_axis;
00397 if ( axis_model == 0 ) break;
00398
00399 unsigned int column = m_columns[i];
00400 const Range & range = axis_model->getRange ( false );
00401 double value = m_ntuple -> valueAt ( row, column );
00402 if ( range.excludes ( value ) ) return false;
00403 }
00404
00405 return yes;
00406 }
00407
00410 const DataSource *
00411 NTupleProjector::
00412 getNTuple () const
00413 {
00414 return m_ntuple;
00415 }
00416
00419 DataSource *
00420 NTupleProjector::getNTuple ()
00421 {
00422 return const_cast < DataSource * > ( m_ntuple );
00423 }
00424
00425 const string & NTupleProjector::getNTupleName () const
00426 {
00427 return m_ntuple->getName ();
00428 }
00429
00430 double
00431 NTupleProjector::
00432 getAverage ( hippodraw::Axes::Type axis ) const
00433 {
00434
00435 double sum = 0.0;
00436 double number = 0.0;
00437
00438 string label = "";
00439
00440
00441 switch ( axis ) {
00442 case Axes::X:
00443 label = getXLabel();
00444 break;
00445 case Axes::Y:
00446 label = getYLabel();
00447 break;
00448 case Axes::Z:
00449 label = getZLabel();
00450 break;
00451 default:
00452 break;
00453 }
00454
00455
00456 const DataSource * tuple = getNTuple();
00457 if ( tuple -> empty () ) {
00458 return 0.0;
00459 }
00460
00461
00462
00463
00464 unsigned int column = tuple -> indexOf ( label );
00465
00466 const Range & r = getRange ( axis );
00467 unsigned int size = m_ntuple -> rows ();
00468 for ( unsigned int i = 0; i < size; i++ ) {
00469
00470 if ( !acceptRow ( i ) )continue;
00471 double value = m_ntuple -> valueAt ( i, column );
00472
00473 if ( r.includes ( value ) ) {
00474 sum += value;
00475 number ++;
00476 }
00477
00478 }
00479
00480 return (sum / number);
00481 }
00482
00483 bool
00484 NTupleProjector::
00485 isEmpty () const
00486 {
00487 return m_ntuple -> empty ();
00488 }
00489
00490 NTuple *
00491 NTupleProjector::
00492 getNTupleAfterCuts () const
00493 {
00494 unsigned int columns = m_ntuple->columns();
00495
00496 NTuple * ntuple = new NTuple ( columns );
00497
00498 const vector < string > & labels = m_ntuple->getLabels();
00499 ntuple->setLabels ( labels );
00500
00501 unsigned int size = m_ntuple->rows();
00502 ntuple -> reserve ( size );
00503
00504 for ( unsigned int i = 0; i < size; i++ ) {
00505 if (acceptRow(i) ) {
00506 const vector < double > & row = m_ntuple -> getRow ( i );
00507 ntuple -> addRow ( row );
00508 }
00509 }
00510
00511 return ntuple;
00512 }
00513
00514 bool
00515 NTupleProjector::
00516 isDataValid () const
00517 {
00518 return m_is_valid;
00519 }