14 # pragma warning( disable : 2259 )
17 # pragma warning( disable : 1572 )
23 # pragma warning( disable : 4996 )
27 #include "AIDA/IAnnotation.h"
28 #include "AIDA/IAxis.h"
29 #include "AIDA/IHistogram1D.h"
30 #include "AIDA/IProfile1D.h"
38 #include <fmt/format.h>
64 Bin(
const double h = 0,
const double e = 0,
const double l = -1 ) : height(
h ), error( e ), lower(
l ) {}
73 Bin& operator+=(
const Bin& right ) {
74 height +=
right.height;
75 const double e2 = error * error +
right.error *
right.error;
83 double maxY(
const bool withErr )
const {
86 [&](
double m,
const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
89 double minY(
const bool withErr )
const {
92 [&](
double m,
const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
95 Histo rebin(
const unsigned int bin )
const {
102 for (
unsigned int ibin = 0; ibin < bins.size(); ++ibin ) {
103 const Bin& current = bins[ibin];
104 if ( nh.bins.empty() ) {
105 nh.bins.push_back( current );
106 }
else if ( 0 == ibin % bin ) {
107 nh.bins.push_back( current );
109 nh.bins.back() += current;
115 int nullBin()
const {
116 for (
auto ib = bins.cbegin(); bins.cend() != ib + 1; ++ib ) {
117 if ( ib->lower <= 0 && 0 < ( ib + 1 )->lower ) {
return ib - bins.cbegin(); }
145 const TAxis* axis =
root->GetXaxis();
147 const int nbins = axis->GetNbins();
151 hist.under = Histo::Bin(
root->GetBinContent( 0 ),
root->GetBinError( 0 ), axis->GetXmin() );
153 hist.over = Histo::Bin(
root->GetBinContent( nbins + 1 ),
root->GetBinError( nbins + 1 ), axis->GetXmax() );
156 for (
int ibin = 1; ibin <= nbins; ++ibin ) {
158 hist.bins.emplace_back(
root->GetBinContent( ibin ),
root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
170 StatusCode _getHisto(
const TProfile*
root, Histo& hist,
const bool ) {
172 return _getHisto(
histo, hist );
182 StatusCode _getHisto(
const AIDA::IHistogram1D* aida, Histo& hist ) {
188 const AIDA::IAxis& axis = aida->axis();
189 const int nbins = axis.bins();
192 hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
193 aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
195 hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
198 for (
int ibin = 0; ibin < nbins; ++ibin ) {
200 hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
212 StatusCode _getHisto(
const AIDA::IProfile1D* aida, Histo& hist,
const bool spread ) {
218 const AIDA::IAxis& axis = aida->axis();
219 const int nbins = axis.bins();
223 Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
224 spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
228 Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
229 spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
232 for (
int ibin = 0; ibin < nbins; ++ibin ) {
234 hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
235 axis.binLowerEdge( ibin ) );
245 inline unsigned int rebin(
const unsigned int bins,
const unsigned int imax ) {
246 if ( 0 == imax ) {
return 1; }
247 unsigned int ibin = 1;
248 while ( bins > imax * ibin ) { ++ibin; }
265 auto r = decompose( -
v );
266 return {-
r.first,
r.second};
267 }
else if ( 0.1 >
v ) {
274 }
else if ( 1 <
v ) {
289 inline double _pow(
double x,
unsigned long n ) {
290 double y =
n % 2 ? x : 1;
293 if (
n % 2 ) { y *= x; }
298 inline double rValMin(
double v );
304 inline double rValMax(
double v ) {
309 return -1 * rValMin( -
v );
314 const double f =
std::ceil( 20 *
r.first ) / 2;
315 const int l =
r.second - 1;
316 return 0 <
l ? f * _pow( 10,
l ) : f / _pow( 10, -
l );
323 inline double rValMin(
double v ) {
328 return -1 * rValMax( -
v );
333 const int l =
r.second - 1;
334 return 0 <
l ? f * _pow( 10,
l ) : f / _pow( 10, -
l );
350 char symbBin(
const Histo::Bin& bin,
const double yLow,
const double yHigh,
const bool yNull,
const bool errors ) {
351 if ( errors && yLow <= bin.height && bin.height < yHigh ) {
354 else if ( errors && yHigh < bin.height - bin.error ) {
356 }
else if ( errors && yLow >= bin.height + bin.error ) {
358 }
else if ( errors ) {
360 }
else if ( yLow <= bin.height && bin.height < yHigh ) {
362 }
else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
365 else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
378 if ( 40 > width ) {
return dumpText(
histo, 40, height, errors,
stream ); }
379 if ( 200 < width ) {
return dumpText(
histo, 200, height, errors,
stream ); }
380 if ( 150 < height ) {
return dumpText(
histo, width, 150, errors,
stream ); }
381 if ( 20 > height ) {
return dumpText(
histo, width, 20, errors,
stream ); }
382 if ( height > width ) {
return dumpText(
histo, width, width, errors,
stream ); }
384 const unsigned int nBins =
histo.bins.size();
385 if ( nBins > width ) {
387 Histo
r =
histo.rebin( rebin( nBins, width ) );
388 return dumpText(
r, width, height, errors,
stream );
392 double yMax =
std::max( rValMax(
histo.maxY( errors ) ), 0.0 );
393 double yMin =
std::min( rValMin(
histo.minY( errors ) ), 0.0 );
395 if ( yMin == yMax ) { yMax = yMin + 1; }
399 if ( 1 >= _ny ) { _ny = 10; }
403 if ( 20 > yBins ) { yBins = 20; }
404 const double yScale = ( yMax - yMin ) / yBins;
416 : 0 == yBins % 7 ? 7 : 0 == yBins % 6 ? 6 : 0 == yBins % 5 ? 5 : 0 == yBins % 4 ? 4 : 10;
420 0 == nBins % 7 ? 7 : 0 == nBins % 6 ? 6 : 0 == nBins % 5 ? 5 : 0 == nBins % 4 ? 4 : 10;
422 int iNull =
histo.nullBin();
432 for (
int yLine = -1; yLine < yBins; ++yLine ) {
433 const double yHigh = yMax - yScale * yLine;
435 const double yLow = yMax - yScale * ( yLine + 1 );
439 const bool ynull = ( yLow <= 0 && 0 < yHigh );
440 const bool yfirst = -1 == yLine || yBins - 1 == yLine;
441 const bool ylab = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
444 line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
452 line1 += symbBin(
histo.under, yLow, yHigh, ynull, errors );
454 line1 += ynull ?
"-+" : ylab ?
" +" :
" |";
458 for (
auto ibin =
histo.bins.cbegin();
histo.bins.cend() != ibin; ++ibin ) {
460 const int i = ibin -
histo.bins.cbegin();
462 const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) !=
histo.bins.cend() && 0 < ( ibin + 1 )->lower;
463 const bool xlab = iNull == i % xSkip;
465 char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
468 if ( ( ynull || yfirst ) && xlab ) {
470 }
else if ( ynull || yfirst ) {
474 else if ( ylab && xnull ) {
476 }
else if ( xnull ) {
480 else if ( ylab || xlab ) {
489 std::string line3 = ynull ?
"->" : ylab ?
"+ " :
"| ";
492 line3 += symbBin(
histo.over, yLow, yHigh, ynull, errors );
500 for (
auto ib =
histo.bins.cbegin();
histo.bins.cend() != ib; ++ib ) { xlabels.
push_back( xLabel( ib->lower ) ); }
505 static const std::string s_UNDERFLOW(
"UNDERFLOW" );
506 static const std::string s_OVERFLOW(
" OVERFLOW" );
509 for (
unsigned int yLine = 0; yLine < 12; ++yLine ) {
512 if ( yLine < s_UNDERFLOW.size() ) {
513 line += s_UNDERFLOW[yLine];
520 if ( uLabel.
size() > yLine ) {
521 line += uLabel[yLine];
526 for (
auto ibin =
histo.bins.cbegin();
histo.bins.cend() != ibin; ++ibin ) {
527 int ib = ibin -
histo.bins.cbegin();
528 const bool xlab = ( iNull == ib % xSkip );
529 if ( xlab && yLine < xlabels[ib].
size() ) {
530 line += xlabels[ib][yLine];
536 if ( oLabel.
size() > yLine ) {
537 line += oLabel[yLine];
544 if ( yLine < s_OVERFLOW.size() ) {
545 line += s_OVERFLOW[yLine];
579 Mean : {:11.5g} +- {:<10.4g}
580 Rms : {:11.5g} +- {:<10.4g}
581 Skewness : {:11.5g} +- {:<10.4g}
582 Kurtosis : {:11.5g} +- {:<10.4g}
585 | All | In Range | Underflow | Overflow | #Equivalent | Integral | Total |
586 | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
594 histo->allEntries(),
histo->entries(),
histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
595 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ),
histo->equivalentBinEntries(),
596 histo->sumBinHeights(),
histo->sumAllBinHeights() );
598 const AIDA::IAnnotation& a =
histo->annotation();
600 stream <<
" Annotation\n";
601 for (
int i = 0; i < a.size(); ++i ) {
602 stream <<
fmt::format(
" | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
607 return dumpText( hist, width, height, errors,
stream );
654 | All | In Range | Underflow | Overflow | Integral | Total |
655 | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} |
660 histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
661 histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ),
histo->sumBinHeights(),
662 histo->sumAllBinHeights() );
664 const AIDA::IAnnotation& a =
histo->annotation();
666 stream <<
" Annotation\n";
667 for (
int i = 0; i < a.size(); ++i ) {
668 stream <<
fmt::format(
" | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
673 return dumpText( hist, width, height,
true,
stream );
704 const TProfile* profile =
dynamic_cast<const TProfile*
>(
histo );
716 Mean : {:11.5g} +- {:<10.4g}
717 Rms : {:11.5g} +- {:<10.4g}
722 | All | Underflow | Overflow | #Equivalent | Integral |
723 | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
729 histo->GetBinContent(
histo->GetNbinsX() + 1 ),
histo->GetEffectiveEntries(),
732 return dumpText( hist, width, height, errors,
stream );
760 | All | Underflow | Overflow | Integral |
761 | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
769 return dumpText( hist, width, height,
true,
stream );
782 const bool errors ) {