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;
 
  407     const int ySkip = 0 == yBins % 13   ? 13
 
  408                       : 0 == yBins % 11 ? 11
 
  425     int iNull = 
histo.nullBin();
 
  435     for ( 
int yLine = -1; yLine < yBins; ++yLine ) {
 
  436       const double yHigh = yMax - yScale * yLine;
 
  438       const double yLow = yMax - yScale * ( yLine + 1 );
 
  442       const bool ynull  = ( yLow <= 0 && 0 < yHigh );
 
  443       const bool yfirst = -1 == yLine || yBins - 1 == yLine;
 
  444       const bool ylab   = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
 
  447         line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
 
  455       line1 += symbBin( 
histo.under, yLow, yHigh, ynull, errors );
 
  457       line1 += ynull ? 
"-+" : ylab ? 
" +" : 
" |";
 
  461       for ( 
auto ibin = 
histo.bins.cbegin(); 
histo.bins.cend() != ibin; ++ibin ) {
 
  463         const int i = ibin - 
histo.bins.cbegin();
 
  465         const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != 
histo.bins.cend() && 0 < ( ibin + 1 )->lower;
 
  466         const bool xlab  = iNull == i % xSkip;
 
  468         char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
 
  471           if ( ( ynull || yfirst ) && xlab ) {
 
  473           } 
else if ( ynull || yfirst ) {
 
  477           else if ( ylab && xnull ) {
 
  479           } 
else if ( xnull ) {
 
  483           else if ( ylab || xlab ) {
 
  492       std::string line3 = ynull ? 
"->" : ylab ? 
"+ " : 
"| ";
 
  495       line3 += symbBin( 
histo.over, yLow, yHigh, ynull, errors );
 
  503     for ( 
auto ib = 
histo.bins.cbegin(); 
histo.bins.cend() != ib; ++ib ) { xlabels.
push_back( xLabel( ib->lower ) ); }
 
  508     static const std::string s_UNDERFLOW( 
"UNDERFLOW" );
 
  509     static const std::string s_OVERFLOW( 
" OVERFLOW" );
 
  512     for ( 
unsigned int yLine = 0; yLine < 12; ++yLine ) {
 
  515       if ( yLine < s_UNDERFLOW.size() ) {
 
  516         line += s_UNDERFLOW[yLine];
 
  523       if ( uLabel.
size() > yLine ) {
 
  524         line += uLabel[yLine];
 
  529       for ( 
auto ibin = 
histo.bins.cbegin(); 
histo.bins.cend() != ibin; ++ibin ) {
 
  530         int        ib   = ibin - 
histo.bins.cbegin();
 
  531         const bool xlab = ( iNull == ib % xSkip );
 
  532         if ( xlab && yLine < xlabels[ib].
size() ) {
 
  533           line += xlabels[ib][yLine];
 
  539       if ( oLabel.
size() > yLine ) {
 
  540         line += oLabel[yLine];
 
  547       if ( yLine < s_OVERFLOW.size() ) {
 
  548         line += s_OVERFLOW[yLine];
 
  582  Mean        : {:11.5g} +- {:<10.4g} 
  583  Rms         : {:11.5g} +- {:<10.4g} 
  584  Skewness    : {:11.5g} +- {:<10.4g} 
  585  Kurtosis    : {:11.5g} +- {:<10.4g} 
  588  |    All    |  In Range | Underflow |  Overflow | #Equivalent |   Integral  |    Total    | 
  589  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} | {:^11.5g} | 
  597                          histo->allEntries(), 
histo->entries(), 
histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
 
  598                          histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), 
histo->equivalentBinEntries(),
 
  599                          histo->sumBinHeights(), 
histo->sumAllBinHeights() );
 
  601   const AIDA::IAnnotation& a = 
histo->annotation();
 
  603     stream << 
" Annotation\n";
 
  604     for ( 
int i = 0; i < a.size(); ++i ) {
 
  605       stream << 
fmt::format( 
" | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
 
  610   return dumpText( hist, width, height, errors, 
stream );
 
  657  |    All    |  In Range | Underflow |  Overflow |   Integral  |    Total    | 
  658  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} | 
  663                          histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
 
  664                          histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), 
histo->sumBinHeights(),
 
  665                          histo->sumAllBinHeights() );
 
  667   const AIDA::IAnnotation& a = 
histo->annotation();
 
  669     stream << 
" Annotation\n";
 
  670     for ( 
int i = 0; i < a.size(); ++i ) {
 
  671       stream << 
fmt::format( 
" | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
 
  676   return dumpText( hist, width, height, 
true, 
stream );
 
  707   const TProfile* profile = 
dynamic_cast<const TProfile*
>( 
histo );
 
  719  Mean        : {:11.5g} +- {:<10.4g} 
  720  Rms         : {:11.5g} +- {:<10.4g} 
  725  |     All     |  Underflow  |   Overflow  | #Equivalent |   Integral  | 
  726  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | 
  732                          histo->GetBinContent( 
histo->GetNbinsX() + 1 ), 
histo->GetEffectiveEntries(),
 
  735   return dumpText( hist, width, height, errors, 
stream );
 
  763  |     All     |  Underflow  |   Overflow  |   Integral  | 
  764  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | 
  772   return dumpText( hist, width, height, 
true, 
stream );
 
  785                                              const bool errors ) {