5 #pragma warning(disable:2259)
8 #pragma warning(disable:1572)
14 #pragma warning(disable:4996)
29 #include "AIDA/IHistogram1D.h"
30 #include "AIDA/IProfile1D.h"
31 #include "AIDA/IAxis.h"
32 #include "AIDA/IAnnotation.h"
46 #include "boost/format.hpp"
65 Histo() : bins() , under() , over() {}
75 Bin (
const double h = 0 ,
89 Bin& operator+= (
const Bin& right )
91 height += right.height ;
92 const double e2 = error * error + right.error * right.error ;
93 error = std::sqrt ( e2 ) ;
100 double maxY (
const bool withErr )
const
102 double _m = std::max ( under.height , over.height ) ;
103 for ( Bins::const_iterator ib = bins.begin() ; bins.end() != ib ; ++ib )
104 { _m = std::max ( _m , withErr ? ib->height + ib->error : ib->height ) ; }
108 double minY (
const bool withErr )
const
110 double _m =
std::min ( under.height , over.height ) ;
111 for ( Bins::const_iterator ib = bins.begin() ; bins.end() != ib ; ++ib )
112 { _m =
std::min ( _m , withErr ? ib->height - ib->error : ib->height ) ; }
116 Histo rebin (
const unsigned int bin )
const
124 for (
unsigned int ibin = 0 ; ibin < bins.size() ; ++ibin )
126 const Bin& current = bins[ibin] ;
127 if ( nh.bins.empty() ) { nh.bins.push_back ( current ) ; }
128 else if ( 0 == ibin % bin ) { nh.bins.push_back ( current ) ; }
129 else { nh.bins.back() += current ; }
136 for ( Bins::const_iterator ib = bins.begin() ; bins.end() != ib + 1 ; ++ib )
137 {
if ( ib->lower <= 0 && 0 < (ib+1)->lower ) {
return ib - bins.begin() ; } }
141 typedef std::vector<Bin> Bins ;
165 const TAxis* axis = root->GetXaxis() ;
167 const int nbins = axis->GetNbins () ;
171 hist.under = Histo::Bin ( root -> GetBinContent ( 0 ) ,
172 root -> GetBinError ( 0 ) ,
173 axis -> GetXmin () ) ;
175 hist.over = Histo::Bin ( root -> GetBinContent ( nbins + 1 ) ,
176 root -> GetBinError ( nbins + 1 ) ,
177 axis -> GetXmax () ) ;
180 for (
int ibin = 1 ; ibin <= nbins ; ++ibin )
183 Histo::Bin bin ( root -> GetBinContent ( ibin ) ,
184 root -> GetBinError ( ibin ) ,
185 axis -> GetBinLowEdge ( ibin ) ) ;
186 hist.bins.push_back ( bin ) ;
202 const TH1* histo =
root ;
203 return _getHisto ( histo , hist ) ;
214 (
const AIDA::IHistogram1D* aida , Histo& hist )
221 const AIDA::IAxis& axis = aida -> axis () ;
222 const int nbins = axis . bins () ;
225 hist.under = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::UNDERFLOW_BIN ) ,
226 aida -> binError ( AIDA::IAxis::UNDERFLOW_BIN ) ,
227 axis . lowerEdge () ) ;
229 hist.over = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::OVERFLOW_BIN ) ,
230 aida -> binError ( AIDA::IAxis::OVERFLOW_BIN ) ,
231 axis . upperEdge () ) ;
233 for (
int ibin = 0 ; ibin < nbins ; ++ibin )
236 Histo::Bin bin ( aida -> binHeight ( ibin ) ,
237 aida -> binError ( ibin ) ,
238 axis . binLowerEdge ( ibin ) ) ;
239 hist.bins.push_back ( bin ) ;
252 (
const AIDA::IProfile1D* aida ,
261 const AIDA::IAxis& axis = aida -> axis () ;
262 const int nbins = axis . bins () ;
265 hist.under = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::UNDERFLOW_BIN ) ,
267 aida -> binRms ( AIDA::IAxis::UNDERFLOW_BIN ) :
268 aida -> binError ( AIDA::IAxis::UNDERFLOW_BIN ) ,
269 axis . lowerEdge () ) ;
271 hist.over = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::OVERFLOW_BIN ) ,
273 aida -> binRms ( AIDA::IAxis::OVERFLOW_BIN ) :
274 aida -> binError ( AIDA::IAxis::OVERFLOW_BIN ) ,
275 axis . upperEdge () ) ;
277 for (
int ibin = 0 ; ibin < nbins ; ++ibin )
280 Histo::Bin bin ( aida -> binHeight ( ibin ) ,
282 aida -> binRms ( ibin ) :
283 aida -> binError ( ibin ) ,
284 axis . binLowerEdge ( ibin ) ) ;
285 hist.bins.push_back ( bin ) ;
295 inline unsigned int rebin
296 (
const unsigned int bins ,
297 const unsigned int imax )
299 if ( 0 == imax ) {
return 1 ; }
300 unsigned int ibin = 1 ;
301 while ( bins > imax * ibin ) { ++ibin ; }
310 std::pair<double,int> decompose (
double v )
312 if ( 0 == v ) {
return std::make_pair ( 0.0 , 0 ) ; }
313 else if ( 1 == v ) {
return std::make_pair ( 1.0 , 0 ) ; }
316 std::pair<double,int> r = decompose ( -v ) ;
317 return std::pair<double,int>( -r.first , r.second ) ;
322 while ( 0.1 > v ) { ++
i ; v *= 10 ; }
323 return std::make_pair ( v , -i ) ;
328 while ( 1 <= v ) { ++
i ; v /= 10 ; }
329 return std::make_pair ( v , i ) ;
331 return std::make_pair ( v , 1 ) ;
338 inline double _pow (
double __x ,
unsigned long __n )
340 double __y = __n % 2 ? __x : 1;
344 if ( __n % 2) { __y = __y * __x; }
353 inline double rValMax (
const double v ) ;
359 inline double rValMin (
const double v ) ;
365 inline double rValMax (
const double v )
367 if ( 0 == v ) {
return 0 ; }
368 else if ( 0 > v ) {
return -1 * rValMin ( -v ) ; }
370 std::pair<double,int> r = decompose ( v ) ;
372 const double f = std::ceil ( 20 * r.first ) / 2 ;
373 const int l = r.second - 1 ;
374 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
381 inline double rValMin (
const double v )
383 if ( 0 == v ) {
return 0 ; }
384 else if ( 0 > v ) {
return -1 * rValMax ( -v ) ; }
386 std::pair<double,int> r = decompose ( v ) ;
387 const double f = std::floor ( 20 * r.first ) / 2 ;
388 const int l = r.second - 1 ;
389 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
396 inline std::string yLabel (
const double value )
407 inline std::string xLabel (
const double value )
415 char symbBin (
const Histo::Bin& bin ,
421 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
422 else if ( errors && yHigh < bin.height - bin.error ) {
return ' ' ; }
423 else if ( errors && yLow >= bin.height + bin.error ) {
return ' ' ; }
424 else if ( errors ) {
return 'I' ; }
425 else if ( yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
426 else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
return '*' ; }
427 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
return '*' ; }
436 std::ostream& dumpText
437 (
const Histo& histo ,
438 const std::size_t width ,
439 const std::size_t height ,
441 std::ostream& stream )
443 if ( 40 > width ) {
return dumpText ( histo , 40 , height , errors , stream ) ; }
444 if ( 200 < width ) {
return dumpText ( histo , 200 , height , errors , stream ) ; }
445 if ( 150 < height ) {
return dumpText ( histo , width , 150 , errors , stream ) ; }
446 if ( 20 > height ) {
return dumpText ( histo , width , 20 , errors , stream ) ; }
447 if ( height > width ) {
return dumpText ( histo , width , width , errors , stream ) ; }
449 const unsigned int nBins = histo.bins.size() ;
453 Histo r = histo.rebin ( rebin ( nBins , width ) ) ;
454 return dumpText ( r , width , height , errors , stream ) ;
458 double yMax = std::max ( rValMax ( histo.maxY ( errors ) ) , 0.0 ) ;
459 double yMin =
std::min ( rValMin ( histo.minY ( errors ) ) , 0.0 ) ;
461 if ( yMin == yMax ) { yMax = yMin + 1 ; }
463 std::pair<double,int> r = decompose ( yMax - yMin ) ;
464 double _ny = std::ceil ( 10 * r.first ) ;
465 if ( 1 >= _ny ) { _ny = 10 ; }
466 int yBins = (int) std::max ( 1. , std::ceil ( height / _ny ) ) ;
469 if ( 20 > yBins ) { yBins = 20 ; }
470 const double yScale = ( yMax - yMin ) / yBins ;
474 0 == yBins % 13 ? 13 :
475 0 == yBins % 11 ? 11 :
481 0 == yBins % 4 ? 4 : 10 ;
488 0 == nBins % 4 ? 4 : 10 ;
490 int iNull = histo.nullBin() ;
492 if ( 0 <= iNull ) { iNull %= xSkip ; }
495 stream << std::endl ;
497 for (
int yLine = -1 ; yLine < yBins ; ++yLine )
499 const double yHigh = yMax - yScale * yLine ;
501 const double yLow = yMax - yScale * ( yLine + 1 ) ;
503 std::string line1 =
" " ;
505 const bool ynull = ( yLow <= 0 && 0 < yHigh ) ;
506 const bool yfirst = -1 == yLine || yBins -1 == yLine ;
508 ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull ;
510 if ( ylab ) { line1 += yLabel ( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow ) ; }
511 else { line1 += std::string( 10 ,
' ' ) ; }
516 line1 += symbBin ( histo.under , yLow , yHigh , ynull , errors ) ;
524 for ( Histo::Bins::const_iterator ibin = histo.bins.begin() ;
525 histo.bins.end() != ibin ; ++ibin )
528 const int i = ibin - histo.bins.begin () ;
531 ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.end() && 0 < (ibin+1)->lower ;
532 const bool xlab = iNull == i % xSkip ;
534 char symb = symbBin ( *ibin, yLow , yHigh , ynull , errors ) ;
538 if ( ( ynull || yfirst ) && xlab ) { symb =
'+' ; }
539 else if ( ynull || yfirst ) { symb =
'-' ; }
541 else if ( ylab && xnull ) { symb =
'+' ; }
542 else if ( xnull ) { symb =
'|' ; }
544 else if ( ylab || xlab ) { symb =
'.' ; }
556 line3 += symbBin ( histo.over , yLow , yHigh , ynull , errors ) ;
558 stream << line1 << line2 << line3 << std::endl ;
563 std::vector<std::string> xlabels ;
564 for ( Histo::Bins::const_iterator ib = histo.bins.begin() ; histo.bins.end() != ib ; ++ib )
565 { xlabels.push_back ( xLabel ( ib->lower ) ) ; }
567 const std::string oLabel = xLabel ( histo.over.lower ) ;
568 const std::string uLabel = xLabel ( histo.under.lower ) ;
570 static const std::string s_UNDERFLOW (
"UNDERFLOW" ) ;
571 static const std::string s_OVERFLOW (
" OVERFLOW" ) ;
574 for (
unsigned int yLine = 0 ; yLine < 12 ; ++yLine )
576 std::string
line = std::string ( 12 ,
' ' ) ;
578 if ( yLine < s_UNDERFLOW.size() ) { line += s_UNDERFLOW[yLine] ; }
579 else { line +=
' ' ; }
583 if ( uLabel.size() > yLine ) { line += uLabel[yLine] ; }
584 else { line +=
' ' ; }
586 for ( Histo::Bins::const_iterator ibin = histo.bins.begin() ; histo.bins.end() != ibin ; ++ibin )
588 int ib = ibin - histo.bins.begin() ;
589 const bool xlab = ( iNull == ib % xSkip ) ;
590 if ( xlab && yLine < xlabels[ib].size() ) { line += xlabels[ib][yLine] ; }
591 else { line +=
' ' ; }
594 if ( oLabel.size() > yLine ) { line += oLabel[yLine] ; }
595 else { line +=
' ' ; }
599 if ( yLine < s_OVERFLOW.size() ) { line += s_OVERFLOW[yLine] ; }
600 else { line +=
' ' ; }
602 stream << line << std::endl ;
621 (
const AIDA::IHistogram1D* histo ,
622 std::ostream& stream ,
623 const std::size_t width ,
624 const std::size_t height ,
627 stream << std::endl ;
628 if ( 0 == histo ) {
return stream ; }
631 if ( sc.
isFailure() ) {
return stream ; }
660 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |")
669 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g | %=11.5g |")
670 % histo -> allEntries ()
671 % histo -> entries ()
672 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
673 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
674 % histo -> equivalentBinEntries ()
675 % histo -> sumBinHeights ()
676 % histo -> sumAllBinHeights ()
680 const AIDA::IAnnotation& a = histo->annotation () ;
683 stream <<
" Annotation" << std::endl ;
684 for (
int i = 0 ; i < a.size() ; ++
i )
692 stream << std::endl ;
695 return dumpText ( hist , width , height , errors , stream ) ;
710 (
const AIDA::IHistogram1D* histo ,
711 const std::size_t width ,
712 const std::size_t height ,
715 std::ostringstream stream ;
716 histoDump_ ( histo , stream , width , height , errors );
717 return stream.str() ;
732 (
const AIDA::IProfile1D* histo ,
733 std::ostream& stream ,
734 const std::size_t width ,
735 const std::size_t height ,
738 stream << std::endl ;
739 if ( 0 == histo ) {
return stream ; }
742 if ( sc.
isFailure() ) {
return stream ; }
759 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |")
768 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g |")
769 % histo -> allEntries ()
770 % histo -> entries ()
771 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
772 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
774 % histo -> sumBinHeights ()
775 % histo -> sumAllBinHeights ()
779 const AIDA::IAnnotation& a = histo->annotation () ;
782 stream <<
" Annotation" << std::endl ;
783 for (
int i = 0 ; i < a.size() ; ++
i )
791 stream << std::endl ;
794 return dumpText ( hist , width , height ,
true , stream ) ;
807 (
const AIDA::IProfile1D* histo ,
808 const std::size_t width ,
809 const std::size_t height ,
812 std::ostringstream stream ;
813 histoDump_ ( histo , stream , width , height , spread );
814 return stream.str() ;
829 std::ostream& stream ,
830 const std::size_t width ,
831 const std::size_t height ,
834 const TProfile* profile =
dynamic_cast<const TProfile*
> ( histo ) ;
836 {
return histoDump_ ( profile , stream , width , height ) ; }
838 stream << std::endl ;
839 if ( 0 == histo ) {
return stream ; }
842 if ( sc.
isFailure() ) {
return stream ; }
846 % histo -> GetName ()
849 % histo -> GetTitle ()
855 % histo -> GetMean ()
856 % histo -> GetMeanError ()
860 % histo -> GetRMSError ()
863 % histo -> GetSkewness ()
866 % histo -> GetKurtosis ()
871 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |")
878 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
879 % histo -> GetEntries ()
880 % histo -> GetBinContent ( 0 )
881 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
882 % histo -> GetEffectiveEntries ()
887 return dumpText ( hist , width , height , errors , stream ) ;
901 (
const TProfile* histo ,
902 std::ostream& stream ,
903 const std::size_t width ,
904 const std::size_t height )
906 stream << std::endl ;
907 if ( 0 == histo ) {
return stream ; }
910 if ( sc.
isFailure() ) {
return stream ; }
914 % histo -> GetName ()
917 % histo -> GetTitle ()
929 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s |")
935 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
936 % histo -> GetEntries ()
937 % histo -> GetBinContent ( 0 )
938 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
943 return dumpText ( hist , width , height ,
true , stream ) ;
957 const std::size_t width ,
958 const std::size_t height ,
961 std::ostringstream stream ;
962 histoDump_ ( histo , stream , width , height , errors );
963 return stream.str() ;
976 (
const TProfile* histo ,
977 const std::size_t width ,
978 const std::size_t height )
980 std::ostringstream stream ;
981 histoDump_ ( histo , stream , width , height );
982 return stream.str() ;
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
GAUDI_API std::ostream & histoDump_(const AIDA::IHistogram1D *histo, std::ostream &stream, const std::size_t width=80, const std::size_t height=50, const bool errors=false)
dump the text representation of the histogram
GAUDI_API std::string histoDump(const AIDA::IHistogram1D *histo, const std::size_t width=80, const std::size_t height=50, const bool errors=false)
dump the text representation of the histogram
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
bool isFailure() const
Test for a status code of FAILURE.
static double rms(const AIDA::IHistogram1D *histo)
get the rms value for the histogram (just for completeness)
This class is used for returning status codes from appropriate routines.
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
static double kurtosisErr(const AIDA::IHistogram1D *histo)
get the error in kurtosis for the histogram
GAUDI_API double Integral(const Genfun::AbsFunction &function, const double a, const double b, const GaudiMath::Integration::Type type=GaudiMath::Integration::Adaptive, const GaudiMath::Integration::KronrodRule rule=GaudiMath::Integration::Default, const double epsabs=1.e-10, const double epsrel=1.e-7, const size_t size=1000)
static double mean(const AIDA::IHistogram1D *histo)
get the mean value for the histogram (just for completeness)
static double skewnessErr(const AIDA::IHistogram1D *histo)
get the error in skewness for the histogram
static double kurtosis(const AIDA::IHistogram1D *histo)
get the kurtosis for the histogram
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram