00001 #include "AIDA_Histogram3D.h"
00002 #include "EvenBinAxis.h"
00003 #include "VariableBinAxis.h"
00004 #include "GravityBin3D.h"
00005 #include "AIDA/IAnnotation.h"
00006 #include <typeinfo>
00007 #include <cmath>
00008 #include <set>
00009 #include "AnnotationNumberFormater.h"
00010
00011
00012 static const unsigned int numberOfExtraBins = 2;
00013 static const std::string meanXKey = "MeanX";
00014 static const std::string rmsXKey = "RmsX";
00015 static const std::string meanYKey = "MeanY";
00016 static const std::string rmsYKey = "RmsY";
00017 static const std::string meanZKey = "MeanZ";
00018 static const std::string rmsZKey = "RmsZ";
00019 static const std::string extra_entriesKey = "Extra Entries";
00020 static const std::string emptyString = "";
00021
00022
00023 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::AIDA_Histogram3D( const std::string& title,
00024 int numberOfBinsX,
00025 double lowEdgeX,
00026 double highEdgeX,
00027 int numberOfBinsY,
00028 double lowEdgeY,
00029 double highEdgeY,
00030 int numberOfBinsZ,
00031 double lowEdgeZ,
00032 double highEdgeZ ):
00033 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram3D", 3 ),
00034 m_axisX( new EvenBinAxis( std::abs( numberOfBinsX ), lowEdgeX, highEdgeX ) ),
00035 m_axisY( new EvenBinAxis( std::abs( numberOfBinsY ), lowEdgeY, highEdgeY ) ),
00036 m_axisZ( new EvenBinAxis( std::abs( numberOfBinsZ ), lowEdgeZ, highEdgeZ ) ),
00037 m_bins( std::abs( numberOfBinsX ) + numberOfExtraBins, std::vector< std::vector< GravityBin3D* > >( std::abs( numberOfBinsY ) + numberOfExtraBins, std::vector< GravityBin3D* >( std::abs( numberOfBinsZ ) + numberOfExtraBins, 0 ) ) ),
00038 m_validStatistics( false )
00039 {
00040 m_sumWeightTimesSquaredX = 0;
00041 m_sumWeightTimesSquaredY = 0;
00042 m_sumWeightTimesSquaredZ = 0;
00043 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00044 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00045 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00046 m_bins[i][j][k] = new Anaphe::AIDA_Histogram_native::GravityBin3D;
00047
00049 AIDA::IAnnotation& annotation = annotationNoUpdate();
00050 annotation.addItem( meanXKey, emptyString, false );
00051 annotation.addItem( rmsXKey, emptyString, false );
00052 annotation.addItem( meanYKey, emptyString, false );
00053 annotation.addItem( rmsYKey, emptyString, false );
00054 annotation.addItem( meanZKey, emptyString, false );
00055 annotation.addItem( rmsZKey, emptyString, false );
00056 annotation.addItem( extra_entriesKey, emptyString, false );
00057 }
00058
00059 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::AIDA_Histogram3D( const std::string& title,
00060 const std::vector< double >& edgesX,
00061 const std::vector< double >& edgesY,
00062 const std::vector< double >& edgesZ ):
00063 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram3D", 3 ),
00064 m_axisX( new VariableBinAxis( edgesX ) ),
00065 m_axisY( new VariableBinAxis( edgesY ) ),
00066 m_axisZ( new VariableBinAxis( edgesZ ) ),
00067 m_bins( edgesX.size() - 1 + numberOfExtraBins, std::vector< std::vector< GravityBin3D* > >( edgesY.size() - 1 + numberOfExtraBins, std::vector< GravityBin3D* >( edgesZ.size() - 1 + numberOfExtraBins, 0 ) ) ),
00068 m_validStatistics( false )
00069 {
00070 m_sumWeightTimesSquaredX = 0;
00071 m_sumWeightTimesSquaredY = 0;
00072 m_sumWeightTimesSquaredZ = 0;
00073 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00074 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00075 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00076 m_bins[i][j][k] = new Anaphe::AIDA_Histogram_native::GravityBin3D;
00077
00079 AIDA::IAnnotation& annotation = annotationNoUpdate();
00080 annotation.addItem( meanXKey, emptyString, false );
00081 annotation.addItem( rmsXKey, emptyString, false );
00082 annotation.addItem( meanYKey, emptyString, false );
00083 annotation.addItem( rmsYKey, emptyString, false );
00084 annotation.addItem( meanZKey, emptyString, false );
00085 annotation.addItem( rmsZKey, emptyString, false );
00086 annotation.addItem( extra_entriesKey, emptyString, false );
00087 }
00088
00089
00090 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::AIDA_Histogram3D( const Anaphe::AIDA_Histogram_native::AIDA_Histogram3D& h ):
00091 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram3D", 3 ),
00092 m_axisX( 0 ),
00093 m_axisY( 0 ),
00094 m_axisZ( 0 ),
00095 m_bins( h.m_bins.size(), std::vector< std::vector< GravityBin3D* > >( h.m_bins[0].size(), std::vector< GravityBin3D* >( h.m_bins[0][0].size(), 0 ) ) ),
00096 m_validStatistics( false )
00097 {
00098
00099 const AIDA::IAxis& otherAxisX = h.xAxis();
00100 if ( otherAxisX.isFixedBinning() ) {
00101 m_axisX = new EvenBinAxis( otherAxisX.bins(),
00102 otherAxisX.lowerEdge(),
00103 otherAxisX.upperEdge() );
00104 }
00105 else {
00106 std::vector< double > edges( otherAxisX.bins() + 1 );
00107 for ( int i = 0; i < otherAxisX.bins(); ++i ) edges[i] = otherAxisX.binLowerEdge( i );
00108 edges.back() = otherAxisX.upperEdge();
00109 m_axisX = new VariableBinAxis( edges );
00110 };
00111 const AIDA::IAxis& otherAxisY = h.yAxis();
00112 if ( otherAxisY.isFixedBinning() ) {
00113 m_axisY = new EvenBinAxis( otherAxisY.bins(),
00114 otherAxisY.lowerEdge(),
00115 otherAxisY.upperEdge() );
00116 }
00117 else {
00118 std::vector< double > edges( otherAxisY.bins() + 1 );
00119 for ( int i = 0; i < otherAxisY.bins(); ++i ) edges[i] = otherAxisY.binLowerEdge( i );
00120 edges.back() = otherAxisY.upperEdge();
00121 m_axisY = new VariableBinAxis( edges );
00122 };
00123 const AIDA::IAxis& otherAxisZ = h.zAxis();
00124 if ( otherAxisZ.isFixedBinning() ) {
00125 m_axisZ = new EvenBinAxis( otherAxisZ.bins(),
00126 otherAxisZ.lowerEdge(),
00127 otherAxisZ.upperEdge() );
00128 }
00129 else {
00130 std::vector< double > edges( otherAxisZ.bins() + 1 );
00131 for ( int i = 0; i < otherAxisZ.bins(); ++i ) edges[i] = otherAxisZ.binLowerEdge( i );
00132 edges.back() = otherAxisZ.upperEdge();
00133 m_axisZ = new VariableBinAxis( edges );
00134 }
00135
00136
00137 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00138 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00139 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00140 m_bins[i][j][k] = new GravityBin3D( *( h.m_bins[i][j][k] ) );
00141 setRms( h.rmsX(), h.rmsY(), h.rmsZ() );
00142
00144 AIDA::IAnnotation& annotation = annotationNoUpdate();
00145 std::set< std::string > existingAnnotationItems;
00146 for ( int item = 0; item < annotation.size(); ++item ) {
00147 existingAnnotationItems.insert( annotation.key( item ) );
00148 }
00149 const AIDA::IAnnotation& otherAnnotation = h.annotation();
00150 for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00151 const std::string& key = otherAnnotation.key( itemNew );
00152 if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00153 annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00154 }
00155 }
00156
00157 }
00158
00159
00160 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::AIDA_Histogram3D( const AIDA::IHistogram3D& h ):
00161 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram3D", 3 ),
00162 m_axisX( 0 ),
00163 m_axisY( 0 ),
00164 m_axisZ( 0 ),
00165 m_bins( h.xAxis().bins() + numberOfExtraBins, std::vector< std::vector< GravityBin3D* > >( h.yAxis().bins() + numberOfExtraBins, std::vector< GravityBin3D* >( h.zAxis().bins() + numberOfExtraBins, 0 ) ) ),
00166 m_validStatistics( false )
00167 {
00168
00169 const AIDA::IAxis& otherAxisX = h.xAxis();
00170 if ( otherAxisX.isFixedBinning() ) {
00171 m_axisX = new EvenBinAxis( otherAxisX.bins(),
00172 otherAxisX.lowerEdge(),
00173 otherAxisX.upperEdge() );
00174 }
00175 else {
00176 std::vector< double > edges( otherAxisX.bins() + 1 );
00177 for ( int i = 0; i < otherAxisX.bins(); ++i ) edges[i] = otherAxisX.binLowerEdge( i );
00178 edges.back() = otherAxisX.upperEdge();
00179 m_axisX = new VariableBinAxis( edges );
00180 };
00181 const AIDA::IAxis& otherAxisY = h.yAxis();
00182 if ( otherAxisY.isFixedBinning() ) {
00183 m_axisY = new EvenBinAxis( otherAxisY.bins(),
00184 otherAxisY.lowerEdge(),
00185 otherAxisY.upperEdge() );
00186 }
00187 else {
00188 std::vector< double > edges( otherAxisY.bins() + 1 );
00189 for ( int i = 0; i < otherAxisY.bins(); ++i ) edges[i] = otherAxisY.binLowerEdge( i );
00190 edges.back() = otherAxisY.upperEdge();
00191 m_axisY = new VariableBinAxis( edges );
00192 };
00193 const AIDA::IAxis& otherAxisZ = h.zAxis();
00194 if ( otherAxisZ.isFixedBinning() ) {
00195 m_axisZ = new EvenBinAxis( otherAxisZ.bins(),
00196 otherAxisZ.lowerEdge(),
00197 otherAxisZ.upperEdge() );
00198 }
00199 else {
00200 std::vector< double > edges( otherAxisZ.bins() + 1 );
00201 for ( int i = 0; i < otherAxisZ.bins(); ++i ) edges[i] = otherAxisZ.binLowerEdge( i );
00202 edges.back() = otherAxisZ.upperEdge();
00203 m_axisZ = new VariableBinAxis( edges );
00204 }
00205
00206
00207 for ( unsigned int iBin = 0; iBin < m_bins.size(); ++iBin ) {
00208 for ( unsigned int jBin = 0; jBin < m_bins[0].size(); ++jBin ) {
00209 for ( unsigned int kBin = 0; kBin < m_bins[0][0].size(); ++kBin ) {
00210 m_bins[iBin][jBin][kBin]->set( h.binEntries( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ),
00211 h.binHeight( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ),
00212 h.binError( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ),
00213 h.binMeanX( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ),
00214 h.binMeanY( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ),
00215 h.binMeanZ( iBin - numberOfExtraBins, jBin - numberOfExtraBins, kBin - numberOfExtraBins ) );
00216 }
00217 }
00218 }
00219
00220 setRms( h.rmsX(), h.rmsY(), h.rmsZ() );
00221
00223 AIDA::IAnnotation& annotation = annotationNoUpdate();
00224 std::set< std::string > existingAnnotationItems;
00225 for ( int item = 0; item < annotation.size(); ++item ) {
00226 existingAnnotationItems.insert( annotation.key( item ) );
00227 }
00228 const AIDA::IAnnotation& otherAnnotation = h.annotation();
00229 for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00230 const std::string& key = otherAnnotation.key( itemNew );
00231 if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00232 annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00233 }
00234 }
00235
00236 }
00237
00238
00239 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::~AIDA_Histogram3D()
00240 {
00241 if ( m_axisX ) delete m_axisX;
00242 if ( m_axisY ) delete m_axisY;
00243 if ( m_axisZ ) delete m_axisZ;
00244 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00245 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00246 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00247 if ( m_bins[i][j][k] ) delete m_bins[i][j][k];
00248 }
00249 }
00250
00251
00252 bool
00253 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::reset()
00254 {
00255 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00256 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00257 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00258 m_bins[i][j][k]->reset();
00259 m_sumWeightTimesSquaredX = m_sumWeightTimesSquaredY = m_sumWeightTimesSquaredZ = 0;
00260 setUpToDate( false );
00261 m_validStatistics = false;
00262 return true;
00263 }
00264
00265
00266 int
00267 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::entries() const
00268 {
00269 calculateStatistics();
00270 return m_entries;
00271 }
00272
00273
00274 int
00275 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::allEntries() const
00276 {
00277 return ( entries() + extraEntries() );
00278 }
00279
00280
00281 int
00282 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::extraEntries() const
00283 {
00284 calculateStatistics();
00285 return m_extraEntries;
00286 }
00287
00288
00289 void
00290 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::updateAnnotation() const
00291 {
00292 Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram::updateAnnotation();
00293 const AIDA::IAnnotation& anno = annotationNoUpdate();
00294 AIDA::IAnnotation& annotation = const_cast< AIDA::IAnnotation& >( anno );
00295
00296 annotation.setValue( meanXKey, anaphe_annotationNumberFormater.formatDouble( meanX() ) );
00297 annotation.setValue( rmsXKey, anaphe_annotationNumberFormater.formatDouble( rmsX() ) );
00298 annotation.setValue( meanYKey, anaphe_annotationNumberFormater.formatDouble( meanY() ) );
00299 annotation.setValue( rmsYKey, anaphe_annotationNumberFormater.formatDouble( rmsY() ) );
00300 annotation.setValue( meanZKey, anaphe_annotationNumberFormater.formatDouble( meanZ() ) );
00301 annotation.setValue( rmsZKey, anaphe_annotationNumberFormater.formatDouble( rmsZ() ) );
00302 annotation.setValue( extra_entriesKey, anaphe_annotationNumberFormater.formatInteger( extraEntries() ) );
00303 }
00304
00305
00306 double
00307 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::equivalentBinEntries() const
00308 {
00309 calculateStatistics();
00310 return m_ebe;
00311 }
00312
00313
00314 double
00315 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::sumBinHeights() const
00316 {
00317 calculateStatistics();
00318 return m_sumBinHeights;
00319 }
00320
00321
00322 double
00323 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::sumExtraBinHeights() const
00324 {
00325 calculateStatistics();
00326 return m_sumExtraBinHeights;
00327 }
00328
00329
00330 double
00331 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::sumAllBinHeights() const
00332 {
00333 return ( sumBinHeights() + sumExtraBinHeights() );
00334 }
00335
00336
00337 double
00338 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::minBinHeight() const
00339 {
00340 calculateStatistics();
00341 return m_minHeight;
00342 }
00343
00344
00345 double
00346 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::maxBinHeight() const
00347 {
00348 calculateStatistics();
00349 return m_maxHeight;
00350 }
00351
00352
00353 bool
00354 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::scale( double scaleFactor )
00355 {
00356 for ( unsigned int i = 0; i < m_bins.size(); ++i )
00357 for ( unsigned int j = 0; j < m_bins[0].size(); ++j )
00358 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k )
00359 m_bins[i][j][k]->scale( scaleFactor );
00360 m_sumWeightTimesSquaredX *= scaleFactor;
00361 m_sumWeightTimesSquaredY *= scaleFactor;
00362 m_sumWeightTimesSquaredZ *= scaleFactor;
00363 setUpToDate( false );
00364 m_validStatistics = false;
00365 return true;
00366 }
00367
00368
00369 bool
00370 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::fill( double x, double y, double z, double weight )
00371 {
00372 const int binIndexX = m_axisX->coordToIndex( x );
00373 const int binIndexY = m_axisY->coordToIndex( y );
00374 const int binIndexZ = m_axisZ->coordToIndex( z );
00375 m_bins[binIndexX + numberOfExtraBins][binIndexY + numberOfExtraBins][binIndexZ + numberOfExtraBins]->fill( weight, x, y, z );
00376 if ( binIndexX >= 0 && binIndexY >= 0 && binIndexZ >= 0 ) {
00377 m_sumWeightTimesSquaredX += weight * x * x;
00378 m_sumWeightTimesSquaredY += weight * y * y;
00379 m_sumWeightTimesSquaredZ += weight * z * z;
00380 }
00381 setUpToDate( false );
00382 m_validStatistics = false;
00383 return true;
00384 }
00385
00386
00387 double
00388 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binMeanX( int indexX, int indexY, int indexZ ) const
00389 {
00390 unsigned int realIndexX = indexX + numberOfExtraBins;
00391 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00392 unsigned int realIndexY = indexY + numberOfExtraBins;
00393 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00394 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00395 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00396
00397 const GravityBin3D& bin = *( m_bins[ realIndexX ][ realIndexY ][ realIndexZ ] );
00398 return bin.centreOfGravityX();
00399 }
00400
00401
00402 double
00403 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binMeanY( int indexX, int indexY, int indexZ ) const
00404 {
00405 unsigned int realIndexX = indexX + numberOfExtraBins;
00406 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00407 unsigned int realIndexY = indexY + numberOfExtraBins;
00408 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00409 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00410 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00411
00412 const GravityBin3D& bin = *( m_bins[ realIndexX ][ realIndexY ][ realIndexZ ] );
00413 return bin.centreOfGravityY();
00414 }
00415
00416
00417 double
00418 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binMeanZ( int indexX, int indexY, int indexZ ) const
00419 {
00420 unsigned int realIndexX = indexX + numberOfExtraBins;
00421 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00422 unsigned int realIndexY = indexY + numberOfExtraBins;
00423 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00424 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00425 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00426
00427 const GravityBin3D& bin = *( m_bins[ realIndexX ][ realIndexY ][ realIndexZ ] );
00428 return bin.centreOfGravityZ();
00429 }
00430
00431
00432 int
00433 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binEntries( int indexX, int indexY, int indexZ ) const
00434 {
00435 unsigned int realIndexX = indexX + numberOfExtraBins;
00436 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00437 unsigned int realIndexY = indexY + numberOfExtraBins;
00438 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00439 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00440 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00441 return m_bins[realIndexX][realIndexY][realIndexZ]->entries();
00442 }
00443
00444
00445 int
00446 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binEntriesX( int index ) const
00447 {
00448 unsigned int realIndex = index + numberOfExtraBins;
00449 if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00450 int e = 0;
00451 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00452 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00453 const GravityBin3D& bin = *( m_bins[ realIndex ][j][k] );
00454 e += bin.entries();
00455 }
00456 }
00457 return e;
00458 }
00459
00460
00461 int
00462 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binEntriesY( int index ) const
00463 {
00464 unsigned int realIndex = index + numberOfExtraBins;
00465 if ( realIndex < 0 || realIndex>= m_bins[0].size() ) return 0;
00466 int e = 0;
00467 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00468 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00469 const GravityBin3D& bin = *( m_bins[j][ realIndex ][k] );
00470 e += bin.entries();
00471 }
00472 }
00473 return e;
00474 }
00475
00476
00477 int
00478 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binEntriesZ( int index ) const
00479 {
00480 unsigned int realIndex = index + numberOfExtraBins;
00481 if ( realIndex < 0 || realIndex>= m_bins[0][0].size() ) return 0;
00482 int e = 0;
00483 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00484 for ( unsigned int k = 0; k < m_bins[0].size(); ++k ) {
00485 const GravityBin3D& bin = *( m_bins[j][k][realIndex] );
00486 e += bin.entries();
00487 }
00488 }
00489 return e;
00490 }
00491
00492
00493 double
00494 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binHeight( int indexX, int indexY, int indexZ ) const
00495 {
00496 unsigned int realIndexX = indexX + numberOfExtraBins;
00497 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00498 unsigned int realIndexY = indexY + numberOfExtraBins;
00499 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00500 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00501 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00502 return m_bins[realIndexX][realIndexY][realIndexZ]->height();
00503 }
00504
00505
00506 double
00507 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binHeightX( int index ) const
00508 {
00509 unsigned int realIndex = index + numberOfExtraBins;
00510 if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00511 double e = 0;
00512 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00513 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00514 const GravityBin3D& bin = *( m_bins[ realIndex ][j][k] );
00515 e += bin.height();
00516 }
00517 }
00518 return e;
00519 }
00520
00521
00522 double
00523 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binHeightY( int index ) const
00524 {
00525 unsigned int realIndex = index + numberOfExtraBins;
00526 if ( realIndex < 0 || realIndex>= m_bins[0].size() ) return 0;
00527 double e = 0;
00528 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00529 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00530 const GravityBin3D& bin = *( m_bins[j][ realIndex ][k] );
00531 e += bin.height();
00532 }
00533 }
00534 return e;
00535 }
00536
00537
00538 double
00539 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binHeightZ( int index ) const
00540 {
00541 unsigned int realIndex = index + numberOfExtraBins;
00542 if ( realIndex < 0 || realIndex>= m_bins[0][0].size() ) return 0;
00543 double e = 0;
00544 for ( unsigned int j = 0; j < m_bins.size(); ++j ) {
00545 for ( unsigned int k = 0; k < m_bins[0].size(); ++k ) {
00546 const GravityBin3D& bin = *( m_bins[j][k][ realIndex ] );
00547 e += bin.height();
00548 }
00549 }
00550 return e;
00551 }
00552
00553
00554 double
00555 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::binError( int indexX, int indexY, int indexZ ) const
00556 {
00557 unsigned int realIndexX = indexX + numberOfExtraBins;
00558 if ( realIndexX < 0 || realIndexX>= m_bins.size() ) return 0;
00559 unsigned int realIndexY = indexY + numberOfExtraBins;
00560 if ( realIndexY < 0 || realIndexY>= m_bins[0].size() ) return 0;
00561 unsigned int realIndexZ = indexZ + numberOfExtraBins;
00562 if ( realIndexZ < 0 || realIndexZ>= m_bins[0][0].size() ) return 0;
00563 return m_bins[realIndexX][realIndexY][realIndexZ]->error();
00564 }
00565
00566
00567 double
00568 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::meanX() const
00569 {
00570 calculateStatistics();
00571 return m_meanX;
00572 }
00573
00574
00575 double
00576 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::rmsX() const
00577 {
00578 calculateStatistics();
00579 return m_rmsX;
00580 }
00581
00582
00583 double
00584 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::meanY() const
00585 {
00586 calculateStatistics();
00587 return m_meanY;
00588 }
00589
00590
00591 double
00592 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::rmsY() const
00593 {
00594 calculateStatistics();
00595 return m_rmsY;
00596 }
00597
00598
00599 double
00600 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::meanZ() const
00601 {
00602 calculateStatistics();
00603 return m_meanZ;
00604 }
00605
00606
00607 double
00608 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::rmsZ() const
00609 {
00610 calculateStatistics();
00611 return m_rmsZ;
00612 }
00613
00614
00615 bool
00616 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::calculateStatistics() const
00617 {
00618 if ( m_validStatistics ) return true;
00619
00620
00621 m_sumBinHeights = 0;
00622 double sww = 0;
00623 double swx = 0;
00624 double swy = 0;
00625 double swz = 0;
00626 m_entries = 0;
00627 m_sumExtraBinHeights = 0;
00628 m_extraEntries = 0;
00629 m_maxHeight = m_minHeight = m_bins[numberOfExtraBins][numberOfExtraBins][numberOfExtraBins]->height();
00630 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00631 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00632 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00633 const GravityBin3D& bin = *( m_bins[i][j][k] );
00634 if ( i < numberOfExtraBins || j < numberOfExtraBins || k < numberOfExtraBins ) {
00635 m_extraEntries += bin.entries();
00636 m_sumExtraBinHeights += bin.height();
00637 }
00638 else {
00639 const double binMeanX = bin.centreOfGravityX();
00640 const double binMeanY = bin.centreOfGravityY();
00641 const double binMeanZ = bin.centreOfGravityZ();
00642 const double binHeight = bin.height();
00643 const double binErrorSquared = bin.errorSquared();
00644 m_entries += bin.entries();
00645 m_sumBinHeights += binHeight;
00646 sww += binErrorSquared;
00647 swx += binMeanX * binHeight;
00648 swy += binMeanY * binHeight;
00649 swz += binMeanZ * binHeight;
00650 if ( m_maxHeight < binHeight ) m_maxHeight = binHeight;
00651 if ( m_minHeight > binHeight ) m_minHeight = binHeight;
00652 }
00653 }
00654 }
00655 }
00656
00657 if ( m_sumBinHeights == 0 ) {
00658 m_meanX = m_rmsX = m_meanY = m_rmsY = m_meanZ = m_rmsZ = 0;
00659 }
00660 else {
00661 m_meanX = swx / m_sumBinHeights;
00662 m_rmsX = std::sqrt( std::abs( m_sumWeightTimesSquaredX / m_sumBinHeights - m_meanX * m_meanX ) );
00663 m_meanY = swy / m_sumBinHeights;
00664 m_rmsY = std::sqrt( std::abs( m_sumWeightTimesSquaredY / m_sumBinHeights - m_meanY * m_meanY ) );
00665 m_meanZ = swz / m_sumBinHeights;
00666 m_rmsZ = std::sqrt( std::abs( m_sumWeightTimesSquaredZ / m_sumBinHeights - m_meanZ * m_meanZ ) );
00667 }
00668
00669 if ( sww ) {
00670 m_ebe = m_sumBinHeights * m_sumBinHeights / sww;
00671 }
00672 else {
00673 m_ebe = 0;
00674 }
00675
00676
00677 m_validStatistics = true;
00678 return m_validStatistics;
00679 }
00680
00681
00682
00683 const AIDA::IAxis&
00684 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::xAxis() const
00685 {
00686 return *m_axisX;
00687 }
00688
00689 const AIDA::IAxis&
00690 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::yAxis() const
00691 {
00692 return *m_axisY;
00693 }
00694
00695
00696 const AIDA::IAxis&
00697 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::zAxis() const
00698 {
00699 return *m_axisZ;
00700 }
00701
00702
00703 int
00704 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::coordToIndexX( double coord ) const
00705 {
00706 return m_axisX->coordToIndex( coord );
00707 }
00708
00709
00710 int
00711 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::coordToIndexY( double coord ) const
00712 {
00713 return m_axisY->coordToIndex( coord );
00714 }
00715
00716
00717 int
00718 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::coordToIndexZ( double coord ) const
00719 {
00720 return m_axisZ->coordToIndex( coord );
00721 }
00722
00723
00724 bool
00725 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::add( const AIDA::IHistogram3D & h )
00726 {
00727
00728 const AIDA::IAxis& otherAxisX = h.xAxis();
00729 const AIDA::IAxis& myAxisX = *m_axisX;
00730 if ( otherAxisX.bins() != myAxisX.bins() ) return false;
00731 for ( int iBin = 0; iBin < myAxisX.bins(); ++iBin ) {
00732 const double otherLowEdge = otherAxisX.binLowerEdge( iBin );
00733 const double myLowEdge = myAxisX.binLowerEdge( iBin );
00734 if ( otherLowEdge != myLowEdge ) return false;
00735 }
00736 if ( otherAxisX.upperEdge() != myAxisX.upperEdge() ) return false;
00737
00738 const AIDA::IAxis& otherAxisY = h.yAxis();
00739 const AIDA::IAxis& myAxisY = *m_axisY;
00740 if ( otherAxisY.bins() != myAxisY.bins() ) return false;
00741 for ( int iBin = 0; iBin < myAxisY.bins(); ++iBin ) {
00742 const double otherLowEdge = otherAxisY.binLowerEdge( iBin );
00743 const double myLowEdge = myAxisY.binLowerEdge( iBin );
00744 if ( otherLowEdge != myLowEdge ) return false;
00745 }
00746 if ( otherAxisY.upperEdge() != myAxisY.upperEdge() ) return false;
00747
00748 const AIDA::IAxis& otherAxisZ = h.zAxis();
00749 const AIDA::IAxis& myAxisZ = *m_axisZ;
00750 if ( otherAxisZ.bins() != myAxisZ.bins() ) return false;
00751 for ( int iBin = 0; iBin < myAxisZ.bins(); ++iBin ) {
00752 const double otherLowEdge = otherAxisZ.binLowerEdge( iBin );
00753 const double myLowEdge = myAxisZ.binLowerEdge( iBin );
00754 if ( otherLowEdge != myLowEdge ) return false;
00755 }
00756 if ( otherAxisZ.upperEdge() != myAxisZ.upperEdge() ) return false;
00757
00758
00759
00760
00761
00762 try {
00763 const Anaphe::AIDA_Histogram_native::AIDA_Histogram3D& other = dynamic_cast<const Anaphe::AIDA_Histogram_native::AIDA_Histogram3D&>( h );
00764 return increment( other );
00765 }
00766 catch( std::bad_cast ) {
00767 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D * transformed = new Anaphe::AIDA_Histogram_native::AIDA_Histogram3D( h );
00768 bool ret = increment( *transformed );
00769 delete transformed;
00770 return ret;
00771 }
00772 }
00773
00774
00775 bool
00776 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::increment( const AIDA_Histogram3D& h )
00777 {
00778 for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00779 for ( unsigned int j = 0; j < m_bins[0].size(); ++j ) {
00780 for ( unsigned int k = 0; k < m_bins[0][0].size(); ++k ) {
00781 m_bins[i][j][k]->increment( *( h.m_bins[i][j][k] ) );
00782 }
00783 }
00784 }
00785 m_sumWeightTimesSquaredX += h.m_sumWeightTimesSquaredX;
00786 m_sumWeightTimesSquaredY += h.m_sumWeightTimesSquaredY;
00787 m_sumWeightTimesSquaredZ += h.m_sumWeightTimesSquaredZ;
00788 setUpToDate( false );
00789 m_validStatistics = false;
00790 return true;
00791 }
00792
00793
00794 bool
00795 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::setBinContents( int binIndexX,
00796 int binIndexY,
00797 int binIndexZ,
00798 int entries,
00799 double height,
00800 double error,
00801 double centreX,
00802 double centreY,
00803 double centreZ )
00804 {
00805 unsigned int realIndexX = binIndexX + numberOfExtraBins;
00806 if ( realIndexX < 0 || realIndexX >= m_bins.size() ) return false;
00807 unsigned int realIndexY = binIndexY + numberOfExtraBins;
00808 if ( realIndexY < 0 || realIndexY >= m_bins[0].size() ) return false;
00809 unsigned int realIndexZ = binIndexZ + numberOfExtraBins;
00810 if ( realIndexZ < 0 || realIndexZ >= m_bins[0][0].size() ) return false;
00811 setUpToDate( false );
00812 m_validStatistics = false;
00813 return m_bins[realIndexX][realIndexY][realIndexZ]->set( entries, height, error, centreX, centreY, centreZ );
00814 }
00815
00816
00817 bool
00818 Anaphe::AIDA_Histogram_native::AIDA_Histogram3D::setRms( double rmsX, double rmsY, double rmsZ )
00819 {
00820 const double sw = sumBinHeights();
00821 const double mnX = meanX();
00822 m_sumWeightTimesSquaredX = ( mnX*mnX + rmsX*rmsX) * sw;
00823 const double mnY = meanY();
00824 m_sumWeightTimesSquaredY = ( mnY*mnY + rmsY*rmsY) * sw;
00825 const double mnZ = meanZ();
00826 m_sumWeightTimesSquaredZ = ( mnZ*mnZ + rmsZ*rmsZ) * sw;
00827 m_validStatistics = false;
00828 return true;
00829 }