Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

AIDA_Histogram1D.cpp

Go to the documentation of this file.
00001 #include "AIDA_Histogram1D.h"
00002 #include "EvenBinAxis.h"
00003 #include "VariableBinAxis.h"
00004 #include "GravityBin1D.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 meanKey = "Mean";
00013 static const std::string rmsKey = "Rms";
00014 static const std::string extra_entriesKey = "Extra Entries";
00015 static const std::string overflowKey = "Overflow";
00016 static const std::string underflowKey = "Underflow";
00017 static const std::string emptyString = "";
00018 
00019 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::AIDA_Histogram1D( const std::string& title,
00020                                                                    int numberOfBins,
00021                                                                    double lowEdge,
00022                                                                    double highEdge ):
00023   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram1D", 1 ),
00024   m_axis( new EvenBinAxis( std::abs( numberOfBins ), lowEdge, highEdge ) ),
00025   m_bins( std::abs( numberOfBins ) + numberOfExtraBins ),
00026   m_validStatistics( false )
00027 {
00028   m_sumWeightTimesSquaredX = 0;
00029   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[ i ] = new Anaphe::AIDA_Histogram_native::GravityBin1D;
00030 
00032   AIDA::IAnnotation& annotation = annotationNoUpdate();
00033   annotation.addItem( meanKey, emptyString, false );
00034   annotation.addItem( rmsKey, emptyString, false );
00035   annotation.addItem( extra_entriesKey, emptyString, false );
00036   annotation.addItem( overflowKey, emptyString, false );
00037   annotation.addItem( underflowKey, emptyString, false );
00038 }
00039 
00040 
00041 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::AIDA_Histogram1D( const std::string& title,
00042                                                                    const std::vector< double >& edges ):
00043   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "IHistogram1D", 1 ),
00044   m_axis( new VariableBinAxis( edges ) ),
00045   m_bins( edges.size() - 1 + numberOfExtraBins ),
00046   m_validStatistics( false )
00047 {
00048   m_sumWeightTimesSquaredX = 0;
00049   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[ i ] = new Anaphe::AIDA_Histogram_native::GravityBin1D;
00050 
00052   AIDA::IAnnotation& annotation = annotationNoUpdate();
00053   annotation.addItem( meanKey, emptyString, false );
00054   annotation.addItem( rmsKey, emptyString, false );
00055   annotation.addItem( extra_entriesKey, emptyString, false );
00056   annotation.addItem( overflowKey, emptyString, false );
00057   annotation.addItem( underflowKey, emptyString, false );
00058 }
00059 
00060 
00061 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::AIDA_Histogram1D( const Anaphe::AIDA_Histogram_native::AIDA_Histogram1D& h ):
00062   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram1D", 1 ),
00063   m_axis( 0 ),
00064   m_bins( h.m_bins.size() ),
00065   m_validStatistics( false )
00066 {
00067   m_sumWeightTimesSquaredX = 0;
00068 
00069   // Construct the axis first
00070   const AIDA::IAxis& otherAxis = h.axis();
00071   if ( otherAxis.isFixedBinning() ) {
00072     m_axis = new EvenBinAxis( otherAxis.bins(),
00073                               otherAxis.lowerEdge(),
00074                               otherAxis.upperEdge() );
00075   }
00076   else {
00077     std::vector< double > edges( otherAxis.bins() + 1);
00078     for ( int i = 0; i < otherAxis.bins(); ++i ) edges[i] = otherAxis.binLowerEdge( i );
00079     edges.back() = otherAxis.upperEdge();
00080     m_axis = new VariableBinAxis( edges );
00081   }
00082 
00083   // Copy the bin contents
00084   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[i] = new GravityBin1D( *( h.m_bins[i] ) );
00085   setRms( h.rms() );
00086 
00088   AIDA::IAnnotation& annotation = annotationNoUpdate();
00089   std::set< std::string > existingAnnotationItems;
00090   for ( int item = 0; item < annotation.size(); ++item ) {
00091       existingAnnotationItems.insert( annotation.key( item ) );
00092   }
00093   const AIDA::IAnnotation& otherAnnotation = h.annotation();
00094   for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00095       const std::string& key = otherAnnotation.key( itemNew );
00096       if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00097           annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00098       }
00099   }
00100 }
00101 
00102 
00103 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::AIDA_Histogram1D( const AIDA::IHistogram1D& h ):
00104   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "IHistogram1D", 1 ),
00105   m_axis( 0 ),
00106   m_bins( h.axis().bins() + numberOfExtraBins ),
00107   m_validStatistics( false )
00108 {
00109   m_sumWeightTimesSquaredX = 0;
00110 
00111   // Construct the axis first
00112   const AIDA::IAxis& otherAxis = h.axis();
00113   if ( h.axis().isFixedBinning() ) {
00114     m_axis = new EvenBinAxis( otherAxis.bins(),
00115                               otherAxis.lowerEdge(),
00116                               otherAxis.upperEdge() );
00117   }
00118   else {
00119     std::vector< double > edges( otherAxis.bins() + 1);
00120     for ( int i = 0; i < otherAxis.bins(); ++i ) edges[i] = otherAxis.binLowerEdge( i );
00121     edges.back() = otherAxis.upperEdge();
00122     m_axis = new VariableBinAxis( edges );
00123   }
00124 
00125   // Create the bins
00126   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[i] = new GravityBin1D;
00127 
00128   // Copy the in-range bin contents
00129   for ( unsigned int iBin = numberOfExtraBins; iBin < m_bins.size(); ++iBin ) {
00130     m_bins[iBin]->set( h.binEntries( iBin - numberOfExtraBins ),
00131                        h.binHeight( iBin - numberOfExtraBins ),
00132                        h.binError( iBin - numberOfExtraBins ),
00133                        h.binMean( iBin - numberOfExtraBins ) );
00134   }
00135 
00136   // Underflow bin:
00137   const int underFlowBin = static_cast< int >( AIDA::IAxis::UNDERFLOW_BIN );
00138   m_bins[ underFlowBin ]->set( h.binEntries( underFlowBin ),
00139                                h.binHeight( underFlowBin ),
00140                                h.binError( underFlowBin ),
00141                                h.binMean( underFlowBin ) );
00142   // Overflow bin:
00143   const int overFlowBin = static_cast< int >( AIDA::IAxis::OVERFLOW_BIN );
00144   m_bins[ underFlowBin ]->set( h.binEntries( overFlowBin ),
00145                                h.binHeight( overFlowBin ),
00146                                h.binError( overFlowBin ),
00147                                h.binMean( overFlowBin ) );
00148   setRms( h.rms() );
00149 
00151   AIDA::IAnnotation& annotation = annotationNoUpdate();
00152   std::set< std::string > existingAnnotationItems;
00153   for ( int item = 0; item < annotation.size(); ++item ) {
00154       existingAnnotationItems.insert( annotation.key( item ) );
00155   }
00156   const AIDA::IAnnotation& otherAnnotation = h.annotation();
00157   for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00158       const std::string& key = otherAnnotation.key( itemNew );
00159       if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00160           annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00161       }
00162   }
00163 }
00164 
00165 
00166 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::~AIDA_Histogram1D()
00167 {
00168   if ( m_axis ) delete m_axis;
00169   for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00170     if ( m_bins[ i ] ) delete m_bins[ i ];
00171   }
00172 }
00173 
00174 
00175 bool
00176 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::reset()
00177 {
00178   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[ i ]->reset();
00179   m_sumWeightTimesSquaredX = 0;
00180   m_validStatistics = false;
00181   setUpToDate( false );
00182   return true;
00183 }
00184 
00185 
00186 int
00187 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::entries() const
00188 {
00189   calculateStatistics();
00190   return m_entries;
00191 }
00192 
00193 
00194 int
00195 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::allEntries() const
00196 {
00197   return ( entries() + extraEntries() );
00198 }
00199 
00200 
00201 int
00202 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::extraEntries() const
00203 {
00204   calculateStatistics();
00205   return m_extraEntries;
00206 }
00207 
00208 
00209 void
00210 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::updateAnnotation() const
00211 {
00212   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram::updateAnnotation();
00213   const AIDA::IAnnotation& anno = annotationNoUpdate();
00214   AIDA::IAnnotation& annotation = const_cast< AIDA::IAnnotation& >( anno );
00215 
00216   annotation.setValue( meanKey, anaphe_annotationNumberFormater.formatDouble( mean() ) );
00217   annotation.setValue( rmsKey, anaphe_annotationNumberFormater.formatDouble( rms() ) );
00218   annotation.setValue( extra_entriesKey, anaphe_annotationNumberFormater.formatInteger( extraEntries() ) );
00219   annotation.setValue( underflowKey, anaphe_annotationNumberFormater.formatInteger( m_bins[numberOfExtraBins + AIDA::IAxis::UNDERFLOW_BIN]->entries() ) );
00220   annotation.setValue( overflowKey, anaphe_annotationNumberFormater.formatInteger( m_bins[numberOfExtraBins + AIDA::IAxis::OVERFLOW_BIN]->entries() ) );
00221 }
00222 
00223 
00224 double
00225 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::equivalentBinEntries() const
00226 {
00227   calculateStatistics();
00228   return m_ebe;
00229 }
00230 
00231 
00232 double
00233 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::sumBinHeights() const
00234 {
00235   calculateStatistics();
00236   return m_sumBinHeights;
00237 }
00238 
00239 
00240 double
00241 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::sumExtraBinHeights() const
00242 {
00243   calculateStatistics();
00244   return m_sumExtraBinHeights;
00245 }
00246 
00247 
00248 double
00249 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::sumAllBinHeights() const
00250 {
00251   return ( sumBinHeights() + sumExtraBinHeights() );
00252 }
00253 
00254 
00255 double
00256 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::minBinHeight() const
00257 {
00258   calculateStatistics();
00259   return m_minHeight;
00260 }
00261 
00262 
00263 double
00264 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::maxBinHeight() const
00265 {
00266   calculateStatistics();
00267   return m_maxHeight;
00268 }
00269 
00270 
00271 bool
00272 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::scale( double scaleFactor )
00273 {
00274   for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[ i ]->scale( scaleFactor );  
00275   m_sumWeightTimesSquaredX *= scaleFactor;
00276   setUpToDate( false );
00277   m_validStatistics = false;
00278   return true;
00279 }
00280 
00281 
00282 bool
00283 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::fill( double x, double weight )
00284 {
00285   const int binIndex = m_axis->coordToIndex( x );
00286   m_bins[binIndex + numberOfExtraBins]->fill( weight, x );
00287   if ( binIndex >= 0 ) m_sumWeightTimesSquaredX += weight * x * x;
00288   setUpToDate( false );  
00289   m_validStatistics = false;
00290   return true;
00291 }
00292 
00293 
00294 double
00295 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::binMean( int index ) const
00296 {
00297   unsigned int realIndex = index + numberOfExtraBins;
00298   if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00299   const Anaphe::AIDA_Histogram_native::GravityBin1D& bin = * ( m_bins[ realIndex ] );
00300   if ( bin.entries() == 0 ) {
00301     return m_axis->binLowerEdge( index ) + 0.5 * m_axis->binWidth( index );
00302   }
00303   else return bin.centreOfGravityX();
00304 }
00305 
00306 
00307 int
00308 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::binEntries( int index ) const
00309 {
00310   unsigned int realIndex = index + numberOfExtraBins;
00311   if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00312   return m_bins[ realIndex ]->entries();
00313 }
00314 
00315 
00316 double
00317 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::binHeight( int index ) const
00318 {
00319   unsigned int realIndex = index + numberOfExtraBins;
00320   if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00321   return m_bins[ realIndex ]->height();
00322 }
00323 
00324 
00325 double
00326 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::binError( int index ) const
00327 {
00328   unsigned int realIndex = index + numberOfExtraBins;
00329   if ( realIndex < 0 || realIndex>= m_bins.size() ) return 0;
00330   return m_bins[ realIndex ]->error();
00331 }
00332 
00333 
00334 double
00335 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::mean() const
00336 {
00337   calculateStatistics();
00338   return m_mean;
00339 }
00340 
00341 
00342 double
00343 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::rms() const
00344 {
00345   calculateStatistics();
00346   return m_rms;
00347 }
00348 
00349 
00350 bool
00351 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::calculateStatistics() const
00352 {
00353   if ( m_validStatistics ) return true;
00354 
00355   // For the in-range bins:
00356   m_sumBinHeights = 0;
00357   double sww = 0;
00358   double swp = 0;
00359   m_entries = 0;
00360   m_maxHeight = m_minHeight = m_bins[ numberOfExtraBins ]->height();
00361   for ( unsigned int i = numberOfExtraBins; i < m_bins.size(); ++i ) {
00362     const GravityBin1D& bin = *( m_bins[ i ] );
00363     const double binMean = bin.centreOfGravityX();
00364     const double binHeight = bin.height();
00365     const double binErrorSquared = bin.errorSquared();
00366     m_entries += bin.entries();
00367     m_sumBinHeights += binHeight;
00368     sww += binErrorSquared;
00369     swp += binMean * binHeight;
00370     if ( m_maxHeight < binHeight ) m_maxHeight = binHeight;
00371     if ( m_minHeight > binHeight ) m_minHeight = binHeight;
00372   }
00373 
00374   if ( m_sumBinHeights == 0 ) {
00375     m_mean = m_rms = 0;
00376   }
00377   else {
00378     m_mean = swp / m_sumBinHeights;
00379     m_rms = std::sqrt( std::abs(  m_sumWeightTimesSquaredX / m_sumBinHeights - m_mean * m_mean ) );
00380   }
00381 
00382   if ( sww ) {
00383     m_ebe = m_sumBinHeights * m_sumBinHeights / sww;
00384   }
00385   else {
00386     m_ebe = 0;
00387   }
00388 
00389   // For the out-of-range bins:
00390   m_sumExtraBinHeights = 0;
00391   m_extraEntries = 0;
00392   for ( unsigned int i = 0; i < numberOfExtraBins; ++i ) {
00393     const GravityBin1D& bin = *( m_bins[ i ] );
00394     m_extraEntries += bin.entries();
00395     m_sumExtraBinHeights += bin.height();
00396   }
00397 
00398   // Done !
00399   m_validStatistics = true;
00400   return m_validStatistics;
00401 }
00402 
00403 
00404 const AIDA::IAxis&
00405 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::axis() const
00406 {
00407   return *m_axis;
00408 }
00409 
00410 
00411 int
00412 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::coordToIndex( double coord ) const
00413 {
00414   return m_axis->coordToIndex( coord );
00415 }
00416 
00417 
00418 bool
00419 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::add( const AIDA::IHistogram1D & h )
00420 {
00421   // First check that the histograms are compatible
00422   const AIDA::IAxis& otherAxis = h.axis();
00423   const AIDA::IAxis& myAxis = *m_axis;
00424   if ( otherAxis.bins() != myAxis.bins() ) return false;
00425   for ( int iBin = 0; iBin < myAxis.bins(); ++iBin ) {
00426     const double otherLowEdge = otherAxis.binLowerEdge( iBin );
00427     const double myLowEdge = myAxis.binLowerEdge( iBin );
00428     if ( otherLowEdge != myLowEdge ) return false;
00429   }
00430   if ( otherAxis.upperEdge() != myAxis.upperEdge() ) return false;
00431 
00432   // OK, the histograms are compatible.
00433   // Let's check if the histograms are the ANAPHE ones, to make our life a bit easier.
00434   try {
00435     const Anaphe::AIDA_Histogram_native::AIDA_Histogram1D& other = dynamic_cast<const Anaphe::AIDA_Histogram_native::AIDA_Histogram1D&>( h );
00436     return increment( other );
00437   }
00438   catch( std::bad_cast ) {
00439     Anaphe::AIDA_Histogram_native::AIDA_Histogram1D * transformed = new Anaphe::AIDA_Histogram_native::AIDA_Histogram1D( h );
00440     bool ret = increment( *transformed );
00441     delete transformed;
00442     return ret;
00443   }
00444 }
00445 
00446 
00447 bool
00448 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::increment( const AIDA_Histogram1D& h )
00449 {
00450   for ( unsigned int i = 0; i < m_bins.size(); ++i ) {
00451     m_bins[ i ]->increment( *( h.m_bins[i] ) );
00452   }
00453   m_sumWeightTimesSquaredX += h.m_sumWeightTimesSquaredX;  
00454   setUpToDate( false );  
00455   m_validStatistics = false;
00456   return true;
00457 }
00458 
00459 
00460 bool
00461 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::setBinContents( int binIndex,
00462                                                                  int entries,
00463                                                                  double height,
00464                                                                  double error,
00465                                                                  double centre )
00466 {
00467   unsigned int realIndex = binIndex + numberOfExtraBins;
00468   if ( realIndex < 0 || realIndex>= m_bins.size() ) return false;
00469   setUpToDate( false );  
00470   m_validStatistics = false;
00471   return m_bins[ realIndex ]->set( entries, height, error, centre );
00472 }
00473 
00474 
00475 bool
00476 Anaphe::AIDA_Histogram_native::AIDA_Histogram1D::setRms( double rms )
00477 {
00478   const double mn = mean();
00479   m_sumWeightTimesSquaredX = ( mn*mn + rms*rms) * sumBinHeights();
00480   m_validStatistics = false;
00481   return true;
00482 }

Generated on Tue Nov 19 12:32:16 2002 for AIDA_Histogram_native by doxygen1.2.16