The Gaudi Framework  master (37c0b60a)
HistoDump.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #ifdef __ICC
12 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
13 // TODO: To be removed, since it comes from ROOT TMathBase.h
14 # pragma warning( disable : 2259 )
15 #endif
16 #ifdef WIN32
17 // Disable warning
18 // warning C4996: 'sprintf': This function or variable may be unsafe.
19 // coming from TString.h
20 # pragma warning( disable : 4996 )
21 #endif
22 
23 #include <AIDA/IAnnotation.h>
24 #include <AIDA/IAxis.h>
25 #include <AIDA/IHistogram1D.h>
26 #include <AIDA/IProfile1D.h>
27 #include <GaudiKernel/StatusCode.h>
28 #include <GaudiUtils/HistoDump.h>
29 #include <GaudiUtils/HistoStats.h>
31 #include <TAxis.h>
32 #include <TH1.h>
33 #include <TProfile.h>
34 #include <cmath>
35 #include <fmt/format.h>
36 #include <iostream>
37 #include <numeric>
38 #include <sstream>
39 #include <utility>
40 #include <vector>
41 
42 // ============================================================================
43 namespace {
44 
45  // idea coming from The art of computer programming by Knuth
46  constexpr bool essentiallyEqual( double const a, double const b ) {
47  return std::abs( a - b ) <= std::min( std::abs( a ), std::abs( b ) ) * std::numeric_limits<double>::epsilon();
48  }
49 
50  // ==========================================================================
56  struct Histo {
57  // ========================================================================
58  Histo() = default;
59  // ========================================================================
65  struct Bin {
66  // ======================================================================
67  Bin( const double h = 0, const double e = 0, const double l = -1 ) : height( h ), error( e ), lower( l ) {}
68  // ======================================================================
70  double height; // bin height
72  double error; // bin error
74  double lower; // lower edge
75  // ======================================================================
76  Bin& operator+=( const Bin& right ) {
77  height += right.height;
78  const double e2 = error * error + right.error * right.error;
79  error = std::sqrt( e2 );
80  return *this;
81  }
82  // ======================================================================
83  };
84  // ========================================================================
86  double maxY( const bool withErr ) const {
87  return std::accumulate(
88  std::begin( bins ), std::end( bins ), std::max( under.height, over.height ),
89  [&]( double m, const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
90  }
92  double minY( const bool withErr ) const {
93  return std::accumulate(
94  std::begin( bins ), std::end( bins ), std::min( under.height, over.height ),
95  [&]( double m, const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
96  }
98  Histo rebin( const unsigned int bin ) const {
99  // create new histogram
100  Histo nh;
101  // copy overflow & underflow bins
102  nh.under = under;
103  nh.over = over;
104  // rebin
105  for ( unsigned int ibin = 0; ibin < bins.size(); ++ibin ) {
106  const Bin& current = bins[ibin];
107  if ( nh.bins.empty() ) {
108  nh.bins.push_back( current );
109  } else if ( 0 == ibin % bin ) {
110  nh.bins.push_back( current );
111  } else {
112  nh.bins.back() += current;
113  }
114  }
115  return nh;
116  }
117  // find "null-bin", if any
118  int nullBin() const {
119  for ( auto ib = bins.cbegin(); bins.cend() != ib + 1; ++ib ) {
120  if ( ib->lower <= 0 && 0 < ( ib + 1 )->lower ) { return ib - bins.cbegin(); }
121  }
122  return -1;
123  }
124  // ========================================================================
125  typedef std::vector<Bin> Bins;
126  // ========================================================================
128  Bins bins; // histogram bins
130  Bin under; // underflow bin
132  Bin over; // overflow bin
133  // ========================================================================
134  };
135  // ==========================================================================
143  StatusCode _getHisto( const TH1* root, Histo& hist ) {
144  // clear the histogram
145  hist.bins.clear();
146  //
147  if ( !root ) { return StatusCode::FAILURE; } // RETURN
148  const TAxis* axis = root->GetXaxis();
149  if ( !axis ) { return StatusCode::FAILURE; } // RETURN
150  const int nbins = axis->GetNbins();
151  if ( 0 == nbins ) { return StatusCode::FAILURE; } // RETURN
152 
153  // underflow bin
154  hist.under = Histo::Bin( root->GetBinContent( 0 ), root->GetBinError( 0 ), axis->GetXmin() );
155  // overflow bin
156  hist.over = Histo::Bin( root->GetBinContent( nbins + 1 ), root->GetBinError( nbins + 1 ), axis->GetXmax() );
157  //
158  //
159  for ( int ibin = 1; ibin <= nbins; ++ibin ) {
160  // add to the local histo
161  hist.bins.emplace_back( root->GetBinContent( ibin ), root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
162  }
163  return StatusCode::SUCCESS;
164  }
165  // ==========================================================================
173  StatusCode _getHisto( const TProfile* root, Histo& hist, const bool /* spread */ ) {
174  const TH1* histo = root;
175  return _getHisto( histo, hist );
176  }
177  // ==========================================================================
185  StatusCode _getHisto( const AIDA::IHistogram1D* aida, Histo& hist ) {
186  // clear the histogram
187  hist.bins.clear();
188  //
189  if ( !aida ) { return StatusCode::FAILURE; } // RETURN
190  //
191  const AIDA::IAxis& axis = aida->axis();
192  const int nbins = axis.bins();
193  //
194  // underflow bin
195  hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
196  aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
197  // overflow bin
198  hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
199  axis.upperEdge() );
200  //
201  for ( int ibin = 0; ibin < nbins; ++ibin ) {
202  // add to the local histo
203  hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
204  }
205  return StatusCode::SUCCESS;
206  }
207  // ==========================================================================
215  StatusCode _getHisto( const AIDA::IProfile1D* aida, Histo& hist, const bool spread ) {
216  // clear the histogram
217  hist.bins.clear();
218  //
219  if ( !aida ) { return StatusCode::FAILURE; } // RETURN
220  //
221  const AIDA::IAxis& axis = aida->axis();
222  const int nbins = axis.bins();
223  //
224  // underflow bin
225  hist.under =
226  Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
227  spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
228  axis.lowerEdge() );
229  // overflow bin
230  hist.over =
231  Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
232  spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
233  axis.upperEdge() );
234  //
235  for ( int ibin = 0; ibin < nbins; ++ibin ) {
236  // add to the local histo
237  hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
238  axis.binLowerEdge( ibin ) );
239  }
240  return StatusCode::SUCCESS;
241  }
242  // ==========================================================================
248  inline unsigned int rebin( const unsigned int bins, const unsigned int imax ) {
249  if ( 0 == imax ) { return 1; } // RETURN
250  unsigned int ibin = 1;
251  while ( bins > imax * ibin ) { ++ibin; }
252  return ibin; // RETURN
253  }
254  // ==========================================================================
260  std::pair<double, int> decompose( double v ) {
262  return { 0.0, 0 };
263  } // RETURN
264  else if ( essentiallyEqual( 1.0, v ) ) {
265  return { 1.0, 0 };
266  } // RETURN
267  else if ( 0 > v ) {
268  auto r = decompose( -v );
269  return { -r.first, r.second }; // RETURN
270  } else if ( 0.1 > v ) {
271  int i = 0;
272  while ( 0.1 > v ) {
273  ++i;
274  v *= 10;
275  } // STUPID
276  return { v, -i };
277  } else if ( 1 < v ) {
278  int i = 0;
279  while ( 1 <= v ) {
280  ++i;
281  v /= 10;
282  } // STUPID
283  return { v, i };
284  }
285  return { v, 1 };
286  }
287  // ==========================================================================
292  inline double _pow( double x, unsigned long n ) {
293  double y = n % 2 ? x : 1;
294  while ( n >>= 1 ) {
295  x = x * x;
296  if ( n % 2 ) { y *= x; }
297  }
298  return y;
299  }
300  // forward declaration to break cyclic dependency between rValMin and rValMax
301  inline double rValMin( double v );
302  // ==========================================================================
307  inline double rValMax( double v ) {
308  if ( 0 > v ) { return -1 * rValMin( -v ); } // RETURN
309  // decompose the double value into decimal significand and mantissa
310  std::pair<double, int> r = decompose( v );
311  //
312  const double f = std::ceil( 20 * r.first ) / 2; // + 1 ;
313  const int l = r.second - 1;
314  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
315  }
316  // ==========================================================================
321  inline double rValMin( double v ) {
322  if ( 0 > v ) { return -1 * rValMax( -v ); } // RETURN
323  // decompose the double value into decimal significand and mantissa
324  std::pair<double, int> r = decompose( v );
325  const double f = std::floor( 20 * r.first ) / 2; // - 1 ;
326  const int l = r.second - 1;
327  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
328  }
329  // ==========================================================================
334  inline std::string yLabel( double value ) { return fmt::format( "{:10.3g}", value ); }
335  // ==========================================================================
340  inline std::string xLabel( const double value ) { return fmt::format( "{:9.3g}", value ); }
341  // ==========================================================================
343  char symbBin( const Histo::Bin& bin, const double yLow, const double yHigh, const bool yNull, const bool errors ) {
344  if ( errors && yLow <= bin.height && bin.height < yHigh ) {
345  return '*';
346  } // O
347  else if ( errors && yHigh < bin.height - bin.error ) {
348  return ' ';
349  } else if ( errors && yLow >= bin.height + bin.error ) {
350  return ' ';
351  } else if ( errors ) {
352  return 'I';
353  } else if ( yLow <= bin.height && bin.height < yHigh ) {
354  return '*';
355  } else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
356  return '*';
357  } // +
358  else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
359  return '*';
360  } // -
361  //
362  return ' ';
363  }
364  // ==========================================================================
369  std::ostringstream& dumpText( const Histo& histo, const std::size_t width, const std::size_t height,
370  const bool errors, std::ostringstream& stream ) {
371  if ( 40 > width ) { return dumpText( histo, 40, height, errors, stream ); }
372  if ( 200 < width ) { return dumpText( histo, 200, height, errors, stream ); }
373  if ( 150 < height ) { return dumpText( histo, width, 150, errors, stream ); }
374  if ( 20 > height ) { return dumpText( histo, width, 20, errors, stream ); }
375  if ( height > width ) { return dumpText( histo, width, width, errors, stream ); }
376  //
377  const unsigned int nBins = histo.bins.size();
378  if ( nBins > width ) {
379  // rebin histogram
380  Histo r = histo.rebin( rebin( nBins, width ) );
381  return dumpText( r, width, height, errors, stream );
382  }
383  //
384  // get the Y-scale
385  double yMax = std::max( rValMax( histo.maxY( errors ) ), 0.0 );
386  double yMin = std::min( rValMin( histo.minY( errors ) ), 0.0 );
387 
388  if ( essentiallyEqual( yMin, yMax ) ) { yMax = yMin + 1; }
390  std::pair<double, int> r = decompose( yMax - yMin );
391  double _ny = std::ceil( 10 * r.first ); // 1 <= ny < 10
392  if ( 1 >= _ny ) { _ny = 10; }
393  int yBins = (int)std::max( 1., std::ceil( height / _ny ) );
394 
395  yBins *= (int)_ny;
396  if ( 20 > yBins ) { yBins = 20; }
397  const double yScale = ( yMax - yMin ) / yBins;
398 
399  //
400  const int ySkip = 0 == yBins % 13 ? 13
401  : 0 == yBins % 11 ? 11
402  : 0 == yBins % 9 ? 9
403  : 0 == yBins % 8 ? 8
404  : 0 == yBins % 7 ? 7
405  : 0 == yBins % 6 ? 6
406  : 0 == yBins % 5 ? 5
407  : 0 == yBins % 4 ? 4
408  : 10;
409 
410  const int xSkip =
411  // 0 == nBins % 8 ? 8 :
412  0 == nBins % 7 ? 7
413  : 0 == nBins % 6 ? 6
414  : 0 == nBins % 5 ? 5
415  : 0 == nBins % 4 ? 4
416  : 10;
417 
418  int iNull = histo.nullBin();
419 
420  if ( 0 <= iNull ) {
421  iNull %= xSkip;
422  } else {
423  iNull = 0;
424  }
425 
426  stream << std::endl;
427 
428  for ( int yLine = -1; yLine < yBins; ++yLine ) {
429  const double yHigh = yMax - yScale * yLine;
430  // const double yLow = yHigh - yScale ;
431  const double yLow = yMax - yScale * ( yLine + 1 );
432  //
433  std::string line1 = " ";
434 
435  const bool ynull = ( yLow <= 0 && 0 < yHigh );
436  const bool yfirst = -1 == yLine || yBins - 1 == yLine;
437  const bool ylab = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
438 
439  if ( ylab ) {
440  line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
441  } else {
442  line1 += std::string( 10, ' ' );
443  }
444  //
445  line1 += " ";
446  //
448  line1 += symbBin( histo.under, yLow, yHigh, ynull, errors );
449  //
450  line1 += ynull ? "-+" : ylab ? " +" : " |";
451  //
452  std::string line2;
453  //
454  for ( auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
455  // char symb = ' ' ;
456  const int i = ibin - histo.bins.cbegin();
457  //
458  const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < ( ibin + 1 )->lower;
459  const bool xlab = iNull == i % xSkip;
460  //
461  char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
462  //
463  if ( ' ' == symb ) {
464  if ( ( ynull || yfirst ) && xlab ) {
465  symb = '+';
466  } else if ( ynull || yfirst ) {
467  symb = '-';
468  }
469  //
470  else if ( ylab && xnull ) {
471  symb = '+';
472  } else if ( xnull ) {
473  symb = '|';
474  }
475  //
476  else if ( ylab || xlab ) {
477  symb = '.';
478  }
479  //
480  }
481  line2 += symb;
482  //
483  }
484  //
485  std::string line3 = ynull ? "->" : ylab ? "+ " : "| ";
486  //
488  line3 += symbBin( histo.over, yLow, yHigh, ynull, errors );
489  //
490  stream << line1 << line2 << line3 << std::endl;
491  //
492  }
493 
494  // get x-labels
495  std::vector<std::string> xlabels;
496  for ( auto ib = histo.bins.cbegin(); histo.bins.cend() != ib; ++ib ) { xlabels.push_back( xLabel( ib->lower ) ); }
497  // overflow& underflow label
498  const std::string oLabel = xLabel( histo.over.lower );
499  const std::string uLabel = xLabel( histo.under.lower );
500  //
501  static const std::string s_UNDERFLOW( "UNDERFLOW" );
502  static const std::string s_OVERFLOW( " OVERFLOW" );
503  //
504  //
505  for ( unsigned int yLine = 0; yLine < 12; ++yLine ) {
506  std::string line = std::string( 12, ' ' );
507  //
508  if ( yLine < s_UNDERFLOW.size() ) {
509  line += s_UNDERFLOW[yLine];
510  } else {
511  line += ' ';
512  }
513  //
514  line += ' ';
515  //
516  if ( uLabel.size() > yLine ) {
517  line += uLabel[yLine];
518  } else {
519  line += ' ';
520  }
521  //
522  for ( auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
523  int ib = ibin - histo.bins.cbegin();
524  const bool xlab = ( iNull == ib % xSkip );
525  if ( xlab && yLine < xlabels[ib].size() ) {
526  line += xlabels[ib][yLine];
527  } else {
528  line += ' ';
529  }
530  }
531  //
532  if ( oLabel.size() > yLine ) {
533  line += oLabel[yLine];
534  } else {
535  line += ' ';
536  }
537  //
538  line += ' ';
539  //
540  if ( yLine < s_OVERFLOW.size() ) {
541  line += s_OVERFLOW[yLine];
542  } else {
543  line += ' ';
544  }
545  //
546  stream << line << std::endl;
547  }
548  //
549  return stream; // RETURN
550  }
551 } // namespace
552 
553 // ============================================================================
554 /* dump the text representation of the histogram
555  * @param histo the histogram
556  * @param stream the stream
557  * @param width the maximal column width
558  * @param height (INPUT) the proposed coulmn height
559  * @param errors (INPUT) print/plot errors
560  * @param erorrs print/plot errors
561  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
562  * @date 2009-09-19
563  */
564 // ============================================================================
565 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IHistogram1D* histo, const std::size_t width,
566  const std::size_t height, const bool errors ) {
568  stream << std::endl;
569  if ( !histo ) { return stream.str(); } // RETURN
570  Histo hist;
571  StatusCode sc = _getHisto( histo, hist );
572  if ( sc.isFailure() ) { return stream.str(); } // RETURN
573 
574  stream << fmt::format( R"( Histo TES : "{}"
575  Histo Title : "{}"
576 
577  Mean : {:11.5g} +- {:<10.4g}
578  Rms : {:11.5g} +- {:<10.4g}
579  Skewness : {:11.5g} +- {:<10.4g}
580  Kurtosis : {:11.5g} +- {:<10.4g}
581 
582  Entries :
583  | All | In Range | Underflow | Overflow | #Equivalent | Integral | Total |
584  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
585 
586 )",
587  path( histo ), histo->title(), //
592  histo->allEntries(), histo->entries(), histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
593  histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), histo->equivalentBinEntries(),
594  histo->sumBinHeights(), histo->sumAllBinHeights() );
595 
596  const AIDA::IAnnotation& a = histo->annotation();
597  if ( a.size() ) {
598  stream << " Annotation\n";
599  for ( int i = 0; i < a.size(); ++i ) {
600  stream << fmt::format( " | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
601  }
602  stream << '\n';
603  }
604 
605  return dumpText( hist, width, height, errors, stream ).str();
606 }
607 
608 /* dump the text representation of the 1D-profile
609  * @param histo the histogram
610  * @param stream the stream
611  * @param width the maximal column width
612  * @param height (INPUT) the proposed coulmn height
613  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
614  * @date 2009-09-19
615  */
616 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IProfile1D* histo, const std::size_t width,
617  const std::size_t height, const bool spread ) {
619  stream << std::endl;
620  if ( !histo ) { return stream.str(); } // RETURN
621  Histo hist;
622  StatusCode sc = _getHisto( histo, hist, spread );
623  if ( sc.isFailure() ) { return stream.str(); } // RETURN
624 
625  stream << fmt::format( R"( Histo TES : "{}"
626  Histo Title : "{}"
627 
628  Mean : {:11.5g}
629  Rms : {:11.5g}
630 
631  Entries :
632  | All | In Range | Underflow | Overflow | Integral | Total |
633  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} |
634 
635 )",
636  path( histo ), histo->title(), //
637  histo->mean(), histo->rms(), histo->allEntries(), histo->entries(),
638  histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
639  histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), histo->sumBinHeights(),
640  histo->sumAllBinHeights() );
641 
642  const AIDA::IAnnotation& a = histo->annotation();
643  if ( a.size() ) {
644  stream << " Annotation\n";
645  for ( int i = 0; i < a.size(); ++i ) {
646  stream << fmt::format( " | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
647  }
648  stream << std::endl;
649  }
650 
651  return dumpText( hist, width, height, true, stream ).str();
652 }
653 
654 /* dump the text representation of the histogram
655  * @param histo (INPUT) the histogram
656  * @param width (INPUT) the maximal column width
657  * @param errors (INPUT) print/plot errors
658  * @return string representation of the histogram
659  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
660  * @date 2009-09-19
661  */
662 std::string Gaudi::Utils::Histos::histoDump( const TH1* histo, const std::size_t width, const std::size_t height,
663  const bool errors ) {
664  const TProfile* profile = dynamic_cast<const TProfile*>( histo );
665  if ( profile ) { return histoDump( profile, width, height ); }
666  //
668  stream << std::endl;
669  if ( !histo ) { return stream.str(); } // RETURN
670  Histo hist;
671  StatusCode sc = _getHisto( histo, hist );
672  if ( sc.isFailure() ) { return stream.str(); } // RETURN
673 
674  stream << fmt::format( R"( Histo Name : "{}"
675  Histo Title : "{}"
676 
677  Mean : {:11.5g} +- {:<10.4g}
678  Rms : {:11.5g} +- {:<10.4g}
679  Skewness : {:11.5g}
680  Kurtosis : {:11.5g}
681 
682  Entries :
683  | All | Underflow | Overflow | #Equivalent | Integral |
684  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
685 
686 )",
687  histo->GetName(), histo->GetTitle(), //
688  histo->GetMean(), histo->GetMeanError(), histo->GetRMS(), histo->GetRMSError(),
689  histo->GetSkewness(), histo->GetKurtosis(), histo->GetEntries(), histo->GetBinContent( 0 ),
690  histo->GetBinContent( histo->GetNbinsX() + 1 ), histo->GetEffectiveEntries(),
691  histo->Integral() );
692 
693  return dumpText( hist, width, height, errors, stream ).str();
694 }
695 
696 /* dump the text representation of the histogram
697  * @param histo (INPUT) the histogram
698  * @param width (INPUT) the maximal column width
699  * @param errors (INPUT) print/plot errors
700  * @return string representation of the histogram
701  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
702  * @date 2009-09-19
703  */
704 std::string Gaudi::Utils::Histos::histoDump( const TProfile* histo, const std::size_t width,
705  const std::size_t height ) {
707  stream << std::endl;
708  if ( !histo ) { return stream.str(); } // RETURN
709  Histo hist;
710  StatusCode sc = _getHisto( histo, hist, true );
711  if ( sc.isFailure() ) { return stream.str(); } // RETURN
712 
713  stream << fmt::format( R"( Profile Name : "{}"
714  Profile Title : "{}"
715 
716  Mean : {:11.5g}
717  Rms : {:11.5g}
718 
719  Entries :
720  | All | Underflow | Overflow | Integral |
721  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
722 
723 )",
724  histo->GetName(), histo->GetTitle(), //
725  histo->GetMean(), histo->GetRMS(), histo->GetSkewness(), histo->GetKurtosis(),
726  histo->GetEntries(), histo->GetBinContent( 0 ), histo->GetBinContent( histo->GetNbinsX() + 1 ),
727  histo->Integral() );
728 
729  return dumpText( hist, width, height, true, stream ).str();
730 }
HistoStats.h
std::floor
T floor(T... args)
Write.stream
stream
Definition: Write.py:32
std::string
STL class.
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:23
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
plotBacklogPyRoot.maxY
maxY
Definition: plotBacklogPyRoot.py:45
std::pair
std::vector
STL class.
std::string::size
T size(T... args)
Gaudi::Utils::HistoStats::rmsErr
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
Definition: HistoStats.cpp:652
gaudiComponentHelp.root
root
Definition: gaudiComponentHelp.py:42
Gaudi::Utils::Histos::histoDump
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
Definition: HistoDump.cpp:565
std::abs
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.
Definition: ParticleID.h:191
StatusCode.h
Gaudi::Utils::HistoStats::kurtosisErr
static double kurtosisErr(const AIDA::IHistogram1D *histo)
get the error in kurtosis for the histogram
Definition: HistoStats.cpp:612
std::sqrt
T sqrt(T... args)
std::vector::push_back
T push_back(T... args)
Gaudi::Utils::HistoStats::meanErr
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
Definition: HistoStats.cpp:636
StatusCode
Definition: StatusCode.h:65
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:108
AlgSequencer.h
h
Definition: AlgSequencer.py:31
std::accumulate
T accumulate(T... args)
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
std::ceil
T ceil(T... args)
cpluginsvc.n
n
Definition: cpluginsvc.py:234
std::numeric_limits::epsilon
T epsilon(T... args)
std::min
T min(T... args)
std::ostringstream
STL class.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
std::endl
T endl(T... args)
std::right
T right(T... args)
gaudirun.l
dictionary l
Definition: gaudirun.py:583
std::begin
T begin(T... args)
Gaudi::Utils::HistoStats::mean
static double mean(const AIDA::IHistogram1D *histo)
get the mean value for the histogram (just for completeness)
Definition: HistoStats.cpp:628
Gaudi::Utils::HistoStats::rms
static double rms(const AIDA::IHistogram1D *histo)
get the rms value for the histogram (just for completeness)
Definition: HistoStats.cpp:644
plotSpeedupsPyRoot.line
line
Definition: plotSpeedupsPyRoot.py:198
Properties.v
v
Definition: Properties.py:122
Gaudi::Utils::HistoStats::kurtosis
static double kurtosis(const AIDA::IHistogram1D *histo)
get the kurtosis for the histogram
Definition: HistoStats.cpp:604
HepRndm::Engine
Definition: HepRndmEngine.h:35
std::size_t
std::end
T end(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
std::max
T max(T... args)
Gaudi::Utils::HistoStats::skewnessErr
static double skewnessErr(const AIDA::IHistogram1D *histo)
get the error in skewness for the histogram
Definition: HistoStats.cpp:596
HistoTableFormat.h
std::numeric_limits
Gaudi::Utils::HistoStats::skewness
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram
Definition: HistoStats.cpp:588
HistoDump.h