00001 #include "AIDA_Histogram2D.h"
00002 #include "EvenBinAxis.h"
00003 #include "VariableBinAxis.h"
00004 #include "GravityBin2D.h"
00005 #include "AIDA/IAnnotation.h"
00006 #include <typeinfo>
00007 #include <cmath>
00008 #include <set>
00009 #include "AnnotationNumberFormater.h"
00010
00011 static const unsigned int numberOfExtraBins = 2;
00012 static const std::string meanXKey = "MeanX";
00013 static const std::string rmsXKey = "RmsX";
00014 static const std::string meanYKey = "MeanY";
00015 static const std::string rmsYKey = "RmsY";
00016 static const std::string extra_entriesKey = "Extra Entries";
00017 static const std::string emptyString = "";
00018
00019
00020 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::AIDA_Histogram2D( const std::string& title,
00021 int numberOfBinsX,
00022 double lowEdgeX,
00023 double highEdgeX,
00024 int numberOfBinsY,
00025 double lowEdgeY,
00026 double highEdgeY ):
00027 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram2D", 2 ),
00028 m_axisX( new EvenBinAxis( std::abs( numberOfBinsX ), lowEdgeX, highEdgeX ) ),
00029 m_axisY( new EvenBinAxis( std::abs( numberOfBinsY ), lowEdgeY, highEdgeY ) ),
00030 m_bins( std::abs( numberOfBinsX ) + numberOfExtraBins, std::vector< GravityBin2D* >( std::abs( numberOfBinsY ) + numberOfExtraBins, 0 ) ),
00031 m_validStatistics( false )
00032 {
00033 m_sumWeightTimesSquaredX = 0;
00034 m_sumWeightTimesSquaredY = 0;
00035
00036 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00037 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00038 m_bins[i][j] = new Anaphe::AIDA_Histogram_native::GravityBin2D;
00039
00041 AIDA::IAnnotation& annotation = annotationNoUpdate();
00042 annotation.addItem( meanXKey, emptyString, false );
00043 annotation.addItem( rmsXKey, emptyString, false );
00044 annotation.addItem( meanYKey, emptyString, false );
00045 annotation.addItem( rmsYKey, emptyString, false );
00046 annotation.addItem( extra_entriesKey, emptyString, false );
00047 }
00048
00049 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::AIDA_Histogram2D( const std::string& title,
00050 const std::vector< double >& edgesX,
00051 const std::vector< double >& edgesY ):
00052 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram2D", 2 ),
00053 m_axisX( new VariableBinAxis( edgesX ) ),
00054 m_axisY( new VariableBinAxis( edgesY ) ),
00055 m_bins( edgesX.size() - 1 + numberOfExtraBins, std::vector< GravityBin2D* >( edgesY.size() - 1 + numberOfExtraBins, 0 ) ),
00056 m_validStatistics( false )
00057 {
00058 m_sumWeightTimesSquaredX = 0;
00059 m_sumWeightTimesSquaredY = 0;
00060
00061 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00062 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00063 m_bins[i][j] = new Anaphe::AIDA_Histogram_native::GravityBin2D;
00064
00066 AIDA::IAnnotation& annotation = annotationNoUpdate();
00067 annotation.addItem( meanXKey, emptyString, false );
00068 annotation.addItem( rmsXKey, emptyString, false );
00069 annotation.addItem( meanYKey, emptyString, false );
00070 annotation.addItem( rmsYKey, emptyString, false );
00071 annotation.addItem( extra_entriesKey, emptyString, false );
00072 }
00073
00074
00075 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::AIDA_Histogram2D( const Anaphe::AIDA_Histogram_native::AIDA_Histogram2D& h ):
00076 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram2D", 2 ),
00077 m_axisX( 0 ),
00078 m_axisY( 0 ),
00079 m_bins( h.m_bins.size(), std::vector< GravityBin2D* >( h.m_bins[0].size(), 0 ) ),
00080 m_validStatistics( false )
00081 {
00082 m_sumWeightTimesSquaredX = 0;
00083 m_sumWeightTimesSquaredY = 0;
00084
00085
00086 const AIDA::IAxis& otherAxisX = h.xAxis();
00087 if ( otherAxisX.isFixedBinning() ) {
00088 m_axisX = new EvenBinAxis( otherAxisX.bins(),
00089 otherAxisX.lowerEdge(),
00090 otherAxisX.upperEdge() );
00091 }
00092 else {
00093 std::vector< double > edges( otherAxisX.bins() + 1 );
00094 for ( int i = 0; i < otherAxisX.bins(); ++i ) edges[i] = otherAxisX.binLowerEdge( i );
00095 edges.back() = otherAxisX.upperEdge();
00096 m_axisX = new VariableBinAxis( edges );
00097 };
00098 const AIDA::IAxis& otherAxisY = h.yAxis();
00099 if ( otherAxisY.isFixedBinning() ) {
00100 m_axisY = new EvenBinAxis( otherAxisY.bins(),
00101 otherAxisY.lowerEdge(),
00102 otherAxisY.upperEdge() );
00103 }
00104 else {
00105 std::vector< double > edges( otherAxisY.bins() + 1 );
00106 for ( int i = 0; i < otherAxisY.bins(); ++i ) edges[i] = otherAxisY.binLowerEdge( i );
00107 edges.back() = otherAxisY.upperEdge();
00108 m_axisY = new VariableBinAxis( edges );
00109 }
00110
00111
00112 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00113 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00114 m_bins[i][j] = new GravityBin2D( *( h.m_bins[i][j] ) );
00115 setRms( h.rmsX(), h.rmsY() );
00116
00118 AIDA::IAnnotation& annotation = annotationNoUpdate();
00119 std::set< std::string > existingAnnotationItems;
00120 for ( int item = 0; item < annotation.size(); ++item ) {
00121 existingAnnotationItems.insert( annotation.key( item ) );
00122 }
00123 const AIDA::IAnnotation& otherAnnotation = h.annotation();
00124 for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00125 const std::string& key = otherAnnotation.key( itemNew );
00126 if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00127 annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00128 }
00129 }
00130
00131 }
00132
00133
00134 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::AIDA_Histogram2D( const AIDA::IHistogram2D& h ):
00135 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram2D", 2 ),
00136 m_axisX( 0 ),
00137 m_axisY( 0 ),
00138 m_bins( h.xAxis().bins() + numberOfExtraBins, std::vector< GravityBin2D* >( h.yAxis().bins() + numberOfExtraBins, 0 ) ),
00139 m_validStatistics( false )
00140 {
00141
00142 const AIDA::IAxis& otherAxisX = h.xAxis();
00143 if ( otherAxisX.isFixedBinning() ) {
00144 m_axisX = new EvenBinAxis( otherAxisX.bins(),
00145 otherAxisX.lowerEdge(),
00146 otherAxisX.upperEdge() );
00147 }
00148 else {
00149 std::vector< double > edges( otherAxisX.bins() + 1 );
00150 for ( int i = 0; i < otherAxisX.bins(); ++i ) edges[i] = otherAxisX.binLowerEdge( i );
00151 edges.back() = otherAxisX.upperEdge();
00152 m_axisX = new VariableBinAxis( edges );
00153 };
00154 const AIDA::IAxis& otherAxisY = h.yAxis();
00155 if ( otherAxisY.isFixedBinning() ) {
00156 m_axisY = new EvenBinAxis( otherAxisY.bins(),
00157 otherAxisY.lowerEdge(),
00158 otherAxisY.upperEdge() );
00159 }
00160 else {
00161 std::vector< double > edges( otherAxisY.bins() + 1 );
00162 for ( int i = 0; i < otherAxisY.bins(); ++i ) edges[i] = otherAxisY.binLowerEdge( i );
00163 edges.back() = otherAxisY.upperEdge();
00164 m_axisY = new VariableBinAxis( edges );
00165 }
00166
00167
00168 for ( unsigned int iBin = 0; iBin < m_bins.size(); ++iBin ) {
00169 for ( unsigned int jBin = 0; jBin < m_bins[0].size(); ++jBin ) {
00170 m_bins[iBin][jBin]->set( h.binEntries( iBin - numberOfExtraBins, jBin - numberOfExtraBins ),
00171 h.binHeight( iBin - numberOfExtraBins, jBin - numberOfExtraBins ),
00172 h.binError( iBin - numberOfExtraBins, jBin - numberOfExtraBins ),
00173 h.binMeanX( iBin - numberOfExtraBins, jBin - numberOfExtraBins ),
00174 h.binMeanY( iBin - numberOfExtraBins, jBin - numberOfExtraBins ) );
00175 }
00176 }
00177 setRms( h.rmsX(), h.rmsY() );
00178
00180 AIDA::IAnnotation& annotation = annotationNoUpdate();
00181 std::set< std::string > existingAnnotationItems;
00182 for ( int item = 0; item < annotation.size(); ++item ) {
00183 existingAnnotationItems.insert( annotation.key( item ) );
00184 }
00185 const AIDA::IAnnotation& otherAnnotation = h.annotation();
00186 for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00187 const std::string& key = otherAnnotation.key( itemNew );
00188 if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00189 annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00190 }
00191 }
00192
00193 }
00194
00195
00196 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::~AIDA_Histogram2D()
00197 {
00198 if ( m_axisX ) delete m_axisX;
00199 if ( m_axisY ) delete m_axisY;
00200 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00201 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00202 if ( m_bins[i][j] ) delete m_bins[i][j];
00203 }
00204 }
00205
00206
00207 bool
00208 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::reset()
00209 {
00210 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00211 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00212 m_bins[i][j]->reset();
00213 m_sumWeightTimesSquaredX = m_sumWeightTimesSquaredY = 0;
00214 setUpToDate( false );
00215 m_validStatistics = false;
00216 return true;
00217 }
00218
00219
00220 int
00221 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::entries() const
00222 {
00223 calculateStatistics();
00224 return m_entries;
00225 }
00226
00227
00228 int
00229 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::allEntries() const
00230 {
00231 return ( entries() + extraEntries() );
00232 }
00233
00234
00235 int
00236 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::extraEntries() const
00237 {
00238 calculateStatistics();
00239 return m_extraEntries;
00240 }
00241
00242
00243 void
00244 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::updateAnnotation() const
00245 {
00246 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram::updateAnnotation();
00247 const AIDA::IAnnotation& anno = annotationNoUpdate();
00248 AIDA::IAnnotation& annotation = const_cast< AIDA::IAnnotation& >( anno );
00249
00250 annotation.setValue( meanXKey, anaphe_annotationNumberFormater.formatDouble( meanX() ) );
00251 annotation.setValue( rmsXKey, anaphe_annotationNumberFormater.formatDouble( rmsX() ) );
00252 annotation.setValue( meanYKey, anaphe_annotationNumberFormater.formatDouble( meanY() ) );
00253 annotation.setValue( rmsYKey, anaphe_annotationNumberFormater.formatDouble( rmsY() ) );
00254 annotation.setValue( extra_entriesKey, anaphe_annotationNumberFormater.formatInteger( extraEntries() ) );
00255 }
00256
00257
00258 double
00259 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::equivalentBinEntries() const
00260 {
00261 calculateStatistics();
00262 return m_ebe;
00263 }
00264
00265
00266 double
00267 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::sumBinHeights() const
00268 {
00269 calculateStatistics();
00270 return m_sumBinHeights;
00271 }
00272
00273
00274 double
00275 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::sumExtraBinHeights() const
00276 {
00277 calculateStatistics();
00278 return m_sumExtraBinHeights;
00279 }
00280
00281
00282 double
00283 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::sumAllBinHeights() const
00284 {
00285 return ( sumBinHeights() + sumExtraBinHeights() );
00286 }
00287
00288
00289 double
00290 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::minBinHeight() const
00291 {
00292 calculateStatistics();
00293 return m_minHeight;
00294 }
00295
00296
00297 double
00298 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::maxBinHeight() const
00299 {
00300 calculateStatistics();
00301 return m_maxHeight;
00302 }
00303
00304
00305 bool
00306 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::scale( double scaleFactor )
00307 {
00308 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00309 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00310 m_bins[i][j]->scale( scaleFactor );
00311 m_sumWeightTimesSquaredX *= scaleFactor;
00312 m_sumWeightTimesSquaredY *= scaleFactor;
00313 setUpToDate( false );
00314 m_validStatistics = false;
00315 return true;
00316 }
00317
00318
00319 bool
00320 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::fill( double x, double y, double weight )
00321 {
00322 const int binIndexX = m_axisX->coordToIndex( x );
00323 const int binIndexY = m_axisY->coordToIndex( y );
00324 m_bins[binIndexX + numberOfExtraBins][binIndexY + numberOfExtraBins]->fill( weight, x, y );
00325 if ( binIndexX >= 0 && binIndexY >= 0 ) {
00326 m_sumWeightTimesSquaredX += weight * x * x;
00327 m_sumWeightTimesSquaredY += weight * y * y;
00328 }
00329 setUpToDate( false );
00330 m_validStatistics = false;
00331 return true;
00332 }
00333
00334
00335 double
00336 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binMeanX( int indexX, int indexY ) const
00337 {
00338 unsigned int realIndexX = indexX + numberOfExtraBins;
00339 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00340 unsigned int realIndexY = indexY + numberOfExtraBins;
00341 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00342
00343 const GravityBin2D& bin = *( m_bins[ realIndexX ][ realIndexY ] );
00344 return bin.centreOfGravityX();
00345 }
00346
00347
00348 double
00349 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binMeanY( int indexX, int indexY ) const
00350 {
00351 unsigned int realIndexX = indexX + numberOfExtraBins;
00352 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00353 unsigned int realIndexY = indexY + numberOfExtraBins;
00354 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00355
00356 const GravityBin2D& bin = *( m_bins[ realIndexX ][ realIndexY ] );
00357 return bin.centreOfGravityY();
00358 }
00359
00360
00361 int
00362 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binEntries( int indexX, int indexY ) const
00363 {
00364 unsigned int realIndexX = indexX + numberOfExtraBins;
00365 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00366 unsigned int realIndexY = indexY + numberOfExtraBins;
00367 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00368 return m_bins[realIndexX][realIndexY]->entries();
00369 }
00370
00371
00372 int
00373 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binEntriesX( int index ) const
00374 {
00375 unsigned int realIndex = index + numberOfExtraBins;
00376 if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00377 int e = 0;
00378 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00379 const GravityBin2D& bin = *( m_bins[ realIndex ][j] );
00380 e += bin.entries();
00381 }
00382 return e;
00383 }
00384
00385
00386 int
00387 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binEntriesY( int index ) const
00388 {
00389 unsigned int realIndex = index + numberOfExtraBins;
00390 if ( realIndex < 0 || realIndex>= m_bins[0].size() ) return 0;
00391 int e = 0;
00392 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00393 const GravityBin2D& bin = *( m_bins[j][ realIndex ] );
00394 e += bin.entries();
00395 }
00396 return e;
00397 }
00398
00399
00400 double
00401 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binHeight( int indexX, int indexY ) const
00402 {
00403 unsigned int realIndexX = indexX + numberOfExtraBins;
00404 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00405 unsigned int realIndexY = indexY + numberOfExtraBins;
00406 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00407 return m_bins[realIndexX][realIndexY]->height();
00408 }
00409
00410
00411 double
00412 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binHeightX( int index ) const
00413 {
00414 unsigned int realIndex = index + numberOfExtraBins;
00415 if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00416 double e = 0;
00417 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00418 const GravityBin2D& bin = *( m_bins[ realIndex ][j] );
00419 e += bin.height();
00420 }
00421 return e;
00422 }
00423
00424
00425 double
00426 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binHeightY( int index ) const
00427 {
00428 unsigned int realIndex = index + numberOfExtraBins;
00429 if ( realIndex < 0 || realIndex>= m_bins[0].size() ) return 0;
00430 double e = 0;
00431 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00432 const GravityBin2D& bin = *( m_bins[j][ realIndex ] );
00433 e += bin.height();
00434 }
00435 return e;
00436 }
00437
00438
00439 double
00440 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::binError( int indexX, int indexY ) const
00441 {
00442 unsigned int realIndexX = indexX + numberOfExtraBins;
00443 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00444 unsigned int realIndexY = indexY + numberOfExtraBins;
00445 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00446 return m_bins[realIndexX][realIndexY]->error();
00447 }
00448
00449
00450 double
00451 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::meanX() const
00452 {
00453 calculateStatistics();
00454 return m_meanX;
00455 }
00456
00457
00458 double
00459 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::rmsX() const
00460 {
00461 calculateStatistics();
00462 return m_rmsX;
00463 }
00464
00465
00466 double
00467 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::meanY() const
00468 {
00469 calculateStatistics();
00470 return m_meanY;
00471 }
00472
00473
00474 double
00475 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::rmsY() const
00476 {
00477 calculateStatistics();
00478 return m_rmsY;
00479 }
00480
00481
00482 bool
00483 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::calculateStatistics() const
00484 {
00485 if ( m_validStatistics ) return true;
00486
00487
00488 m_sumBinHeights = 0;
00489 double sww = 0;
00490 double swx = 0;
00491 double swy = 0;
00492 m_entries = 0;
00493 m_sumExtraBinHeights = 0;
00494 m_extraEntries = 0;
00495 m_maxHeight = m_minHeight = m_bins[numberOfExtraBins][numberOfExtraBins]->height();
00496 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00497 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00498 const GravityBin2D& bin = *( m_bins[i][j] );
00499 if ( i < numberOfExtraBins || j < numberOfExtraBins ) {
00500 m_extraEntries += bin.entries();
00501 m_sumExtraBinHeights += bin.height();
00502 }
00503 else {
00504 const double binMeanX = bin.centreOfGravityX();
00505 const double binMeanY = bin.centreOfGravityY();
00506 const double binHeight = bin.height();
00507 const double binErrorSquared = bin.errorSquared();
00508 m_entries += bin.entries();
00509 m_sumBinHeights += binHeight;
00510 sww += binErrorSquared;
00511 swx += binMeanX * binHeight;
00512 swy += binMeanY * binHeight;
00513 if ( m_maxHeight < binHeight ) m_maxHeight = binHeight;
00514 if ( m_minHeight > binHeight ) m_minHeight = binHeight;
00515 }
00516 }
00517 }
00518
00519 if ( m_sumBinHeights == 0 ) {
00520 m_meanX = m_rmsX = m_meanY = m_rmsY = 0;
00521 }
00522 else {
00523 m_meanX = swx / m_sumBinHeights;
00524 m_rmsX = std::sqrt( std::abs( m_sumWeightTimesSquaredX / m_sumBinHeights - m_meanX * m_meanX ) );
00525 m_meanY = swy / m_sumBinHeights;
00526 m_rmsY = std::sqrt( std::abs( m_sumWeightTimesSquaredY / m_sumBinHeights - m_meanY * m_meanY ) );
00527 }
00528
00529 if ( sww ) {
00530 m_ebe = m_sumBinHeights * m_sumBinHeights / sww;
00531 }
00532 else {
00533 m_ebe = 0;
00534 }
00535
00536
00537 m_validStatistics = true;
00538 return m_validStatistics;
00539 }
00540
00541
00542
00543 const AIDA::IAxis&
00544 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::xAxis() const
00545 {
00546 return *m_axisX;
00547 }
00548
00549 const AIDA::IAxis&
00550 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::yAxis() const
00551 {
00552 return *m_axisY;
00553 }
00554
00555
00556 int
00557 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::coordToIndexX( double coord ) const
00558 {
00559 return m_axisX->coordToIndex( coord );
00560 }
00561
00562
00563 int
00564 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::coordToIndexY( double coord ) const
00565 {
00566 return m_axisY->coordToIndex( coord );
00567 }
00568
00569
00570 bool
00571 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::add( const AIDA::IHistogram2D & h )
00572 {
00573
00574 const AIDA::IAxis& otherAxisX = h.xAxis();
00575 const AIDA::IAxis& myAxisX = *m_axisX;
00576 if ( otherAxisX.bins() != myAxisX.bins() ) return false;
00577 for ( int iBin = 0; iBin < myAxisX.bins(); ++iBin ) {
00578 const double otherLowEdge = otherAxisX.binLowerEdge( iBin );
00579 const double myLowEdge = myAxisX.binLowerEdge( iBin );
00580 if ( otherLowEdge != myLowEdge ) return false;
00581 }
00582 if ( otherAxisX.upperEdge() != myAxisX.upperEdge() ) return false;
00583
00584 const AIDA::IAxis& otherAxisY = h.yAxis();
00585 const AIDA::IAxis& myAxisY = *m_axisY;
00586 if ( otherAxisY.bins() != myAxisY.bins() ) return false;
00587 for ( int iBin = 0; iBin < myAxisY.bins(); ++iBin ) {
00588 const double otherLowEdge = otherAxisY.binLowerEdge( iBin );
00589 const double myLowEdge = myAxisY.binLowerEdge( iBin );
00590 if ( otherLowEdge != myLowEdge ) return false;
00591 }
00592 if ( otherAxisY.upperEdge() != myAxisY.upperEdge() ) return false;
00593
00594
00595
00596
00597
00598 try {
00599 const Anaphe::AIDA_Histogram_native::AIDA_Histogram2D& other = dynamic_cast<const Anaphe::AIDA_Histogram_native::AIDA_Histogram2D&>( h );
00600 return increment( other );
00601 }
00602 catch( std::bad_cast ) {
00603 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D * transformed = new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( h );
00604 bool ret = increment( *transformed );
00605 delete transformed;
00606 return ret;
00607 }
00608 }
00609
00610
00611 bool
00612 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::increment( const AIDA_Histogram2D& h )
00613 {
00614 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00615 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00616 m_bins[i][j]->increment( *( h.m_bins[i][j] ) );
00617 }
00618 }
00619 m_sumWeightTimesSquaredX += h.m_sumWeightTimesSquaredX;
00620 m_sumWeightTimesSquaredY += h.m_sumWeightTimesSquaredY;
00621 setUpToDate( false );
00622 m_validStatistics = false;
00623 return true;
00624 }
00625
00626
00627 bool
00628 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::setBinContents( int binIndexX,
00629 int binIndexY,
00630 int entries,
00631 double height,
00632 double error,
00633 double centreX,
00634 double centreY )
00635 {
00636 unsigned int realIndexX = binIndexX + numberOfExtraBins;
00637 if ( realIndexX < 0 || realIndexX >= m_bins.size() ) return false;
00638 unsigned int realIndexY = binIndexY + numberOfExtraBins;
00639 if ( realIndexY < 0 || realIndexY >= m_bins[0].size() ) return false;
00640 setUpToDate( false );
00641 m_validStatistics = false;
00642 return m_bins[ realIndexX ][realIndexY]->set( entries, height, error, centreX, centreY );
00643 }
00644
00645
00646 bool
00647 Anaphe::AIDA_Histogram_native::AIDA_Histogram2D::setRms( double rmsX, double rmsY )
00648 {
00649 const double sw = sumBinHeights();
00650 const double mnX = meanX();
00651 const double mnY = meanY();
00652 m_sumWeightTimesSquaredX = ( mnX*mnX + rmsX*rmsX) * sw;
00653 m_sumWeightTimesSquaredY = ( mnY*mnY + rmsY*rmsY) * sw;
00654 m_validStatistics = false;
00655 return true;
00656 }