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