Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  master (d98a2936)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
HistoDump.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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 
17 #include <AIDA/IAnnotation.h>
18 #include <AIDA/IAxis.h>
19 #include <AIDA/IHistogram1D.h>
20 #include <AIDA/IProfile1D.h>
21 #include <GaudiKernel/StatusCode.h>
22 #include <GaudiUtils/HistoDump.h>
23 #include <GaudiUtils/HistoStats.h>
25 #include <TAxis.h>
26 #include <TH1.h>
27 #include <TProfile.h>
28 #include <cmath>
29 #include <fmt/format.h>
30 #include <iostream>
31 #include <numeric>
32 #include <sstream>
33 #include <utility>
34 #include <vector>
35 
36 // ============================================================================
37 namespace {
38 
39  // idea coming from The art of computer programming by Knuth
40  constexpr bool essentiallyEqual( double const a, double const b ) {
41  return std::abs( a - b ) <= std::min( std::abs( a ), std::abs( b ) ) * std::numeric_limits<double>::epsilon();
42  }
43 
44  // ==========================================================================
50  struct Histo {
51  // ========================================================================
52  Histo() = default;
53  // ========================================================================
59  struct Bin {
60  // ======================================================================
61  Bin( const double h = 0, const double e = 0, const double l = -1 ) : height( h ), error( e ), lower( l ) {}
62  // ======================================================================
64  double height; // bin height
66  double error; // bin error
68  double lower; // lower edge
69  // ======================================================================
70  Bin& operator+=( const Bin& right ) {
71  height += right.height;
72  const double e2 = error * error + right.error * right.error;
73  error = std::sqrt( e2 );
74  return *this;
75  }
76  // ======================================================================
77  };
78  // ========================================================================
80  double maxY( const bool withErr ) const {
81  return std::accumulate(
82  std::begin( bins ), std::end( bins ), std::max( under.height, over.height ),
83  [&]( double m, const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
84  }
86  double minY( const bool withErr ) const {
87  return std::accumulate(
88  std::begin( bins ), std::end( bins ), std::min( under.height, over.height ),
89  [&]( double m, const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
90  }
92  Histo rebin( const unsigned int bin ) const {
93  // create new histogram
94  Histo nh;
95  // copy overflow & underflow bins
96  nh.under = under;
97  nh.over = over;
98  // rebin
99  for ( unsigned int ibin = 0; ibin < bins.size(); ++ibin ) {
100  const Bin& current = bins[ibin];
101  if ( nh.bins.empty() ) {
102  nh.bins.push_back( current );
103  } else if ( 0 == ibin % bin ) {
104  nh.bins.push_back( current );
105  } else {
106  nh.bins.back() += current;
107  }
108  }
109  return nh;
110  }
111  // find "null-bin", if any
112  int nullBin() const {
113  for ( auto ib = bins.cbegin(); bins.cend() != ib + 1; ++ib ) {
114  if ( ib->lower <= 0 && 0 < ( ib + 1 )->lower ) { return ib - bins.cbegin(); }
115  }
116  return -1;
117  }
118  // ========================================================================
119  typedef std::vector<Bin> Bins;
120  // ========================================================================
122  Bins bins; // histogram bins
124  Bin under; // underflow bin
126  Bin over; // overflow bin
127  // ========================================================================
128  };
129  // ==========================================================================
137  StatusCode _getHisto( const TH1* root, Histo& hist ) {
138  // clear the histogram
139  hist.bins.clear();
140  //
141  if ( !root ) { return StatusCode::FAILURE; } // RETURN
142  const TAxis* axis = root->GetXaxis();
143  if ( !axis ) { return StatusCode::FAILURE; } // RETURN
144  const int nbins = axis->GetNbins();
145  if ( 0 == nbins ) { return StatusCode::FAILURE; } // RETURN
146 
147  // underflow bin
148  hist.under = Histo::Bin( root->GetBinContent( 0 ), root->GetBinError( 0 ), axis->GetXmin() );
149  // overflow bin
150  hist.over = Histo::Bin( root->GetBinContent( nbins + 1 ), root->GetBinError( nbins + 1 ), axis->GetXmax() );
151  //
152  //
153  for ( int ibin = 1; ibin <= nbins; ++ibin ) {
154  // add to the local histo
155  hist.bins.emplace_back( root->GetBinContent( ibin ), root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
156  }
157  return StatusCode::SUCCESS;
158  }
159  // ==========================================================================
167  StatusCode _getHisto( const TProfile* root, Histo& hist, const bool /* spread */ ) {
168  const TH1* histo = root;
169  return _getHisto( histo, hist );
170  }
171  // ==========================================================================
179  StatusCode _getHisto( const AIDA::IHistogram1D* aida, Histo& hist ) {
180  // clear the histogram
181  hist.bins.clear();
182  //
183  if ( !aida ) { return StatusCode::FAILURE; } // RETURN
184  //
185  const AIDA::IAxis& axis = aida->axis();
186  const int nbins = axis.bins();
187  //
188  // underflow bin
189  hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
190  aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
191  // overflow bin
192  hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
193  axis.upperEdge() );
194  //
195  for ( int ibin = 0; ibin < nbins; ++ibin ) {
196  // add to the local histo
197  hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
198  }
199  return StatusCode::SUCCESS;
200  }
201  // ==========================================================================
209  StatusCode _getHisto( const AIDA::IProfile1D* aida, Histo& hist, const bool spread ) {
210  // clear the histogram
211  hist.bins.clear();
212  //
213  if ( !aida ) { return StatusCode::FAILURE; } // RETURN
214  //
215  const AIDA::IAxis& axis = aida->axis();
216  const int nbins = axis.bins();
217  //
218  // underflow bin
219  hist.under =
220  Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
221  spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
222  axis.lowerEdge() );
223  // overflow bin
224  hist.over =
225  Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
226  spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
227  axis.upperEdge() );
228  //
229  for ( int ibin = 0; ibin < nbins; ++ibin ) {
230  // add to the local histo
231  hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
232  axis.binLowerEdge( ibin ) );
233  }
234  return StatusCode::SUCCESS;
235  }
236  // ==========================================================================
242  inline unsigned int rebin( const unsigned int bins, const unsigned int imax ) {
243  if ( 0 == imax ) { return 1; } // RETURN
244  unsigned int ibin = 1;
245  while ( bins > imax * ibin ) { ++ibin; }
246  return ibin; // RETURN
247  }
248  // ==========================================================================
254  std::pair<double, int> decompose( double v ) {
255  if ( std::abs( v ) < std::numeric_limits<double>::epsilon() ) {
256  return { 0.0, 0 };
257  } // RETURN
258  else if ( essentiallyEqual( 1.0, v ) ) {
259  return { 1.0, 0 };
260  } // RETURN
261  else if ( 0 > v ) {
262  auto r = decompose( -v );
263  return { -r.first, r.second }; // RETURN
264  } else if ( 0.1 > v ) {
265  int i = 0;
266  while ( 0.1 > v ) {
267  ++i;
268  v *= 10;
269  } // STUPID
270  return { v, -i };
271  } else if ( 1 < v ) {
272  int i = 0;
273  while ( 1 <= v ) {
274  ++i;
275  v /= 10;
276  } // STUPID
277  return { v, i };
278  }
279  return { v, 1 };
280  }
281  // ==========================================================================
286  inline double _pow( double x, unsigned long n ) {
287  double y = n % 2 ? x : 1;
288  while ( n >>= 1 ) {
289  x = x * x;
290  if ( n % 2 ) { y *= x; }
291  }
292  return y;
293  }
294  // forward declaration to break cyclic dependency between rValMin and rValMax
295  inline double rValMin( double v );
296  // ==========================================================================
301  inline double rValMax( double v ) {
302  if ( 0 > v ) { return -1 * rValMin( -v ); } // RETURN
303  // decompose the double value into decimal significand and mantissa
304  std::pair<double, int> r = decompose( v );
305  //
306  const double f = std::ceil( 20 * r.first ) / 2; // + 1 ;
307  const int l = r.second - 1;
308  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
309  }
310  // ==========================================================================
315  inline double rValMin( double v ) {
316  if ( 0 > v ) { return -1 * rValMax( -v ); } // RETURN
317  // decompose the double value into decimal significand and mantissa
318  std::pair<double, int> r = decompose( v );
319  const double f = std::floor( 20 * r.first ) / 2; // - 1 ;
320  const int l = r.second - 1;
321  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
322  }
323  // ==========================================================================
328  inline std::string yLabel( double value ) { return fmt::format( "{:10.3g}", value ); }
329  // ==========================================================================
334  inline std::string xLabel( const double value ) { return fmt::format( "{:9.3g}", value ); }
335  // ==========================================================================
337  char symbBin( const Histo::Bin& bin, const double yLow, const double yHigh, const bool yNull, const bool errors ) {
338  if ( errors && yLow <= bin.height && bin.height < yHigh ) {
339  return '*';
340  } // O
341  else if ( errors && yHigh < bin.height - bin.error ) {
342  return ' ';
343  } else if ( errors && yLow >= bin.height + bin.error ) {
344  return ' ';
345  } else if ( errors ) {
346  return 'I';
347  } else if ( yLow <= bin.height && bin.height < yHigh ) {
348  return '*';
349  } else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
350  return '*';
351  } // +
352  else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
353  return '*';
354  } // -
355  //
356  return ' ';
357  }
358  // ==========================================================================
363  std::ostringstream& dumpText( const Histo& histo, const std::size_t width, const std::size_t height,
364  const bool errors, std::ostringstream& stream ) {
365  if ( 40 > width ) { return dumpText( histo, 40, height, errors, stream ); }
366  if ( 200 < width ) { return dumpText( histo, 200, height, errors, stream ); }
367  if ( 150 < height ) { return dumpText( histo, width, 150, errors, stream ); }
368  if ( 20 > height ) { return dumpText( histo, width, 20, errors, stream ); }
369  if ( height > width ) { return dumpText( histo, width, width, errors, stream ); }
370  //
371  const unsigned int nBins = histo.bins.size();
372  if ( nBins > width ) {
373  // rebin histogram
374  Histo r = histo.rebin( rebin( nBins, width ) );
375  return dumpText( r, width, height, errors, stream );
376  }
377  //
378  // get the Y-scale
379  double yMax = std::max( rValMax( histo.maxY( errors ) ), 0.0 );
380  double yMin = std::min( rValMin( histo.minY( errors ) ), 0.0 );
381 
382  if ( essentiallyEqual( yMin, yMax ) ) { yMax = yMin + 1; }
384  std::pair<double, int> r = decompose( yMax - yMin );
385  double _ny = std::ceil( 10 * r.first ); // 1 <= ny < 10
386  if ( 1 >= _ny ) { _ny = 10; }
387  int yBins = (int)std::max( 1., std::ceil( height / _ny ) );
388 
389  yBins *= (int)_ny;
390  if ( 20 > yBins ) { yBins = 20; }
391  const double yScale = ( yMax - yMin ) / yBins;
392 
393  //
394  const int ySkip = 0 == yBins % 13 ? 13
395  : 0 == yBins % 11 ? 11
396  : 0 == yBins % 9 ? 9
397  : 0 == yBins % 8 ? 8
398  : 0 == yBins % 7 ? 7
399  : 0 == yBins % 6 ? 6
400  : 0 == yBins % 5 ? 5
401  : 0 == yBins % 4 ? 4
402  : 10;
403 
404  const int xSkip =
405  // 0 == nBins % 8 ? 8 :
406  0 == nBins % 7 ? 7
407  : 0 == nBins % 6 ? 6
408  : 0 == nBins % 5 ? 5
409  : 0 == nBins % 4 ? 4
410  : 10;
411 
412  int iNull = histo.nullBin();
413 
414  if ( 0 <= iNull ) {
415  iNull %= xSkip;
416  } else {
417  iNull = 0;
418  }
419 
420  stream << std::endl;
421 
422  for ( int yLine = -1; yLine < yBins; ++yLine ) {
423  const double yHigh = yMax - yScale * yLine;
424  // const double yLow = yHigh - yScale ;
425  const double yLow = yMax - yScale * ( yLine + 1 );
426  //
427  std::string line1 = " ";
428 
429  const bool ynull = ( yLow <= 0 && 0 < yHigh );
430  const bool yfirst = -1 == yLine || yBins - 1 == yLine;
431  const bool ylab = ( 0 == ( yLine + 1 ) % ySkip ) || yfirst || ynull;
432 
433  if ( ylab ) {
434  line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
435  } else {
436  line1 += std::string( 10, ' ' );
437  }
438  //
439  line1 += " ";
440  //
442  line1 += symbBin( histo.under, yLow, yHigh, ynull, errors );
443  //
444  line1 += ynull ? "-+" : ylab ? " +" : " |";
445  //
446  std::string line2;
447  //
448  for ( auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
449  // char symb = ' ' ;
450  const int i = ibin - histo.bins.cbegin();
451  //
452  const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < ( ibin + 1 )->lower;
453  const bool xlab = iNull == i % xSkip;
454  //
455  char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
456  //
457  if ( ' ' == symb ) {
458  if ( ( ynull || yfirst ) && xlab ) {
459  symb = '+';
460  } else if ( ynull || yfirst ) {
461  symb = '-';
462  }
463  //
464  else if ( ylab && xnull ) {
465  symb = '+';
466  } else if ( xnull ) {
467  symb = '|';
468  }
469  //
470  else if ( ylab || xlab ) {
471  symb = '.';
472  }
473  //
474  }
475  line2 += symb;
476  //
477  }
478  //
479  std::string line3 = ynull ? "->" : ylab ? "+ " : "| ";
480  //
482  line3 += symbBin( histo.over, yLow, yHigh, ynull, errors );
483  //
484  stream << line1 << line2 << line3 << std::endl;
485  //
486  }
487 
488  // get x-labels
489  std::vector<std::string> xlabels;
490  for ( auto ib = histo.bins.cbegin(); histo.bins.cend() != ib; ++ib ) { xlabels.push_back( xLabel( ib->lower ) ); }
491  // overflow& underflow label
492  const std::string oLabel = xLabel( histo.over.lower );
493  const std::string uLabel = xLabel( histo.under.lower );
494  //
495  static const std::string s_UNDERFLOW( "UNDERFLOW" );
496  static const std::string s_OVERFLOW( " OVERFLOW" );
497  //
498  //
499  for ( unsigned int yLine = 0; yLine < 12; ++yLine ) {
500  std::string line = std::string( 12, ' ' );
501  //
502  if ( yLine < s_UNDERFLOW.size() ) {
503  line += s_UNDERFLOW[yLine];
504  } else {
505  line += ' ';
506  }
507  //
508  line += ' ';
509  //
510  if ( uLabel.size() > yLine ) {
511  line += uLabel[yLine];
512  } else {
513  line += ' ';
514  }
515  //
516  for ( auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
517  int ib = ibin - histo.bins.cbegin();
518  const bool xlab = ( iNull == ib % xSkip );
519  if ( xlab && yLine < xlabels[ib].size() ) {
520  line += xlabels[ib][yLine];
521  } else {
522  line += ' ';
523  }
524  }
525  //
526  if ( oLabel.size() > yLine ) {
527  line += oLabel[yLine];
528  } else {
529  line += ' ';
530  }
531  //
532  line += ' ';
533  //
534  if ( yLine < s_OVERFLOW.size() ) {
535  line += s_OVERFLOW[yLine];
536  } else {
537  line += ' ';
538  }
539  //
540  stream << line << std::endl;
541  }
542  //
543  return stream; // RETURN
544  }
545 } // namespace
546 
547 // ============================================================================
548 /* dump the text representation of the histogram
549  * @param histo the histogram
550  * @param stream the stream
551  * @param width the maximal column width
552  * @param height (INPUT) the proposed coulmn height
553  * @param errors (INPUT) print/plot errors
554  * @param erorrs print/plot errors
555  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
556  * @date 2009-09-19
557  */
558 // ============================================================================
559 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IHistogram1D* histo, const std::size_t width,
560  const std::size_t height, const bool errors ) {
561  std::ostringstream stream;
562  stream << std::endl;
563  if ( !histo ) { return stream.str(); } // RETURN
564  Histo hist;
565  StatusCode sc = _getHisto( histo, hist );
566  if ( sc.isFailure() ) { return stream.str(); } // RETURN
567 
568  stream << fmt::format( R"( Histo TES : "{}"
569  Histo Title : "{}"
570 
571  Mean : {:11.5g} +- {:<10.4g}
572  Rms : {:11.5g} +- {:<10.4g}
573  Skewness : {:11.5g} +- {:<10.4g}
574  Kurtosis : {:11.5g} +- {:<10.4g}
575 
576  Entries :
577  | All | In Range | Underflow | Overflow | #Equivalent | Integral | Total |
578  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
579 
580 )",
581  path( histo ), histo->title(), //
586  histo->allEntries(), histo->entries(), histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
587  histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), histo->equivalentBinEntries(),
588  histo->sumBinHeights(), histo->sumAllBinHeights() );
589 
590  const AIDA::IAnnotation& a = histo->annotation();
591  if ( a.size() ) {
592  stream << " Annotation\n";
593  for ( int i = 0; i < a.size(); ++i ) {
594  stream << fmt::format( " | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
595  }
596  stream << '\n';
597  }
598 
599  return dumpText( hist, width, height, errors, stream ).str();
600 }
601 
602 /* dump the text representation of the 1D-profile
603  * @param histo the histogram
604  * @param stream the stream
605  * @param width the maximal column width
606  * @param height (INPUT) the proposed coulmn height
607  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
608  * @date 2009-09-19
609  */
610 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IProfile1D* histo, const std::size_t width,
611  const std::size_t height, const bool spread ) {
612  std::ostringstream stream;
613  stream << std::endl;
614  if ( !histo ) { return stream.str(); } // RETURN
615  Histo hist;
616  StatusCode sc = _getHisto( histo, hist, spread );
617  if ( sc.isFailure() ) { return stream.str(); } // RETURN
618 
619  stream << fmt::format( R"( Histo TES : "{}"
620  Histo Title : "{}"
621 
622  Mean : {:11.5g}
623  Rms : {:11.5g}
624 
625  Entries :
626  | All | In Range | Underflow | Overflow | Integral | Total |
627  | {:^9} | {:^9} | {:^9} | {:^9} | {:^11.5g} | {:^11.5g} |
628 
629 )",
630  path( histo ), histo->title(), //
631  histo->mean(), histo->rms(), histo->allEntries(), histo->entries(),
632  histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ),
633  histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ), histo->sumBinHeights(),
634  histo->sumAllBinHeights() );
635 
636  const AIDA::IAnnotation& a = histo->annotation();
637  if ( a.size() ) {
638  stream << " Annotation\n";
639  for ( int i = 0; i < a.size(); ++i ) {
640  stream << fmt::format( " | {:<25.25s} : {:<45.45s} |\n", a.key( i ), a.value( i ) );
641  }
642  stream << std::endl;
643  }
644 
645  return dumpText( hist, width, height, true, stream ).str();
646 }
647 
648 /* dump the text representation of the histogram
649  * @param histo (INPUT) the histogram
650  * @param width (INPUT) the maximal column width
651  * @param errors (INPUT) print/plot errors
652  * @return string representation of the histogram
653  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
654  * @date 2009-09-19
655  */
656 std::string Gaudi::Utils::Histos::histoDump( const TH1* histo, const std::size_t width, const std::size_t height,
657  const bool errors ) {
658  const TProfile* profile = dynamic_cast<const TProfile*>( histo );
659  if ( profile ) { return histoDump( profile, width, height ); }
660  //
661  std::ostringstream stream;
662  stream << std::endl;
663  if ( !histo ) { return stream.str(); } // RETURN
664  Histo hist;
665  StatusCode sc = _getHisto( histo, hist );
666  if ( sc.isFailure() ) { return stream.str(); } // RETURN
667 
668  stream << fmt::format( R"( Histo Name : "{}"
669  Histo Title : "{}"
670 
671  Mean : {:11.5g} +- {:<10.4g}
672  Rms : {:11.5g} +- {:<10.4g}
673  Skewness : {:11.5g}
674  Kurtosis : {:11.5g}
675 
676  Entries :
677  | All | Underflow | Overflow | #Equivalent | Integral |
678  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
679 
680 )",
681  histo->GetName(), histo->GetTitle(), //
682  histo->GetMean(), histo->GetMeanError(), histo->GetRMS(), histo->GetRMSError(),
683  histo->GetSkewness(), histo->GetKurtosis(), histo->GetEntries(), histo->GetBinContent( 0 ),
684  histo->GetBinContent( histo->GetNbinsX() + 1 ), histo->GetEffectiveEntries(),
685  histo->Integral() );
686 
687  return dumpText( hist, width, height, errors, stream ).str();
688 }
689 
690 /* dump the text representation of the histogram
691  * @param histo (INPUT) the histogram
692  * @param width (INPUT) the maximal column width
693  * @param errors (INPUT) print/plot errors
694  * @return string representation of the histogram
695  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
696  * @date 2009-09-19
697  */
698 std::string Gaudi::Utils::Histos::histoDump( const TProfile* histo, const std::size_t width,
699  const std::size_t height ) {
700  std::ostringstream stream;
701  stream << std::endl;
702  if ( !histo ) { return stream.str(); } // RETURN
703  Histo hist;
704  StatusCode sc = _getHisto( histo, hist, true );
705  if ( sc.isFailure() ) { return stream.str(); } // RETURN
706 
707  stream << fmt::format( R"( Profile Name : "{}"
708  Profile Title : "{}"
709 
710  Mean : {:11.5g}
711  Rms : {:11.5g}
712 
713  Entries :
714  | All | Underflow | Overflow | Integral |
715  | {:^11.5g} | {:^11.5g} | {:^11.5g} | {:^11.5g} |
716 
717 )",
718  histo->GetName(), histo->GetTitle(), //
719  histo->GetMean(), histo->GetRMS(), histo->GetSkewness(), histo->GetKurtosis(),
720  histo->GetEntries(), histo->GetBinContent( 0 ), histo->GetBinContent( histo->GetNbinsX() + 1 ),
721  histo->Integral() );
722 
723  return dumpText( hist, width, height, true, stream ).str();
724 }
Gaudi::Accumulators::sqrt
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition: Counters.h:34
HistoStats.h
Write.stream
stream
Definition: Write.py:32
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::abs
GAUDI_API const Gaudi::ParticleProperty * abs(const Gaudi::ParticleProperty *p)
Definition: ParticleProperty.cpp:399
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:559
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
Gaudi::Utils::HistoStats::meanErr
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
Definition: HistoStats.cpp:636
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:135
StatusCode
Definition: StatusCode.h:64
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:107
AlgSequencer.h
h
Definition: AlgSequencer.py:31
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:93
cpluginsvc.n
n
Definition: cpluginsvc.py:234
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:99
gaudirun.l
dictionary l
Definition: gaudirun.py:583
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:34
IOTest.end
end
Definition: IOTest.py:125
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:100
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
Gaudi::Accumulators::accumulate
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
Definition: Accumulators.h:1227
Gaudi::Utils::HistoStats::skewness
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram
Definition: HistoStats.cpp:588
HistoDump.h