4 #pragma warning(disable:2259) 7 #pragma warning(disable:1572) 13 #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" 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 ;
100 double maxY (
const bool withErr )
const 103 std::max ( under.height, over.height ),
104 [&](
double m,
const Bin& b) {
105 return std::max ( m, withErr ? b.height + b.error : b.height ) ;
109 double minY (
const bool withErr )
const 112 std::min ( under.height, over.height ),
113 [&](
double m,
const Bin& b) {
114 return std::min ( m, withErr ? b.height - b.error : b.height ) ;
118 Histo rebin (
const unsigned int bin )
const 126 for (
unsigned int ibin = 0 ; ibin < bins.size() ; ++ibin )
128 const Bin& current = bins[ibin] ;
129 if ( nh.bins.empty() ) { nh.bins.push_back ( current ) ; }
130 else if ( 0 == ibin % bin ) { nh.bins.push_back ( current ) ; }
131 else { nh.bins.back() += current ; }
138 for (
auto ib = bins.cbegin() ; bins.cend() != ib + 1 ; ++ib )
139 {
if ( ib->lower <= 0 && 0 < (ib+1)->lower ) {
return ib - bins.cbegin() ; } }
167 const TAxis* axis = root->GetXaxis() ;
169 const int nbins = axis->GetNbins () ;
173 hist.under = Histo::Bin ( root -> GetBinContent ( 0 ) ,
174 root -> GetBinError ( 0 ) ,
175 axis -> GetXmin () ) ;
177 hist.over = Histo::Bin ( root -> GetBinContent ( nbins + 1 ) ,
178 root -> GetBinError ( nbins + 1 ) ,
179 axis -> GetXmax () ) ;
182 for (
int ibin = 1 ; ibin <= nbins ; ++ibin )
185 hist.bins.emplace_back( root -> GetBinContent ( ibin ) ,
186 root -> GetBinError ( ibin ) ,
187 axis -> GetBinLowEdge ( ibin ) ) ;
203 const TH1* histo =
root ;
204 return _getHisto ( histo , hist ) ;
215 (
const AIDA::IHistogram1D* aida , Histo& hist )
222 const AIDA::IAxis& axis = aida -> axis () ;
223 const int nbins = axis . bins () ;
226 hist.under = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::UNDERFLOW_BIN ) ,
227 aida -> binError ( AIDA::IAxis::UNDERFLOW_BIN ) ,
228 axis . lowerEdge () ) ;
230 hist.over = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::OVERFLOW_BIN ) ,
231 aida -> binError ( AIDA::IAxis::OVERFLOW_BIN ) ,
232 axis . upperEdge () ) ;
234 for (
int ibin = 0 ; ibin < nbins ; ++ibin )
237 hist.bins.emplace_back ( aida -> binHeight ( ibin ) ,
238 aida -> binError ( ibin ) ,
239 axis . binLowerEdge ( ibin ) ) ;
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 hist.bins.emplace_back( aida -> binHeight ( ibin ) ,
282 aida -> binRms ( ibin ) :
283 aida -> binError ( ibin ) ,
284 axis . binLowerEdge ( ibin ) ) ;
294 inline unsigned int rebin
295 (
const unsigned int bins ,
296 const unsigned int imax )
298 if ( 0 == imax ) {
return 1 ; }
299 unsigned int ibin = 1 ;
300 while ( bins > imax * ibin ) { ++ibin ; }
311 if ( 0 == v ) {
return { 0.0 , 0 } ; }
312 else if ( 1 == v ) {
return { 1.0 , 0 } ; }
315 auto r = decompose ( -v ) ;
316 return { -r.first , r.second } ;
321 while ( 0.1 > v ) { ++i ; v *= 10 ; }
327 while ( 1 <= v ) { ++i ; v /= 10 ; }
337 inline double _pow (
double x ,
unsigned long n )
339 double y = n % 2 ? x : 1;
343 if ( n % 2) { y *= x; }
348 inline double rValMin (
double v );
354 inline double rValMax (
double v )
356 if ( 0 == v ) {
return 0 ; }
357 else if ( 0 > v ) {
return -1 * rValMin ( -v ) ; }
361 const double f =
std::ceil ( 20 * r.first ) / 2 ;
362 const int l = r.second - 1 ;
363 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
370 inline double rValMin (
double v )
372 if ( 0 == v ) {
return 0 ; }
373 else if ( 0 > v ) {
return -1 * rValMax ( -v ) ; }
376 const double f =
std::floor ( 20 * r.first ) / 2 ;
377 const int l = r.second - 1 ;
378 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
404 char symbBin (
const Histo::Bin& bin ,
410 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
411 else if ( errors && yHigh < bin.height - bin.error ) {
return ' ' ; }
412 else if ( errors && yLow >= bin.height + bin.error ) {
return ' ' ; }
413 else if ( errors ) {
return 'I' ; }
414 else if ( yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
415 else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
return '*' ; }
416 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
return '*' ; }
426 (
const Histo& histo ,
432 if ( 40 > width ) {
return dumpText ( histo , 40 , height , errors , stream ) ; }
433 if ( 200 < width ) {
return dumpText ( histo , 200 , height , errors , stream ) ; }
434 if ( 150 < height ) {
return dumpText ( histo , width , 150 , errors , stream ) ; }
435 if ( 20 > height ) {
return dumpText ( histo , width , 20 , errors , stream ) ; }
436 if ( height > width ) {
return dumpText ( histo , width , width , errors , stream ) ; }
438 const unsigned int nBins = histo.bins.size() ;
442 Histo r = histo.rebin ( rebin ( nBins , width ) ) ;
443 return dumpText ( r , width , height , errors , stream ) ;
447 double yMax =
std::max ( rValMax ( histo.maxY ( errors ) ) , 0.0 ) ;
448 double yMin =
std::min ( rValMin ( histo.minY ( errors ) ) , 0.0 ) ;
450 if ( yMin == yMax ) { yMax = yMin + 1 ; }
453 double _ny =
std::ceil ( 10 * r.first ) ;
454 if ( 1 >= _ny ) { _ny = 10 ; }
458 if ( 20 > yBins ) { yBins = 20 ; }
459 const double yScale = ( yMax - yMin ) / yBins ;
463 0 == yBins % 13 ? 13 :
464 0 == yBins % 11 ? 11 :
470 0 == yBins % 4 ? 4 : 10 ;
477 0 == nBins % 4 ? 4 : 10 ;
479 int iNull = histo.nullBin() ;
481 if ( 0 <= iNull ) { iNull %= xSkip ; }
486 for (
int yLine = -1 ; yLine < yBins ; ++yLine )
488 const double yHigh = yMax - yScale * yLine ;
490 const double yLow = yMax - yScale * ( yLine + 1 ) ;
494 const bool ynull = ( yLow <= 0 && 0 < yHigh ) ;
495 const bool yfirst = -1 == yLine || yBins -1 == yLine ;
497 ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull ;
499 if ( ylab ) { line1 += yLabel ( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow ) ; }
505 line1 += symbBin ( histo.under , yLow , yHigh , ynull , errors ) ;
513 for (
auto ibin = histo.bins.cbegin() ;
514 histo.bins.cend() != ibin ; ++ibin )
517 const int i = ibin - histo.bins.cbegin () ;
520 ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < (ibin+1)->lower ;
521 const bool xlab = iNull == i % xSkip ;
523 char symb = symbBin ( *ibin, yLow , yHigh , ynull , errors ) ;
527 if ( ( ynull || yfirst ) && xlab ) { symb =
'+' ; }
528 else if ( ynull || yfirst ) { symb =
'-' ; }
530 else if ( ylab && xnull ) { symb =
'+' ; }
531 else if ( xnull ) { symb =
'|' ; }
533 else if ( ylab || xlab ) { symb =
'.' ; }
545 line3 += symbBin ( histo.over , yLow , yHigh , ynull , errors ) ;
547 stream << line1 << line2 << line3 <<
std::endl ;
553 for (
auto ib = histo.bins.cbegin() ; histo.bins.cend() != ib ; ++ib )
554 { xlabels.
push_back ( xLabel ( ib->lower ) ) ; }
556 const std::string oLabel = xLabel ( histo.over.lower ) ;
557 const std::string uLabel = xLabel ( histo.under.lower ) ;
559 static const std::string s_UNDERFLOW (
"UNDERFLOW" ) ;
560 static const std::string s_OVERFLOW (
" OVERFLOW" ) ;
563 for (
unsigned int yLine = 0 ; yLine < 12 ; ++yLine )
567 if ( yLine < s_UNDERFLOW.size() ) { line += s_UNDERFLOW[yLine] ; }
568 else { line +=
' ' ; }
572 if ( uLabel.
size() > yLine ) { line += uLabel[yLine] ; }
573 else { line +=
' ' ; }
575 for (
auto ibin = histo.bins.cbegin() ; histo.bins.cend() != ibin ; ++ibin )
577 int ib = ibin - histo.bins.cbegin() ;
578 const bool xlab = ( iNull == ib % xSkip ) ;
579 if ( xlab && yLine < xlabels[ib].size() ) { line += xlabels[ib][yLine] ; }
580 else { line +=
' ' ; }
583 if ( oLabel.
size() > yLine ) { line += oLabel[yLine] ; }
584 else { line +=
' ' ; }
588 if ( yLine < s_OVERFLOW.size() ) { line += s_OVERFLOW[yLine] ; }
589 else { line +=
' ' ; }
610 (
const AIDA::IHistogram1D* histo ,
617 if ( !histo ) {
return stream ; }
620 if ( sc.
isFailure() ) {
return stream ; }
649 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |")
658 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g | %=11.5g |")
659 % histo -> allEntries ()
660 % histo -> entries ()
661 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
662 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
663 % histo -> equivalentBinEntries ()
664 % histo -> sumBinHeights ()
665 % histo -> sumAllBinHeights ()
669 const AIDA::IAnnotation& a = histo->annotation () ;
673 for (
int i = 0 ; i < a.size() ; ++i )
684 return dumpText ( hist , width , height , errors , stream ) ;
699 (
const AIDA::IHistogram1D* histo ,
705 histoDump_ ( histo , stream , width , height , errors );
706 return stream.
str() ;
721 (
const AIDA::IProfile1D* histo ,
728 if ( !histo ) {
return stream ; }
730 StatusCode sc = _getHisto ( histo , hist , spread ) ;
731 if ( sc.
isFailure() ) {
return stream ; }
748 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |")
757 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g |")
758 % histo -> allEntries ()
759 % histo -> entries ()
760 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
761 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
763 % histo -> sumBinHeights ()
764 % histo -> sumAllBinHeights ()
768 const AIDA::IAnnotation& a = histo->annotation () ;
772 for (
int i = 0 ; i < a.size() ; ++i )
783 return dumpText ( hist , width , height ,
true , stream ) ;
796 (
const AIDA::IProfile1D* histo ,
802 histoDump_ ( histo , stream , width , height , spread );
803 return stream.
str() ;
823 const TProfile* profile =
dynamic_cast<const TProfile*
> ( histo ) ;
825 {
return histoDump_ ( profile , stream , width , height ) ; }
828 if ( !histo ) {
return stream ; }
831 if ( sc.
isFailure() ) {
return stream ; }
835 % histo -> GetName ()
838 % histo -> GetTitle ()
844 % histo -> GetMean ()
845 % histo -> GetMeanError ()
849 % histo -> GetRMSError ()
852 % histo -> GetSkewness ()
855 % histo -> GetKurtosis ()
860 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |")
867 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
868 % histo -> GetEntries ()
869 % histo -> GetBinContent ( 0 )
870 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
871 % histo -> GetEffectiveEntries ()
876 return dumpText ( hist , width , height , errors , stream ) ;
890 (
const TProfile* histo ,
896 if ( ! histo ) {
return stream ; }
898 StatusCode sc = _getHisto ( histo , hist ,
true ) ;
899 if ( sc.
isFailure() ) {
return stream ; }
903 % histo -> GetName ()
906 % histo -> GetTitle ()
918 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s |")
924 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
925 % histo -> GetEntries ()
926 % histo -> GetBinContent ( 0 )
927 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
932 return dumpText ( hist , width , height ,
true , stream ) ;
951 histoDump_ ( histo , stream , width , height , errors );
952 return stream.
str() ;
965 (
const TProfile* histo ,
970 histoDump_ ( histo , stream , width , height );
971 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.
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