4 #pragma warning(disable:2259)
7 #pragma warning(disable:1572)
13 #pragma warning(disable:4996)
28 #include "AIDA/IHistogram1D.h"
29 #include "AIDA/IProfile1D.h"
30 #include "AIDA/IAxis.h"
31 #include "AIDA/IAnnotation.h"
35 #include "GaudiKernel/StatusCode.h"
45 #include "boost/format.hpp"
49 #include "GaudiUtils/HistoDump.h"
50 #include "GaudiUtils/HistoTableFormat.h"
51 #include "GaudiUtils/HistoStats.h"
74 Bin (
const double h = 0 ,
88 Bin& operator+= (
const Bin& right )
90 height += right.height ;
91 const double e2 = error * error + right.error * right.error ;
92 error = std::sqrt ( e2 ) ;
99 double maxY (
const bool withErr )
const
102 std::max ( under.height, over.height ),
103 [&](
double m,
const Bin& b) {
104 return std::max ( m, withErr ? b.height + b.error : b.height ) ;
108 double minY (
const bool withErr )
const
111 std::min ( under.height, over.height ),
112 [&](
double m,
const Bin& b) {
113 return std::min ( m, withErr ? b.height - b.error : b.height ) ;
117 Histo rebin (
const unsigned int bin )
const
125 for (
unsigned int ibin = 0 ; ibin < bins.size() ; ++ibin )
127 const Bin& current = bins[ibin] ;
128 if ( nh.bins.empty() ) { nh.bins.push_back ( current ) ; }
129 else if ( 0 == ibin % bin ) { nh.bins.push_back ( current ) ; }
130 else { nh.bins.back() += current ; }
137 for (
auto ib = bins.cbegin() ; bins.cend() != ib + 1 ; ++ib )
138 {
if ( ib->lower <= 0 && 0 < (ib+1)->lower ) {
return ib - bins.cbegin() ; } }
142 typedef std::vector<Bin> Bins ;
166 const TAxis* axis = root->GetXaxis() ;
168 const int nbins = axis->GetNbins () ;
172 hist.under = Histo::Bin ( root -> GetBinContent ( 0 ) ,
173 root -> GetBinError ( 0 ) ,
174 axis -> GetXmin () ) ;
176 hist.over = Histo::Bin ( root -> GetBinContent ( nbins + 1 ) ,
177 root -> GetBinError ( nbins + 1 ) ,
178 axis -> GetXmax () ) ;
181 for (
int ibin = 1 ; ibin <= nbins ; ++ibin )
184 hist.bins.emplace_back( root -> GetBinContent ( ibin ) ,
185 root -> GetBinError ( ibin ) ,
186 axis -> GetBinLowEdge ( ibin ) ) ;
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 hist.bins.emplace_back ( aida -> binHeight ( ibin ) ,
237 aida -> binError ( ibin ) ,
238 axis . binLowerEdge ( ibin ) ) ;
251 (
const AIDA::IProfile1D* aida ,
260 const AIDA::IAxis& axis = aida -> axis () ;
261 const int nbins = axis . bins () ;
264 hist.under = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::UNDERFLOW_BIN ) ,
266 aida -> binRms ( AIDA::IAxis::UNDERFLOW_BIN ) :
267 aida -> binError ( AIDA::IAxis::UNDERFLOW_BIN ) ,
268 axis . lowerEdge () ) ;
270 hist.over = Histo::Bin ( aida -> binHeight ( AIDA::IAxis::OVERFLOW_BIN ) ,
272 aida -> binRms ( AIDA::IAxis::OVERFLOW_BIN ) :
273 aida -> binError ( AIDA::IAxis::OVERFLOW_BIN ) ,
274 axis . upperEdge () ) ;
276 for (
int ibin = 0 ; ibin < nbins ; ++ibin )
279 hist.bins.emplace_back( aida -> binHeight ( ibin ) ,
281 aida -> binRms ( ibin ) :
282 aida -> binError ( ibin ) ,
283 axis . binLowerEdge ( ibin ) ) ;
293 inline unsigned int rebin
294 (
const unsigned int bins ,
295 const unsigned int imax )
297 if ( 0 == imax ) {
return 1 ; }
298 unsigned int ibin = 1 ;
299 while ( bins > imax * ibin ) { ++ibin ; }
308 std::pair<double,int> decompose (
double v )
310 if ( 0 == v ) {
return { 0.0 , 0 } ; }
311 else if ( 1 == v ) {
return { 1.0 , 0 } ; }
314 auto r = decompose ( -v ) ;
315 return { -r.first , r.second } ;
320 while ( 0.1 > v ) { ++
i ; v *= 10 ; }
326 while ( 1 <= v ) { ++
i ; v /= 10 ; }
336 inline double _pow (
double x ,
unsigned long n )
338 double y = n % 2 ? x : 1;
342 if ( n % 2) { y *= x; }
347 inline double rValMin (
double v );
353 inline double rValMax (
double v )
355 if ( 0 == v ) {
return 0 ; }
356 else if ( 0 > v ) {
return -1 * rValMin ( -v ) ; }
358 std::pair<double,int> r = decompose ( v ) ;
360 const double f = std::ceil ( 20 * r.first ) / 2 ;
361 const int l = r.second - 1 ;
362 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
369 inline double rValMin (
double v )
371 if ( 0 == v ) {
return 0 ; }
372 else if ( 0 > v ) {
return -1 * rValMax ( -v ) ; }
374 std::pair<double,int> r = decompose ( v ) ;
375 const double f = std::floor ( 20 * r.first ) / 2 ;
376 const int l = r.second - 1 ;
377 return 0 < l ? f * _pow ( 10 , l ) : f / _pow ( 10 , -l ) ;
384 inline std::string yLabel (
double value )
395 inline std::string xLabel (
const double value )
403 char symbBin (
const Histo::Bin& bin ,
409 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
410 else if ( errors && yHigh < bin.height - bin.error ) {
return ' ' ; }
411 else if ( errors && yLow >= bin.height + bin.error ) {
return ' ' ; }
412 else if ( errors ) {
return 'I' ; }
413 else if ( yLow <= bin.height && bin.height < yHigh ) {
return '*' ; }
414 else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
return '*' ; }
415 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
return '*' ; }
424 std::ostream& dumpText
425 (
const Histo& histo ,
426 const std::size_t width ,
427 const std::size_t height ,
429 std::ostream& stream )
431 if ( 40 > width ) {
return dumpText ( histo , 40 , height , errors , stream ) ; }
432 if ( 200 < width ) {
return dumpText ( histo , 200 , height , errors , stream ) ; }
433 if ( 150 < height ) {
return dumpText ( histo , width , 150 , errors , stream ) ; }
434 if ( 20 > height ) {
return dumpText ( histo , width , 20 , errors , stream ) ; }
435 if ( height > width ) {
return dumpText ( histo , width , width , errors , stream ) ; }
437 const unsigned int nBins = histo.bins.size() ;
441 Histo r = histo.rebin ( rebin ( nBins , width ) ) ;
442 return dumpText ( r , width , height , errors , stream ) ;
446 double yMax = std::max ( rValMax ( histo.maxY ( errors ) ) , 0.0 ) ;
447 double yMin = std::min ( rValMin ( histo.minY ( errors ) ) , 0.0 ) ;
449 if ( yMin == yMax ) { yMax = yMin + 1 ; }
451 std::pair<double,int> r = decompose ( yMax - yMin ) ;
452 double _ny = std::ceil ( 10 * r.first ) ;
453 if ( 1 >= _ny ) { _ny = 10 ; }
454 int yBins = (int) std::max ( 1. , std::ceil ( height / _ny ) ) ;
457 if ( 20 > yBins ) { yBins = 20 ; }
458 const double yScale = ( yMax - yMin ) / yBins ;
462 0 == yBins % 13 ? 13 :
463 0 == yBins % 11 ? 11 :
469 0 == yBins % 4 ? 4 : 10 ;
476 0 == nBins % 4 ? 4 : 10 ;
478 int iNull = histo.nullBin() ;
480 if ( 0 <= iNull ) { iNull %= xSkip ; }
483 stream << std::endl ;
485 for (
int yLine = -1 ; yLine < yBins ; ++yLine )
487 const double yHigh = yMax - yScale * yLine ;
489 const double yLow = yMax - yScale * ( yLine + 1 ) ;
491 std::string line1 =
" " ;
493 const bool ynull = ( yLow <= 0 && 0 < yHigh ) ;
494 const bool yfirst = -1 == yLine || yBins -1 == yLine ;
496 ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull ;
498 if ( ylab ) { line1 += yLabel ( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow ) ; }
499 else { line1 += std::string( 10 ,
' ' ) ; }
504 line1 += symbBin ( histo.under , yLow , yHigh , ynull , errors ) ;
512 for (
auto ibin = histo.bins.cbegin() ;
513 histo.bins.cend() != ibin ; ++ibin )
516 const int i = ibin - histo.bins.cbegin () ;
519 ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < (ibin+1)->lower ;
520 const bool xlab = iNull == i % xSkip ;
522 char symb = symbBin ( *ibin, yLow , yHigh , ynull , errors ) ;
526 if ( ( ynull || yfirst ) && xlab ) { symb =
'+' ; }
527 else if ( ynull || yfirst ) { symb =
'-' ; }
529 else if ( ylab && xnull ) { symb =
'+' ; }
530 else if ( xnull ) { symb =
'|' ; }
532 else if ( ylab || xlab ) { symb =
'.' ; }
544 line3 += symbBin ( histo.over , yLow , yHigh , ynull , errors ) ;
546 stream << line1 << line2 << line3 << std::endl ;
551 std::vector<std::string> xlabels ;
552 for (
auto ib = histo.bins.cbegin() ; histo.bins.cend() != ib ; ++ib )
553 { xlabels.push_back ( xLabel ( ib->lower ) ) ; }
555 const std::string oLabel = xLabel ( histo.over.lower ) ;
556 const std::string uLabel = xLabel ( histo.under.lower ) ;
558 static const std::string s_UNDERFLOW (
"UNDERFLOW" ) ;
559 static const std::string s_OVERFLOW (
" OVERFLOW" ) ;
562 for (
unsigned int yLine = 0 ; yLine < 12 ; ++yLine )
564 std::string
line = std::string ( 12 ,
' ' ) ;
566 if ( yLine < s_UNDERFLOW.size() ) { line += s_UNDERFLOW[yLine] ; }
567 else { line +=
' ' ; }
571 if ( uLabel.size() > yLine ) { line += uLabel[yLine] ; }
572 else { line +=
' ' ; }
574 for (
auto ibin = histo.bins.cbegin() ; histo.bins.cend() != ibin ; ++ibin )
576 int ib = ibin - histo.bins.cbegin() ;
577 const bool xlab = ( iNull == ib % xSkip ) ;
578 if ( xlab && yLine < xlabels[ib].size() ) { line += xlabels[ib][yLine] ; }
579 else { line +=
' ' ; }
582 if ( oLabel.size() > yLine ) { line += oLabel[yLine] ; }
583 else { line +=
' ' ; }
587 if ( yLine < s_OVERFLOW.size() ) { line += s_OVERFLOW[yLine] ; }
588 else { line +=
' ' ; }
590 stream << line << std::endl ;
609 (
const AIDA::IHistogram1D* histo ,
610 std::ostream& stream ,
611 const std::size_t width ,
612 const std::size_t height ,
615 stream << std::endl ;
616 if ( !histo ) {
return stream ; }
619 if ( sc.
isFailure() ) {
return stream ; }
648 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |")
657 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g | %=11.5g |")
658 % histo -> allEntries ()
659 % histo -> entries ()
660 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
661 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
662 % histo -> equivalentBinEntries ()
663 % histo -> sumBinHeights ()
664 % histo -> sumAllBinHeights ()
668 const AIDA::IAnnotation& a = histo->annotation () ;
671 stream <<
" Annotation" << std::endl ;
672 for (
int i = 0 ; i < a.size() ; ++
i )
680 stream << std::endl ;
683 return dumpText ( hist , width , height , errors , stream ) ;
698 (
const AIDA::IHistogram1D* histo ,
699 const std::size_t width ,
700 const std::size_t height ,
703 std::ostringstream stream ;
704 histoDump_ ( histo , stream , width , height , errors );
705 return stream.str() ;
720 (
const AIDA::IProfile1D* histo ,
721 std::ostream& stream ,
722 const std::size_t width ,
723 const std::size_t height ,
726 stream << std::endl ;
727 if ( !histo ) {
return stream ; }
730 if ( sc.
isFailure() ) {
return stream ; }
747 <<
boost::format (
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |")
756 <<
boost::format (
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g |")
757 % histo -> allEntries ()
758 % histo -> entries ()
759 % histo -> binEntries ( AIDA::IAxis::UNDERFLOW_BIN )
760 % histo -> binEntries ( AIDA::IAxis::OVERFLOW_BIN )
762 % histo -> sumBinHeights ()
763 % histo -> sumAllBinHeights ()
767 const AIDA::IAnnotation& a = histo->annotation () ;
770 stream <<
" Annotation" << std::endl ;
771 for (
int i = 0 ; i < a.size() ; ++
i )
779 stream << std::endl ;
782 return dumpText ( hist , width , height ,
true , stream ) ;
795 (
const AIDA::IProfile1D* histo ,
796 const std::size_t width ,
797 const std::size_t height ,
800 std::ostringstream stream ;
801 histoDump_ ( histo , stream , width , height , spread );
802 return stream.str() ;
817 std::ostream& stream ,
818 const std::size_t width ,
819 const std::size_t height ,
822 const TProfile* profile =
dynamic_cast<const TProfile*
> ( histo ) ;
824 {
return histoDump_ ( profile , stream , width , height ) ; }
826 stream << std::endl ;
827 if ( !histo ) {
return stream ; }
830 if ( sc.
isFailure() ) {
return stream ; }
834 % histo -> GetName ()
837 % histo -> GetTitle ()
843 % histo -> GetMean ()
844 % histo -> GetMeanError ()
848 % histo -> GetRMSError ()
851 % histo -> GetSkewness ()
854 % histo -> GetKurtosis ()
859 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |")
866 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
867 % histo -> GetEntries ()
868 % histo -> GetBinContent ( 0 )
869 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
870 % histo -> GetEffectiveEntries ()
875 return dumpText ( hist , width , height , errors , stream ) ;
889 (
const TProfile* histo ,
890 std::ostream& stream ,
891 const std::size_t width ,
892 const std::size_t height )
894 stream << std::endl ;
895 if ( ! histo ) {
return stream ; }
898 if ( sc.
isFailure() ) {
return stream ; }
902 % histo -> GetName ()
905 % histo -> GetTitle ()
917 <<
boost::format (
" Entries :\n | %=11s | %=11s | %=11s | %=11s |")
923 <<
boost::format (
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g |")
924 % histo -> GetEntries ()
925 % histo -> GetBinContent ( 0 )
926 % histo -> GetBinContent ( histo->GetNbinsX() + 1 )
931 return dumpText ( hist , width , height ,
true , stream ) ;
945 const std::size_t width ,
946 const std::size_t height ,
949 std::ostringstream stream ;
950 histoDump_ ( histo , stream , width , height , errors );
951 return stream.str() ;
964 (
const TProfile* histo ,
965 const std::size_t width ,
966 const std::size_t height )
968 std::ostringstream stream ;
969 histoDump_ ( histo , stream , width , height );
970 return stream.str() ;
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
auto begin(reverse_wrapper< T > &w)
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)
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
auto end(reverse_wrapper< T > &w)
This class is used for returning status codes from appropriate routines.
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)
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 kurtosisErr(const AIDA::IHistogram1D *histo)
get the error in kurtosis for the histogram
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