The Gaudi Framework  v30r3 (a5ef0a68)
HistoDump.cpp
Go to the documentation of this file.
1 #ifdef __ICC
2 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
3 // TODO: To be removed, since it comes from ROOT TMathBase.h
4 #pragma warning( disable : 2259 )
5 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
6 // The comparison are meant
7 #pragma warning( disable : 1572 )
8 #endif
9 #ifdef WIN32
10 // Disable warning
11 // warning C4996: 'sprintf': This function or variable may be unsafe.
12 // coming from TString.h
13 #pragma warning( disable : 4996 )
14 #endif
15 // ============================================================================
16 // Include files
17 // ============================================================================
18 // STD & STL
19 // ============================================================================
20 #include <cmath>
21 #include <iostream>
22 #include <numeric>
23 #include <sstream>
24 #include <utility>
25 #include <vector>
26 // ============================================================================
27 // AIDA
28 // ============================================================================
29 #include "AIDA/IAnnotation.h"
30 #include "AIDA/IAxis.h"
31 #include "AIDA/IHistogram1D.h"
32 #include "AIDA/IProfile1D.h"
33 // ============================================================================
34 // GaudiKernel
35 // ============================================================================
36 #include "GaudiKernel/StatusCode.h"
37 // ============================================================================
38 // ROOT
39 // ============================================================================
40 #include "TAxis.h"
41 #include "TH1.h"
42 #include "TProfile.h"
43 // ============================================================================
44 // Boost
45 // ============================================================================
46 #include "boost/format.hpp"
47 // ============================================================================
48 // Local
49 // ============================================================================
50 #include "GaudiUtils/HistoDump.h"
51 #include "GaudiUtils/HistoStats.h"
53 // ============================================================================
54 namespace
55 {
56  // ==========================================================================
62  struct Histo {
63  // ========================================================================
64  Histo() = default;
65  // ========================================================================
71  struct Bin {
72  // ======================================================================
73  Bin( const double h = 0, const double e = 0, const double l = -1 ) : height( h ), error( e ), lower( l ) {}
74  // ======================================================================
76  double height; // bin height
78  double error; // bin error
80  double lower; // lower edge
81  // ======================================================================
82  Bin& operator+=( const Bin& right )
83  {
84  height += right.height;
85  const double e2 = error * error + right.error * right.error;
86  error = std::sqrt( e2 );
87  return *this;
88  }
89  // ======================================================================
90  };
91  // ========================================================================
93  double maxY( const bool withErr ) const
94  {
95  return std::accumulate(
96  std::begin( bins ), std::end( bins ), std::max( under.height, over.height ),
97  [&]( double m, const Bin& b ) { return std::max( m, withErr ? b.height + b.error : b.height ); } );
98  }
100  double minY( const bool withErr ) const
101  {
102  return std::accumulate(
103  std::begin( bins ), std::end( bins ), std::min( under.height, over.height ),
104  [&]( double m, const Bin& b ) { return std::min( m, withErr ? b.height - b.error : b.height ); } );
105  }
107  Histo rebin( const unsigned int bin ) const
108  {
109  // create new histogram
110  Histo nh;
111  // copy overflow & underflow bins
112  nh.under = under;
113  nh.over = over;
114  // rebin
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 );
121  } else {
122  nh.bins.back() += current;
123  }
124  }
125  return nh;
126  }
127  // find "null-bin", if any
128  int nullBin() const
129  {
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();
133  }
134  }
135  return -1;
136  }
137  // ========================================================================
138  typedef std::vector<Bin> Bins;
139  // ========================================================================
141  Bins bins; // histogram bins
143  Bin under; // underflow bin
145  Bin over; // overflow bin
146  // ========================================================================
147  };
148  // ==========================================================================
156  StatusCode _getHisto( const TH1* root, Histo& hist )
157  {
158  // clear the histogram
159  hist.bins.clear();
160  //
161  if ( !root ) {
162  return StatusCode::FAILURE;
163  } // RETURN
164  const TAxis* axis = root->GetXaxis();
165  if ( !axis ) {
166  return StatusCode::FAILURE;
167  } // RETURN
168  const int nbins = axis->GetNbins();
169  if ( 0 == nbins ) {
170  return StatusCode::FAILURE;
171  } // RETURN
172 
173  // underflow bin
174  hist.under = Histo::Bin( root->GetBinContent( 0 ), root->GetBinError( 0 ), axis->GetXmin() );
175  // overflow bin
176  hist.over = Histo::Bin( root->GetBinContent( nbins + 1 ), root->GetBinError( nbins + 1 ), axis->GetXmax() );
177  //
178  //
179  for ( int ibin = 1; ibin <= nbins; ++ibin ) {
180  // add to the local histo
181  hist.bins.emplace_back( root->GetBinContent( ibin ), root->GetBinError( ibin ), axis->GetBinLowEdge( ibin ) );
182  }
183  return StatusCode::SUCCESS;
184  }
185  // ==========================================================================
193  StatusCode _getHisto( const TProfile* root, Histo& hist, const bool /* spread */ )
194  {
195  const TH1* histo = root;
196  return _getHisto( histo, hist );
197  }
198  // ==========================================================================
206  StatusCode _getHisto( const AIDA::IHistogram1D* aida, Histo& hist )
207  {
208  // clear the histogram
209  hist.bins.clear();
210  //
211  if ( !aida ) {
212  return StatusCode::FAILURE;
213  } // RETURN
214  //
215  const AIDA::IAxis& axis = aida->axis();
216  const int nbins = axis.bins();
217  //
218  // underflow bin
219  hist.under = Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
220  aida->binError( AIDA::IAxis::UNDERFLOW_BIN ), axis.lowerEdge() );
221  // overflow bin
222  hist.over = Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ), aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
223  axis.upperEdge() );
224  //
225  for ( int ibin = 0; ibin < nbins; ++ibin ) {
226  // add to the local histo
227  hist.bins.emplace_back( aida->binHeight( ibin ), aida->binError( ibin ), axis.binLowerEdge( ibin ) );
228  }
229  return StatusCode::SUCCESS;
230  }
231  // ==========================================================================
239  StatusCode _getHisto( const AIDA::IProfile1D* aida, Histo& hist, const bool spread )
240  {
241  // clear the histogram
242  hist.bins.clear();
243  //
244  if ( !aida ) {
245  return StatusCode::FAILURE;
246  } // RETURN
247  //
248  const AIDA::IAxis& axis = aida->axis();
249  const int nbins = axis.bins();
250  //
251  // underflow bin
252  hist.under =
253  Histo::Bin( aida->binHeight( AIDA::IAxis::UNDERFLOW_BIN ),
254  spread ? aida->binRms( AIDA::IAxis::UNDERFLOW_BIN ) : aida->binError( AIDA::IAxis::UNDERFLOW_BIN ),
255  axis.lowerEdge() );
256  // overflow bin
257  hist.over =
258  Histo::Bin( aida->binHeight( AIDA::IAxis::OVERFLOW_BIN ),
259  spread ? aida->binRms( AIDA::IAxis::OVERFLOW_BIN ) : aida->binError( AIDA::IAxis::OVERFLOW_BIN ),
260  axis.upperEdge() );
261  //
262  for ( int ibin = 0; ibin < nbins; ++ibin ) {
263  // add to the local histo
264  hist.bins.emplace_back( aida->binHeight( ibin ), spread ? aida->binRms( ibin ) : aida->binError( ibin ),
265  axis.binLowerEdge( ibin ) );
266  }
267  return StatusCode::SUCCESS;
268  }
269  // ==========================================================================
275  inline unsigned int rebin( const unsigned int bins, const unsigned int imax )
276  {
277  if ( 0 == imax ) {
278  return 1;
279  } // RETURN
280  unsigned int ibin = 1;
281  while ( bins > imax * ibin ) {
282  ++ibin;
283  }
284  return ibin; // RETURN
285  }
286  // ==========================================================================
292  std::pair<double, int> decompose( double v )
293  {
294  if ( 0 == v ) {
295  return {0.0, 0};
296  } // RETURN
297  else if ( 1 == v ) {
298  return {1.0, 0};
299  } // RETURN
300  else if ( 0 > v ) {
301  auto r = decompose( -v );
302  return {-r.first, r.second}; // RETURN
303  } else if ( 0.1 > v ) {
304  int i = 0;
305  while ( 0.1 > v ) {
306  ++i;
307  v *= 10;
308  } // STUPID
309  return {v, -i};
310  } else if ( 1 < v ) {
311  int i = 0;
312  while ( 1 <= v ) {
313  ++i;
314  v /= 10;
315  } // STUPID
316  return {v, i};
317  }
318  return {v, 1};
319  }
320  // ==========================================================================
325  inline double _pow( double x, unsigned long n )
326  {
327  double y = n % 2 ? x : 1;
328  while ( n >>= 1 ) {
329  x = x * x;
330  if ( n % 2 ) {
331  y *= x;
332  }
333  }
334  return y;
335  }
336  // forward declaration to break cyclic dependency between rValMin and rValMax
337  inline double rValMin( double v );
338  // ==========================================================================
343  inline double rValMax( double v )
344  {
345  if ( 0 == v ) {
346  return 0;
347  } // RETURN
348  else if ( 0 > v ) {
349  return -1 * rValMin( -v );
350  } // RETURN
351  // decompose the double value into decimal significand and mantissa
352  std::pair<double, int> r = decompose( v );
353  //
354  const double f = std::ceil( 20 * r.first ) / 2; // + 1 ;
355  const int l = r.second - 1;
356  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
357  }
358  // ==========================================================================
363  inline double rValMin( double v )
364  {
365  if ( 0 == v ) {
366  return 0;
367  } // RETURN
368  else if ( 0 > v ) {
369  return -1 * rValMax( -v );
370  } // RETURN
371  // decompose the double value into decimal significand and mantissa
372  std::pair<double, int> r = decompose( v );
373  const double f = std::floor( 20 * r.first ) / 2; // - 1 ;
374  const int l = r.second - 1;
375  return 0 < l ? f * _pow( 10, l ) : f / _pow( 10, -l );
376  }
377  // ==========================================================================
382  inline std::string yLabel( double value )
383  {
384  boost::format fmt( "%10.3g" );
385  fmt % value;
386  return fmt.str();
387  }
388  // ==========================================================================
393  inline std::string xLabel( const double value )
394  {
395  boost::format fmt( "%9.3g" );
396  fmt % value;
397  return fmt.str();
398  }
399  // ==========================================================================
401  char symbBin( const Histo::Bin& bin, const double yLow, const double yHigh, const bool yNull, const bool errors )
402  {
403  if ( errors && yLow <= bin.height && bin.height < yHigh ) {
404  return '*';
405  } // O
406  else if ( errors && yHigh < bin.height - bin.error ) {
407  return ' ';
408  } else if ( errors && yLow >= bin.height + bin.error ) {
409  return ' ';
410  } else if ( errors ) {
411  return 'I';
412  } else if ( yLow <= bin.height && bin.height < yHigh ) {
413  return '*';
414  } else if ( 0 <= bin.height && yLow <= bin.height && 0 < yHigh && !yNull ) {
415  return '*';
416  } // +
417  else if ( 0 > bin.height && yHigh > bin.height && 0 >= yLow && !yNull ) {
418  return '*';
419  } // -
420  //
421  return ' ';
422  }
423  // ==========================================================================
428  std::ostream& dumpText( const Histo& histo, const std::size_t width, const std::size_t height, const bool errors,
429  std::ostream& stream )
430  {
431  if ( 40 > width ) {
432  return dumpText( histo, 40, height, errors, stream );
433  }
434  if ( 200 < width ) {
435  return dumpText( histo, 200, height, errors, stream );
436  }
437  if ( 150 < height ) {
438  return dumpText( histo, width, 150, errors, stream );
439  }
440  if ( 20 > height ) {
441  return dumpText( histo, width, 20, errors, stream );
442  }
443  if ( height > width ) {
444  return dumpText( histo, width, width, errors, stream );
445  }
446  //
447  const unsigned int nBins = histo.bins.size();
448  if ( nBins > width ) {
449  // rebin histogram
450  Histo r = histo.rebin( rebin( nBins, width ) );
451  return dumpText( r, width, height, errors, stream );
452  }
453  //
454  // get the Y-scale
455  double yMax = std::max( rValMax( histo.maxY( errors ) ), 0.0 );
456  double yMin = std::min( rValMin( histo.minY( errors ) ), 0.0 );
457 
458  if ( yMin == yMax ) {
459  yMax = yMin + 1;
460  }
462  std::pair<double, int> r = decompose( yMax - yMin );
463  double _ny = std::ceil( 10 * r.first ); // 1 <= ny < 10
464  if ( 1 >= _ny ) {
465  _ny = 10;
466  }
467  int yBins = (int)std::max( 1., std::ceil( height / _ny ) );
468 
469  yBins *= (int)_ny;
470  if ( 20 > yBins ) {
471  yBins = 20;
472  }
473  const double yScale = ( yMax - yMin ) / yBins;
474 
475  //
476  const int ySkip =
477  0 == yBins % 13
478  ? 13
479  : 0 == yBins % 11
480  ? 11
481  : 0 == yBins % 9
482  ? 9
483  : 0 == yBins % 8
484  ? 8
485  : 0 == yBins % 7 ? 7 : 0 == yBins % 6 ? 6 : 0 == yBins % 5 ? 5 : 0 == yBins % 4 ? 4 : 10;
486 
487  const int xSkip =
488  // 0 == nBins % 8 ? 8 :
489  0 == nBins % 7 ? 7 : 0 == nBins % 6 ? 6 : 0 == nBins % 5 ? 5 : 0 == nBins % 4 ? 4 : 10;
490 
491  int iNull = histo.nullBin();
492 
493  if ( 0 <= iNull ) {
494  iNull %= xSkip;
495  } else {
496  iNull = 0;
497  }
498 
499  stream << std::endl;
500 
501  for ( int yLine = -1; yLine < yBins; ++yLine ) {
502  const double yHigh = yMax - yScale * yLine;
503  // const double yLow = yHigh - yScale ;
504  const double yLow = yMax - yScale * ( yLine + 1 );
505  //
506  std::string line1 = " ";
507 
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;
511 
512  if ( ylab ) {
513  line1 += yLabel( ( yLow <= 0 && 0 < yHigh ) ? 0.0 : yLow );
514  } else {
515  line1 += std::string( 10, ' ' );
516  }
517  //
518  line1 += " ";
519  //
521  line1 += symbBin( histo.under, yLow, yHigh, ynull, errors );
522  //
523  line1 += ynull ? "-+" : ylab ? " +" : " |";
524  //
525  std::string line2;
526  //
527  for ( auto ibin = histo.bins.cbegin(); histo.bins.cend() != ibin; ++ibin ) {
528  // char symb = ' ' ;
529  const int i = ibin - histo.bins.cbegin();
530  //
531  const bool xnull = ibin->lower <= 0 && ( ibin + 1 ) != histo.bins.cend() && 0 < ( ibin + 1 )->lower;
532  const bool xlab = iNull == i % xSkip;
533  //
534  char symb = symbBin( *ibin, yLow, yHigh, ynull, errors );
535  //
536  if ( ' ' == symb ) {
537  if ( ( ynull || yfirst ) && xlab ) {
538  symb = '+';
539  } else if ( ynull || yfirst ) {
540  symb = '-';
541  }
542  //
543  else if ( ylab && xnull ) {
544  symb = '+';
545  } else if ( xnull ) {
546  symb = '|';
547  }
548  //
549  else if ( ylab || xlab ) {
550  symb = '.';
551  }
552  //
553  }
554  line2 += symb;
555  //
556  }
557  //
558  std::string line3 = ynull ? "->" : ylab ? "+ " : "| ";
559  //
561  line3 += symbBin( histo.over, yLow, yHigh, ynull, errors );
562  //
563  stream << line1 << line2 << line3 << std::endl;
564  //
565  }
566 
567  // get x-labels
568  std::vector<std::string> xlabels;
569  for ( auto ib = histo.bins.cbegin(); histo.bins.cend() != ib; ++ib ) {
570  xlabels.push_back( xLabel( ib->lower ) );
571  }
572  // overflow& underflow label
573  const std::string oLabel = xLabel( histo.over.lower );
574  const std::string uLabel = xLabel( histo.under.lower );
575  //
576  static const std::string s_UNDERFLOW( "UNDERFLOW" );
577  static const std::string s_OVERFLOW( " OVERFLOW" );
578  //
579  //
580  for ( unsigned int yLine = 0; yLine < 12; ++yLine ) {
581  std::string line = std::string( 12, ' ' );
582  //
583  if ( yLine < s_UNDERFLOW.size() ) {
584  line += s_UNDERFLOW[yLine];
585  } else {
586  line += ' ';
587  }
588  //
589  line += ' ';
590  //
591  if ( uLabel.size() > yLine ) {
592  line += uLabel[yLine];
593  } else {
594  line += ' ';
595  }
596  //
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];
602  } else {
603  line += ' ';
604  }
605  }
606  //
607  if ( oLabel.size() > yLine ) {
608  line += oLabel[yLine];
609  } else {
610  line += ' ';
611  }
612  //
613  line += ' ';
614  //
615  if ( yLine < s_OVERFLOW.size() ) {
616  line += s_OVERFLOW[yLine];
617  } else {
618  line += ' ';
619  }
620  //
621  stream << line << std::endl;
622  }
623  //
624  return stream; // RETURN
625  }
626 }
627 // ============================================================================
628 /* dump the text representation of the histogram
629  * @param histo (INPUT) the histogram
630  * @param stream (OUTUT) the stream
631  * @param width (INPUT) the maximal column width
632  * @param height (INPUT) the proposed coulmn height
633  * @param errors (INPUT) print/plot errors
634  * @return the stream
635  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
636  * @date 2009-09-19
637  */
638 // ============================================================================
639 std::ostream& Gaudi::Utils::Histos::histoDump_( const AIDA::IHistogram1D* histo, std::ostream& stream,
640  const std::size_t width, const std::size_t height, const bool errors )
641 {
642  stream << std::endl;
643  if ( !histo ) {
644  return stream;
645  } // RETURN
646  Histo hist;
647  StatusCode sc = _getHisto( histo, hist );
648  if ( sc.isFailure() ) {
649  return stream;
650  } // RETURN
651  //
652  stream << boost::format( " Histo TES : \"%s\"" ) % path( histo ) << std::endl
653  << boost::format( " Histo Title : \"%s\"" ) % histo->title() << std::endl
654  << std::endl;
655  //
656  stream << boost::format( " Mean : %11.5g +- %-10.4g " ) % Gaudi::Utils::HistoStats::mean( histo ) %
658  << std::endl
659  << boost::format( " Rms : %11.5g +- %-10.4g " ) % Gaudi::Utils::HistoStats::rms( histo ) %
661  << std::endl
662  << boost::format( " Skewness : %11.5g +- %-10.4g " ) % Gaudi::Utils::HistoStats::skewness( histo ) %
664  << std::endl
665  << boost::format( " Kurtosis : %11.5g +- %-10.4g " ) % Gaudi::Utils::HistoStats::kurtosis( histo ) %
667  << std::endl
668  << std::endl;
669  //
670  stream << boost::format( " Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s | %=11s |" ) % "All" %
671  "In Range" % "Underflow" % "Overflow" % "#Equivalent" % "Integral" % "Total"
672  << std::endl
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()
677  << std::endl
678  << std::endl;
679  //
680  const AIDA::IAnnotation& a = histo->annotation();
681  if ( 0 != a.size() ) {
682  stream << " Annotation" << std::endl;
683  for ( int i = 0; i < a.size(); ++i ) {
684  stream << boost::format( " | %-25.25s : %-45.45s | " ) % a.key( i ) % a.value( i ) << std::endl;
685  }
686  stream << std::endl;
687  }
688  //
689  return dumpText( hist, width, height, errors, stream );
690 }
691 // ============================================================================
692 /* dump the text representation of the histogram
693  * @param histo the histogram
694  * @param stream the stream
695  * @param width the maximal column width
696  * @param height (INPUT) the proposed coulmn height
697  * @param errors (INPUT) print/plot errors
698  * @param erorrs print/plot errors
699  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
700  * @date 2009-09-19
701  */
702 // ============================================================================
703 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IHistogram1D* histo, const std::size_t width,
704  const std::size_t height, const bool errors )
705 {
706  std::ostringstream stream;
707  histoDump_( histo, stream, width, height, errors );
708  return stream.str();
709 }
710 // ============================================================================
711 /* dump the text representation of the 1D-profile
712  * @param histo (INPUT) the profile
713  * @param stream (OUTUT) the stream
714  * @param width (INPUT) the maximal column width
715  * @param height (INPUT) the proposed coulmn height
716  * @param spread (INPUT) plot spread/error?
717  * @return the stream
718  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
719  * @date 2009-09-19
720  */
721 // ============================================================================
722 std::ostream& Gaudi::Utils::Histos::histoDump_( const AIDA::IProfile1D* histo, std::ostream& stream,
723  const std::size_t width, const std::size_t height, const bool spread )
724 {
725  stream << std::endl;
726  if ( !histo ) {
727  return stream;
728  } // RETURN
729  Histo hist;
730  StatusCode sc = _getHisto( histo, hist, spread );
731  if ( sc.isFailure() ) {
732  return stream;
733  } // RETURN
734  //
735  stream << boost::format( " Histo TES : \"%s\"" ) % path( histo ) << std::endl
736  << boost::format( " Histo Title : \"%s\"" ) % histo->title() << std::endl
737  << std::endl;
738  //
739  stream << boost::format( " Mean : %11.5g " ) % histo->mean() << std::endl
740  << boost::format( " Rms : %11.5g " ) % histo->rms() << std::endl
741  << std::endl;
742  //
743  stream << boost::format( " Entries :\n | %=9s | %=9s | %=9s | %9s | %=11s | %=11s |" ) % "All" % "In Range" %
744  "Underflow" % "Overflow"
745  // % "#Equivalent"
746  % "Integral" % "Total"
747  << std::endl
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 )
751  // % histo -> equivalentBinEntries ()
752  % histo->sumBinHeights() % histo->sumAllBinHeights()
753  << std::endl
754  << std::endl;
755  //
756  const AIDA::IAnnotation& a = histo->annotation();
757  if ( 0 != a.size() ) {
758  stream << " Annotation" << std::endl;
759  for ( int i = 0; i < a.size(); ++i ) {
760  stream << boost::format( " | %-25.25s : %-45.45s | " ) % a.key( i ) % a.value( i ) << std::endl;
761  }
762  stream << std::endl;
763  }
764  //
765  return dumpText( hist, width, height, true, stream );
766 }
767 // ============================================================================
768 /* dump the text representation of the 1D-profile
769  * @param histo the histogram
770  * @param stream the stream
771  * @param width the maximal column width
772  * @param height (INPUT) the proposed coulmn height
773  * @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
774  * @date 2009-09-19
775  */
776 // ============================================================================
777 std::string Gaudi::Utils::Histos::histoDump( const AIDA::IProfile1D* histo, const std::size_t width,
778  const std::size_t height, const bool spread )
779 {
780  std::ostringstream stream;
781  histoDump_( histo, stream, width, height, spread );
782  return stream.str();
783 }
784 // ============================================================================
785 /* dump the text representation of the histogram
786  * @param histo (INPUT) the histogram
787  * @param stream (OUTUT) the stream
788  * @param width (INPUT) the maximal column width
789  * @param errors (INPUT) print/plot errors
790  * @return the stream
791  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
792  * @date 2009-09-19
793  */
794 // ============================================================================
796  const std::size_t height, const bool errors )
797 {
798  const TProfile* profile = dynamic_cast<const TProfile*>( histo );
799  if ( profile ) {
800  return histoDump_( profile, stream, width, height );
801  }
802  //
803  stream << std::endl;
804  if ( !histo ) {
805  return stream;
806  } // RETURN
807  Histo hist;
808  StatusCode sc = _getHisto( histo, hist );
809  if ( sc.isFailure() ) {
810  return stream;
811  } // RETURN
812  //
813  stream << boost::format( " Histo Name : \"%s\"" ) % histo->GetName() << std::endl
814  << boost::format( " Histo Title : \"%s\"" ) % histo->GetTitle() << std::endl
815  << std::endl;
816  //
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
821  << std::endl;
822  //
823  stream << boost::format( " Entries :\n | %=11s | %=11s | %=11s | %=11s | %=11s |" ) % "All" % "Underflow" %
824  "Overflow" % "#Equivalent" % "Integral"
825  << std::endl
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()
829  << std::endl
830  << std::endl;
831  //
832  return dumpText( hist, width, height, errors, stream );
833 }
834 // ============================================================================
835 /* dump the text representation of the histogram
836  * @param histo (INPUT) the histogram
837  * @param stream (OUTUT) the stream
838  * @param width (INPUT) the maximal column width
839  * @param errors (INPUT) print/plot errors
840  * @return the stream
841  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
842  * @date 2009-09-19
843  */
844 // ============================================================================
845 std::ostream& Gaudi::Utils::Histos::histoDump_( const TProfile* histo, std::ostream& stream, const std::size_t width,
846  const std::size_t height )
847 {
848  stream << std::endl;
849  if ( !histo ) {
850  return stream;
851  } // RETURN
852  Histo hist;
853  StatusCode sc = _getHisto( histo, hist, true );
854  if ( sc.isFailure() ) {
855  return stream;
856  } // RETURN
857  //
858  stream << boost::format( " Profile Name : \"%s\"" ) % histo->GetName() << std::endl
859  << boost::format( " Profile Title : \"%s\"" ) % histo->GetTitle() << std::endl
860  << std::endl;
861  //
862  stream << boost::format( " Mean : %11.5g " ) % histo->GetMean() << std::endl
863  << boost::format( " Rms : %11.5g " ) % histo->GetRMS() << std::endl
864  << std::endl;
865  //
866  stream << boost::format( " Entries :\n | %=11s | %=11s | %=11s | %=11s |" ) % "All" % "Underflow" % "Overflow" %
867  "Integral"
868  << std::endl
869  << boost::format( " | %=11.5g | %=11.5g | %=11.5g | %=11.5g |" ) % histo->GetEntries() %
870  histo->GetBinContent( 0 ) % histo->GetBinContent( histo->GetNbinsX() + 1 ) % histo->Integral()
871  << std::endl
872  << std::endl;
873  //
874  return dumpText( hist, width, height, true, stream );
875 }
876 // ============================================================================
877 /* dump the text representation of the histogram
878  * @param histo (INPUT) the histogram
879  * @param width (INPUT) the maximal column width
880  * @param errors (INPUT) print/plot errors
881  * @return string representation of the histogram
882  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
883  * @date 2009-09-19
884  */
885 // ============================================================================
886 std::string Gaudi::Utils::Histos::histoDump( const TH1* histo, const std::size_t width, const std::size_t height,
887  const bool errors )
888 {
889  std::ostringstream stream;
890  histoDump_( histo, stream, width, height, errors );
891  return stream.str();
892 }
893 // ============================================================================
894 /* dump the text representation of the histogram
895  * @param histo (INPUT) the histogram
896  * @param width (INPUT) the maximal column width
897  * @param errors (INPUT) print/plot errors
898  * @return string representation of the histogram
899  * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
900  * @date 2009-09-19
901  */
902 // ============================================================================
903 std::string Gaudi::Utils::Histos::histoDump( const TProfile* histo, const std::size_t width, const std::size_t height )
904 {
905  std::ostringstream stream;
906  histoDump_( histo, stream, width, height );
907  return stream.str();
908 }
909 // ============================================================================
910 
911 // ============================================================================
912 // The END
913 // ============================================================================
constexpr static const auto FAILURE
Definition: StatusCode.h:88
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
T ceil(T...args)
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
Definition: HistoStats.cpp:250
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
Definition: HistoDump.cpp:639
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:703
T endl(T...args)
T end(T...args)
T floor(T...args)
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
Definition: HistoStats.cpp:235
bool isFailure() const
Definition: StatusCode.h:139
constexpr auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
STL class.
T min(T...args)
T push_back(T...args)
static double rms(const AIDA::IHistogram1D *histo)
get the rms value for the histogram (just for completeness)
Definition: HistoStats.cpp:246
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
constexpr double m
Definition: SystemOfUnits.h:94
T max(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
dictionary l
Definition: gaudirun.py:440
T size(T...args)
STL class.
T begin(T...args)
static double kurtosisErr(const AIDA::IHistogram1D *histo)
get the error in kurtosis for the histogram
Definition: HistoStats.cpp:206
static double mean(const AIDA::IHistogram1D *histo)
get the mean value for the histogram (just for completeness)
Definition: HistoStats.cpp:231
static double skewnessErr(const AIDA::IHistogram1D *histo)
get the error in skewness for the histogram
Definition: HistoStats.cpp:179
T sqrt(T...args)
T accumulate(T...args)
static double kurtosis(const AIDA::IHistogram1D *histo)
get the kurtosis for the histogram
Definition: HistoStats.cpp:194
STL class.
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram
Definition: HistoStats.cpp:167