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" 73 Bin(
const double h = 0,
const double e = 0,
const double l = -1 ) : height( h ), error( e ), lower(
l ) {}
82 Bin& operator+=(
const Bin& right )
84 height += right.height;
85 const double e2 = error * error + right.error * right.error;
93 double maxY(
const bool withErr )
const 97 [&](
double m,
const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
100 double minY(
const bool withErr )
const 104 [&](
double m,
const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
107 Histo rebin(
const unsigned int bin )
const 115 for (
unsigned int ibin = 0; ibin < bins.size(); ++ibin ) {
116 const Bin& current = bins[ibin];
117 if ( nh.bins.empty() ) {
118 nh.bins.push_back( current );
119 }
else if ( 0 == ibin % bin ) {
120 nh.bins.push_back( current );
122 nh.bins.back() += current;
130 for (
auto ib = bins.cbegin(); bins.cend() != ib + 1; ++ib ) {
131 if ( ib->lower <= 0 && 0 < ( ib + 1 )->lower ) {
132 return ib - bins.cbegin();
164 const TAxis* axis = root->GetXaxis();
168 const int nbins = axis->GetNbins();
174 hist.under = Histo::Bin( root->GetBinContent( 0 ), root->GetBinError( 0 ), axis->GetXmin() );
176 hist.over = Histo::Bin( root->GetBinContent( nbins + 1 ), root->GetBinError( nbins + 1 ), axis->GetXmax() );
179 for (
int ibin = 1; ibin <= nbins; ++ibin ) {
181 hist.bins.emplace_back( root->GetBinContent( ibin ), root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
193 StatusCode _getHisto(
const TProfile* root, Histo& hist,
const bool )
195 const TH1* histo =
root;
196 return _getHisto( histo, hist );
206 StatusCode _getHisto(
const AIDA::IHistogram1D* aida, Histo& hist )
215 const AIDA::IAxis& axis = aida->axis();
216 const int nbins = axis.bins();
219 hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
220 aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
222 hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
225 for (
int ibin = 0; ibin < nbins; ++ibin ) {
227 hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
239 StatusCode _getHisto(
const AIDA::IProfile1D* aida, Histo& hist,
const bool spread )
248 const AIDA::IAxis& axis = aida->axis();
249 const int nbins = axis.bins();
253 Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
254 spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
258 Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
259 spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
262 for (
int ibin = 0; ibin < nbins; ++ibin ) {
264 hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
265 axis.binLowerEdge( ibin ) );
275 inline unsigned int rebin(
const unsigned int bins,
const unsigned int imax )
280 unsigned int ibin = 1;
281 while ( bins > imax * ibin ) {
301 auto r = decompose( -v );
302 return {-r.first, r.second};
303 }
else if ( 0.1 > v ) {
310 }
else if ( 1 < v ) {
325 inline double _pow(
double x,
unsigned long n )
327 double y = n % 2 ? x : 1;
337 inline double rValMin(
double v );
343 inline double rValMax(
double v )
349 return -1 * rValMin( -v );
354 const double f =
std::ceil( 20 * r.first ) / 2;
355 const int l = r.second - 1;
356 return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
363 inline double rValMin(
double v )
369 return -1 * rValMax( -v );
373 const double f =
std::floor( 20 * r.first ) / 2;
374 const int l = r.second - 1;
375 return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
401 char symbBin(
const Histo::Bin& bin,
const double yLow,
const double yHigh,
const bool yNull,
const bool errors )
403 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
406 else if ( errors && yHigh < bin.height - bin.error ) {
408 }
else if ( errors && yLow >= bin.height + bin.error ) {
410 }
else if ( errors ) {
412 }
else if ( yLow <= bin.height && bin.height < yHigh ) {
414 }
else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
417 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
432 return dumpText( histo, 40, height, errors, stream );
435 return dumpText( histo, 200, height, errors, stream );
437 if ( 150 < height ) {
438 return dumpText( histo, width, 150, errors, stream );
441 return dumpText( histo, width, 20, errors, stream );
443 if ( height > width ) {
444 return dumpText( histo, width, width, errors, stream );
447 const unsigned int nBins = histo.bins.size();
448 if ( nBins > width ) {
450 Histo r = histo.rebin( rebin( nBins, width ) );
451 return dumpText( r, width, height, errors, stream );
455 double yMax =
std::max( rValMax( histo.maxY( errors ) ), 0.0 );
456 double yMin =
std::min( rValMin( histo.minY( errors ) ), 0.0 );
458 if ( yMin == yMax ) {
473 const double yScale = ( yMax - yMin ) / yBins;
485 : 0 == yBins % 7 ? 7 : 0 == yBins % 6 ? 6 : 0 == yBins % 5 ? 5 : 0 == yBins % 4 ? 4 : 10;
489 0 == nBins % 7 ? 7 : 0 == nBins % 6 ? 6 : 0 == nBins % 5 ? 5 : 0 == nBins % 4 ? 4 : 10;
491 int iNull = histo.nullBin();
501 for (
int yLine = -1; yLine < yBins; ++yLine ) {
502 const double yHigh = yMax - yScale * yLine;
504 const double yLow = yMax - yScale * ( yLine + 1 );
508 const bool ynull = ( yLow <= 0 && 0 < yHigh );
509 const bool yfirst = -1 == yLine || yBins - 1 == yLine;
510 const bool ylab = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
513 line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
521 line1 += symbBin( histo.under, yLow, yHigh, ynull, errors );
523 line1 += ynull ?
"-+" : ylab ?
" +" :
" |";
527 for (
auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
529 const int i = ibin - histo.bins.cbegin();
531 const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < ( ibin + 1 )->lower;
532 const bool xlab = iNull == i % xSkip;
534 char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
537 if ( ( ynull || yfirst ) && xlab ) {
539 }
else if ( ynull || yfirst ) {
543 else if ( ylab && xnull ) {
545 }
else if ( xnull ) {
549 else if ( ylab || xlab ) {
558 std::string line3 = ynull ?
"->" : ylab ?
"+ " :
"| ";
561 line3 += symbBin( histo.over, yLow, yHigh, ynull, errors );
563 stream << line1 << line2 << line3 <<
std::endl;
569 for (
auto ib = histo.bins.cbegin(); histo.bins.cend() != ib; ++ib ) {
570 xlabels.
push_back( xLabel( ib->lower ) );
573 const std::string oLabel = xLabel( histo.over.lower );
574 const std::string uLabel = xLabel( histo.under.lower );
576 static const std::string s_UNDERFLOW(
"UNDERFLOW" );
577 static const std::string s_OVERFLOW(
" OVERFLOW" );
580 for (
unsigned int yLine = 0; yLine < 12; ++yLine ) {
583 if ( yLine < s_UNDERFLOW.size() ) {
584 line += s_UNDERFLOW[yLine];
591 if ( uLabel.
size() > yLine ) {
592 line += uLabel[yLine];
597 for (
auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
598 int ib = ibin - histo.bins.cbegin();
599 const bool xlab = ( iNull == ib % xSkip );
600 if ( xlab && yLine < xlabels[ib].
size() ) {
601 line += xlabels[ib][yLine];
607 if ( oLabel.
size() > yLine ) {
608 line += oLabel[yLine];
615 if ( yLine < s_OVERFLOW.size() ) {
616 line += s_OVERFLOW[yLine];
653 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->title() << std::endl
670 stream <<
boost::format(
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |" ) %
"All" %
671 "In Range" %
"Underflow" %
"Overflow" %
"#Equivalent" %
"Integral" %
"Total" 673 <<
boost::format(
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g | %=11.5g |" ) % histo->allEntries() %
674 histo->entries() % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) %
675 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) % histo->equivalentBinEntries() %
676 histo->sumBinHeights() % histo->sumAllBinHeights()
680 const AIDA::IAnnotation& a = histo->annotation();
681 if ( 0 != a.size() ) {
683 for (
int i = 0; i < a.size(); ++i ) {
689 return dumpText( hist, width, height, errors, stream );
707 histoDump_( histo, stream, width, height, errors );
730 StatusCode sc = _getHisto( histo, hist, spread );
736 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->title() << std::endl
739 stream <<
boost::format(
" Mean : %11.5g " ) % histo->mean() << std::endl
740 <<
boost::format(
" Rms : %11.5g " ) % histo->rms() << std::endl
743 stream <<
boost::format(
" Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |" ) %
"All" %
"In Range" %
744 "Underflow" %
"Overflow" 746 %
"Integral" %
"Total" 748 <<
boost::format(
" | %=9d | %=9d | %=9d | %=9d | %=11.5g | %=11.5g |" ) % histo->allEntries() %
749 histo->entries() % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) %
750 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN )
752 % histo->sumBinHeights() % histo->sumAllBinHeights()
756 const AIDA::IAnnotation& a = histo->annotation();
757 if ( 0 != a.size() ) {
759 for (
int i = 0; i < a.size(); ++i ) {
765 return dumpText( hist, width, height,
true, stream );
781 histoDump_( histo, stream, width, height, spread );
798 const TProfile* profile =
dynamic_cast<const TProfile*
>( histo );
800 return histoDump_( profile, stream, width, height );
813 stream <<
boost::format(
" Histo Name : \"%s\"" ) % histo->GetName() << std::endl
814 <<
boost::format(
" Histo Title : \"%s\"" ) % histo->GetTitle() << std::endl
817 stream <<
boost::format(
" Mean : %11.5g +- %-10.4g " ) % histo->GetMean() % histo->GetMeanError() << std::endl
818 <<
boost::format(
" Rms : %11.5g +- %-10.4g " ) % histo->GetRMS() % histo->GetRMSError() << std::endl
819 <<
boost::format(
" Skewness : %11.5g " ) % histo->GetSkewness() << std::endl
820 <<
boost::format(
" Kurtosis : %11.5g " ) % histo->GetKurtosis() << std::endl
823 stream <<
boost::format(
" Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |" ) %
"All" %
"Underflow" %
824 "Overflow" %
"#Equivalent" %
"Integral" 826 <<
boost::format(
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g | %=11.5g |" ) % histo->GetEntries() %
827 histo->GetBinContent( 0 ) % histo->GetBinContent( histo->GetNbinsX() + 1 ) %
828 histo->GetEffectiveEntries() % histo->Integral()
832 return dumpText( hist, width, height, errors, stream );
853 StatusCode sc = _getHisto( histo, hist,
true );
858 stream <<
boost::format(
" Profile Name : \"%s\"" ) % histo->GetName() << std::endl
859 <<
boost::format(
" Profile Title : \"%s\"" ) % histo->GetTitle() << std::endl
862 stream <<
boost::format(
" Mean : %11.5g " ) % histo->GetMean() << std::endl
863 <<
boost::format(
" Rms : %11.5g " ) % histo->GetRMS() << std::endl
866 stream <<
boost::format(
" Entries :\n | %=11s | %=11s | %=11s | %=11s |" ) %
"All" %
"Underflow" %
"Overflow" %
869 <<
boost::format(
" | %=11.5g | %=11.5g | %=11.5g | %=11.5g |" ) % histo->GetEntries() %
870 histo->GetBinContent( 0 ) % histo->GetBinContent( histo->GetNbinsX() + 1 ) % histo->Integral()
874 return dumpText( hist, width, height,
true, stream );
890 histoDump_( histo, stream, width, height, errors );
constexpr static const auto FAILURE
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
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.
constexpr static const auto SUCCESS
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