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
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
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
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
00120 for ( unsigned int i = 0; i < m_bins.size(); ++i ) m_bins[i] = new ProfileBin1D;
00121
00122
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
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
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
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
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
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
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
00412
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 }