4 # pragma warning( disable : 2259 ) 7 # pragma warning( disable : 1572 ) 13 # pragma warning( disable : 4996 ) 29 #include "AIDA/IAnnotation.h" 30 #include "AIDA/IAxis.h" 31 #include "AIDA/IHistogram1D.h" 32 #include "AIDA/IProfile1D.h" 46 #include "boost/format.hpp" 72 Bin(
const double h = 0,
const double e = 0,
const double l = -1 ) : height( h ), error( e ), lower(
l ) {}
81 Bin& operator+=(
const Bin& right ) {
82 height += right.height;
83 const double e2 = error * error + right.error * right.error;
91 double maxY(
const bool withErr )
const {
94 [&](
double m,
const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
97 double minY(
const bool withErr )
const {
100 [&](
double m,
const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
103 Histo rebin(
const unsigned int bin )
const {
110 for (
unsigned int ibin = 0; ibin < bins.size(); ++ibin ) {
111 const Bin& current = bins[ibin];
112 if ( nh.bins.empty() ) {
113 nh.bins.push_back( current );
114 }
else if ( 0 == ibin % bin ) {
115 nh.bins.push_back( current );
117 nh.bins.back() += current;
123 int nullBin()
const {
124 for (
auto ib = bins.cbegin(); bins.cend() != ib + 1; ++ib ) {
125 if ( ib->lower <= 0 && 0 < ( ib + 1 )->lower ) {
return ib - bins.cbegin(); }
153 const TAxis* axis = root->GetXaxis();
155 const int nbins = axis->GetNbins();
159 hist.under = Histo::Bin( root->GetBinContent( 0 ), root->GetBinError( 0 ), axis->GetXmin() );
161 hist.over = Histo::Bin( root->GetBinContent( nbins + 1 ), root->GetBinError( nbins + 1 ), axis->GetXmax() );
164 for (
int ibin = 1; ibin <= nbins; ++ibin ) {
166 hist.bins.emplace_back( root->GetBinContent( ibin ), root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
178 StatusCode _getHisto(
const TProfile* root, Histo& hist,
const bool ) {
179 const TH1* histo =
root;
180 return _getHisto( histo, hist );
190 StatusCode _getHisto(
const AIDA::IHistogram1D* aida, Histo& hist ) {
196 const AIDA::IAxis& axis = aida->axis();
197 const int nbins = axis.bins();
200 hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
201 aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
203 hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
206 for (
int ibin = 0; ibin < nbins; ++ibin ) {
208 hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
220 StatusCode _getHisto(
const AIDA::IProfile1D* aida, Histo& hist,
const bool spread ) {
226 const AIDA::IAxis& axis = aida->axis();
227 const int nbins = axis.bins();
231 Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
232 spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
236 Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
237 spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
240 for (
int ibin = 0; ibin < nbins; ++ibin ) {
242 hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
243 axis.binLowerEdge( ibin ) );
253 inline unsigned int rebin(
const unsigned int bins,
const unsigned int imax ) {
254 if ( 0 == imax ) {
return 1; }
255 unsigned int ibin = 1;
256 while ( bins > imax * ibin ) { ++ibin; }
273 auto r = decompose( -v );
274 return {-r.first, r.second};
275 }
else if ( 0.1 > v ) {
282 }
else if ( 1 < v ) {
297 inline double _pow(
double x,
unsigned long n ) {
298 double y = n % 2 ? x : 1;
301 if ( n % 2 ) { y *= x; }
306 inline double rValMin(
double v );
312 inline double rValMax(
double v ) {
317 return -1 * rValMin( -v );
322 const double f =
std::ceil( 20 * r.first ) / 2;
323 const int l = r.second - 1;
324 return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
331 inline double rValMin(
double v ) {
336 return -1 * rValMax( -v );
340 const double f =
std::floor( 20 * r.first ) / 2;
341 const int l = r.second - 1;
342 return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
366 char symbBin(
const Histo::Bin& bin,
const double yLow,
const double yHigh,
const bool yNull,
const bool errors ) {
367 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
370 else if ( errors && yHigh < bin.height - bin.error ) {
372 }
else if ( errors && yLow >= bin.height + bin.error ) {
374 }
else if ( errors ) {
376 }
else if ( yLow <= bin.height && bin.height < yHigh ) {
378 }
else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
381 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
394 if ( 40 > width ) {
return dumpText( histo, 40, height, errors, stream ); }
395 if ( 200 < width ) {
return dumpText( histo, 200, height, errors, stream ); }
396 if ( 150 < height ) {
return dumpText( histo, width, 150, errors, stream ); }
397 if ( 20 > height ) {
return dumpText( histo, width, 20, errors, stream ); }
398 if ( height > width ) {
return dumpText( histo, width, width, errors, stream ); }
400 const unsigned int nBins = histo.bins.size();
401 if ( nBins > width ) {
403 Histo r = histo.rebin( rebin( nBins, width ) );
404 return dumpText( r, width, height, errors, stream );
408 double yMax =
std::max( rValMax( histo.maxY( errors ) ), 0.0 );
409 double yMin =
std::min( rValMin( histo.minY( errors ) ), 0.0 );
411 if ( yMin == yMax ) { yMax = yMin + 1; }
415 if ( 1 >= _ny ) { _ny = 10; }
419 if ( 20 > yBins ) { yBins = 20; }
420 const double yScale = ( yMax - yMin ) / yBins;
432 : 0 == yBins % 7 ? 7 : 0 == yBins % 6 ? 6 : 0 == yBins % 5 ? 5 : 0 == yBins % 4 ? 4 : 10;
436 0 == nBins % 7 ? 7 : 0 == nBins % 6 ? 6 : 0 == nBins % 5 ? 5 : 0 == nBins % 4 ? 4 : 10;
438 int iNull = histo.nullBin();
448 for (
int yLine = -1; yLine < yBins; ++yLine ) {
449 const double yHigh = yMax - yScale * yLine;
451 const double yLow = yMax - yScale * ( yLine + 1 );
455 const bool ynull = ( yLow <= 0 && 0 < yHigh );
456 const bool yfirst = -1 == yLine || yBins - 1 == yLine;
457 const bool ylab = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
460 line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
468 line1 += symbBin( histo.under, yLow, yHigh, ynull, errors );
470 line1 += ynull ?
"-+" : ylab ?
" +" :
" |";
474 for (
auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
476 const int i = ibin - histo.bins.cbegin();
478 const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < ( ibin + 1 )->lower;
479 const bool xlab = iNull == i % xSkip;
481 char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
484 if ( ( ynull || yfirst ) && xlab ) {
486 }
else if ( ynull || yfirst ) {
490 else if ( ylab && xnull ) {
492 }
else if ( xnull ) {
496 else if ( ylab || xlab ) {
505 std::string line3 = ynull ?
"->" : ylab ?
"+ " :
"| ";
508 line3 += symbBin( histo.over, yLow, yHigh, ynull, errors );
510 stream << line1 << line2 << line3 <<
std::endl;
516 for (
auto ib = histo.bins.cbegin(); histo.bins.cend() != ib; ++ib ) { xlabels.
push_back( xLabel( ib->lower ) ); }
518 const std::string oLabel = xLabel( histo.over.lower );
519 const std::string uLabel = xLabel( histo.under.lower );
521 static const std::string s_UNDERFLOW(
"UNDERFLOW" );
522 static const std::string s_OVERFLOW(
" OVERFLOW" );
525 for (
unsigned int yLine = 0; yLine < 12; ++yLine ) {
528 if ( yLine < s_UNDERFLOW.size() ) {
529 line += s_UNDERFLOW[yLine];
536 if ( uLabel.
size() > yLine ) {
537 line += uLabel[yLine];
542 for (
auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
543 int ib = ibin - histo.bins.cbegin();
544 const bool xlab = ( iNull == ib % xSkip );
545 if ( xlab && yLine < xlabels[ib].
size() ) {
546 line += xlabels[ib][yLine];
552 if ( oLabel.
size() > yLine ) {
553 line += oLabel[yLine];
560 if ( yLine < s_OVERFLOW.size() ) {
561 line += s_OVERFLOW[yLine];
587 if ( !histo ) {
return stream; }
593 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->title() << std::endl
610 stream <<
boost::format(
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |" ) %
"All" %
611 "In Range" %
"Underflow" %
"Overflow" %
"#Equivalent" %
"Integral" %
"Total" 613 <<
boost::format(
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g | %=11.5g |" ) % histo->allEntries() %
614 histo->entries() % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) %
615 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) % histo->equivalentBinEntries() %
616 histo->sumBinHeights() % histo->sumAllBinHeights()
620 const AIDA::IAnnotation& a = histo->annotation();
621 if ( 0 != a.size() ) {
623 for (
int i = 0; i < a.size(); ++i ) {
629 return dumpText( hist, width, height, errors, stream );
646 histoDump_( histo, stream, width, height, errors );
664 if ( !histo ) {
return stream; }
666 StatusCode sc = _getHisto( histo, hist, spread );
670 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->title() << std::endl
673 stream <<
boost::format(
" Mean : %11.5g " ) % histo->mean() << std::endl
674 <<
boost::format(
" Rms : %11.5g " ) % histo->rms() << std::endl
677 stream <<
boost::format(
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |" ) %
"All" %
"In Range" %
681 %
"Integral" %
"Total" 683 <<
boost::format(
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g |" ) % histo->allEntries() %
684 histo->entries() % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) %
685 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN )
687 % histo->sumBinHeights() % histo->sumAllBinHeights()
691 const AIDA::IAnnotation& a = histo->annotation();
692 if ( 0 != a.size() ) {
694 for (
int i = 0; i < a.size(); ++i ) {
700 return dumpText( hist, width, height,
true, stream );
715 histoDump_( histo, stream, width, height, spread );
731 const TProfile* profile =
dynamic_cast<const TProfile*
>( histo );
732 if ( profile ) {
return histoDump_( profile, stream, width, height ); }
735 if ( !histo ) {
return stream; }
740 stream <<
boost::format(
" Histo Name : \"%s\"" ) % histo->GetName() << std::endl
741 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->GetTitle() << std::endl
744 stream <<
boost::format(
" Mean : %11.5g +- %-10.4g " ) % histo->GetMean() % histo->GetMeanError() << std::endl
745 <<
boost::format(
" Rms : %11.5g +- %-10.4g " ) % histo->GetRMS() % histo->GetRMSError() << std::endl
746 <<
boost::format(
" Skewness : %11.5g " ) % histo->GetSkewness() << std::endl
747 <<
boost::format(
" Kurtosis : %11.5g " ) % histo->GetKurtosis() << std::endl
750 stream <<
boost::format(
" Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |" ) %
"All" %
"Underflow" %
751 "Overflow" %
"#Equivalent" %
"Integral" 753 <<
boost::format(
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g | %=11.5g |" ) % histo->GetEntries() %
754 histo->GetBinContent( 0 ) % histo->GetBinContent( histo->GetNbinsX() + 1 ) %
755 histo->GetEffectiveEntries() % histo->Integral()
759 return dumpText( hist, width, height, errors, stream );
775 if ( !histo ) {
return stream; }
777 StatusCode sc = _getHisto( histo, hist,
true );
780 stream <<
boost::format(
" Profile Name : \"%s\"" ) % histo->GetName() << std::endl
781 <<
boost::format(
" Profile Title : \"%s\"" ) % histo->GetTitle() << std::endl
784 stream <<
boost::format(
" Mean : %11.5g " ) % histo->GetMean() << std::endl
785 <<
boost::format(
" Rms : %11.5g " ) % histo->GetRMS() << std::endl
788 stream <<
boost::format(
" Entries :\n | %=11s | %=11s | %=11s | %=11s |" ) %
"All" %
"Underflow" %
"Overflow" %
791 <<
boost::format(
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g |" ) % histo->GetEntries() %
792 histo->GetBinContent( 0 ) % histo->GetBinContent( histo->GetNbinsX() + 1 ) % histo->Integral()
796 return dumpText( hist, width, height,
true, stream );
809 const bool errors ) {
811 histoDump_( histo, stream, width, height, errors );
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
constexpr static const auto SUCCESS
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
constexpr auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
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
constexpr static const auto FAILURE
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