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

AIDA_Profile1D.cpp

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

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