The Gaudi Framework  v33r1 (b1225454)
HistoTableFormat.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 // ============================================================================
12 // Include files
13 // ============================================================================
14 // STD & STL
15 // ============================================================================
16 #include <cmath>
17 #include <string>
18 // ============================================================================
19 // AIDA
20 // ============================================================================
22 #include "GaudiKernel/Kernel.h"
23 #include <vector>
24 #ifdef __clang__
25 # pragma clang diagnostic push
26 # pragma clang diagnostic ignored "-Wkeyword-macro"
27 #endif
28 #define class class GAUDI_API
29 #ifdef __clang__
30 # pragma clang diagnostic pop
31 #endif
32 #include "AIDA/IAxis.h"
33 #include "AIDA/IHistogram1D.h"
34 #include "AIDA/IProfile1D.h"
35 #undef class
36 // ============================================================================
37 // GaudiKernel
38 // ============================================================================
39 #include "GaudiKernel/DataObject.h"
40 #include "GaudiKernel/IRegistry.h"
41 // ============================================================================
42 // Local
43 // ============================================================================
44 #include "GaudiUtils/HistoStats.h"
46 // ============================================================================
47 // Boost
48 // ============================================================================
49 #include "boost/algorithm/string/erase.hpp"
50 #include "boost/format.hpp"
51 // ============================================================================
57 // ============================================================================
58 namespace {
59  // ==========================================================================
60  // Examples of formats
61  // ==========================================================================
63  const std::string s_histoFormatStat = "| %2$-45.45s | %3$=7d |%8$11.5g | %10$-11.5g|%12$11.5g |%14$11.5g |";
64  // ==========================================================================
66  const std::string s_histoFormatStatOnly = "| %3$=7d |%8$11.5g | %10$-11.5g|%12$11.5g |%14$11.5g |";
67  // ==========================================================================
69  const std::string s_histoFormatStat1 =
70  "| %3$=7d |%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9.3g+-%15$-9.3g|";
71  // ==========================================================================
75  const std::string s_histoFormatShapeOnly = "|%8$11.5g |%10$11.5g |%12$11.5g |%14$11.5g |%19$11.5g/%21$-11.5g|";
76  // ==========================================================================
81  const std::string s_histoFormatShape = "|%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9.3g+-%15$-9."
82  "3g|%19$9.3g+-%20$-9.3g|%21$9.3g+-%22$-9.3g|";
83  // ==========================================================================
85  const std::string s_histoFormatLineTitle =
86  " %2$-45.45s mean/sigma/skew/kurtosis = %8$10.4g/%10$10.4g/%12$10.4g/%14$10.4g";
87  // ==========================================================================
89  const std::string s_histoFormatLineOnly = " mean/sigma/skew/kurtosis = %8$10.4g/%10$10.4g/%12$10.4g/%14$10.4g";
90  // ==========================================================================
92  const std::string s_histoFormatOld = " %2$-45.45s Ents/All=%7$5s/%3$5s<X>/sX=%8$.5g/%10$-.5g";
93  // ==========================================================================
95  const std::string s_histoFormatPathTitle = "| %1$-45.45s | %2$-45.45s | ";
96  // ==========================================================================
98  const std::string s_histoFormatFull = "| %1$-45.45s | %2$-45.45s | %3$=7d |%4$5d/%5$-5d|%6$9.3g | "
99  "%7$-9.3g|%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9.3g+-%"
100  "15$-9.3g|";
102  const std::string s_histoFormatFullStat = "| %3$=7d |%4$5d/%5$-5d|%6$9.3g | "
103  "%7$-9.3g|%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9."
104  "3g+-%15$-9.3g|";
105  // ==========================================================================
106  // headers:
107  // ==========================================================================
109  const std::string s_histoFormatStatHeader =
110  "| Title | # | Mean | RMS | Skewness | Kurtosis |";
111  // ==========================================================================
113  const std::string s_histoFormatStatOnlyHeader = "| # | Mean | RMS | Skewness | Kurtosis |";
114  // ==========================================================================
116  const std::string s_histoFormatStat1Header =
117  "| # | Mean+-Error | RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
118  // ==========================================================================
120  const std::string s_histoFormatShapeOnlyHeader =
121  "| Mean | RMS | Skewness | Kurtosis | Underflow%/Overflow% |";
122  // ==========================================================================
124  const std::string s_histoFormatShapeHeader = "| Mean | RMS | Skewness | "
125  "Kurtosis | Underflow [%] | Overflow [%] |";
126  // ==========================================================================
128  const std::string s_histoFormatLineTitleHeader = " Title ";
129  // ==========================================================================
131  const std::string s_histoFormatLineOnlyHeader = "";
132  // ==========================================================================
134  const std::string s_histoFormatOldHeader = "";
135  // ==========================================================================
137  const std::string s_histoFormatPathTitleHeader =
138  "| Path in Histogram Data Store | Title | ";
139  // ==========================================================================
141  const std::string s_histoFormatFullHeader = "| Path in Histogram Data Store | Title | "
142  "# |Udflw/Ovflw| nEff | Sum | Mean+-Error | "
143  "RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
144  // ==========================================================================
146  const std::string s_histoFormatFullStatHeader = "| # |Udflw/Ovflw| nEff | Sum | Mean+-Error | "
147  " RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
148  // ==========================================================================
149  // Get cleaned up histogram title for table printout
150  template <typename HISTO>
151  decltype( auto ) _title( const HISTO* h ) {
152  // strip '|' from title as this is used as printout table delimiter and
153  // instances in the title can cause problems with automatic parsing of the
154  // table (e.g. LHCb QM tests) later on.
155  auto htitle = h->title();
156  boost::erase_all( htitle, "|" );
157  return htitle;
158  }
159  // ==========================================================================
160 } // namespace
161 // ============================================================================
162 // get the format by enum
163 // ============================================================================
165  switch ( ID ) {
166  case Old:
167  return s_histoFormatOld;
168  case Full:
169  return s_histoFormatFull;
170  case FullStat:
171  return s_histoFormatFullStat;
172  case Stat:
173  return s_histoFormatStat;
174  case StatOnly:
175  return s_histoFormatStatOnly;
176  case Stat1:
177  return s_histoFormatStat1;
178  case ShapeOnly:
179  return s_histoFormatShapeOnly;
180  case Shape:
181  return s_histoFormatShape;
182  case LineTitle:
183  return s_histoFormatLineTitle;
184  case LineOnly:
185  return s_histoFormatLineOnly;
186  case PathTitle:
187  return s_histoFormatPathTitle;
188  default:
189  break;
190  }
192  return s_histoFormatStat;
193 }
194 // ============================================================================
195 // get the recommended header by enum
196 // ============================================================================
198  switch ( ID ) {
199  case Old:
200  return s_histoFormatOldHeader;
201  case Full:
202  return s_histoFormatFullHeader;
203  case FullStat:
204  return s_histoFormatFullStatHeader;
205  case Stat:
206  return s_histoFormatStatHeader;
207  case Stat1:
208  return s_histoFormatStat1Header;
209  case StatOnly:
210  return s_histoFormatStatOnlyHeader;
211  case ShapeOnly:
212  return s_histoFormatShapeOnlyHeader;
213  case Shape:
214  return s_histoFormatShapeHeader;
215  case LineTitle:
216  return s_histoFormatLineTitleHeader;
217  case LineOnly:
218  return s_histoFormatLineOnlyHeader;
219  case PathTitle:
220  return s_histoFormatPathTitleHeader;
221  default:;
222  }
224  return s_histoFormatStatHeader;
225 }
226 // ============================================================================
227 // get the path in TES for AIDA histogram
228 // ============================================================================
229 std::string Gaudi::Utils::Histos::path( const AIDA::IBaseHistogram* aida ) {
230  if ( !aida ) { return ""; } // RETURN
231  const auto object = dynamic_cast<const DataObject*>( aida );
232  if ( !object ) { return ""; } // RETURN
233  const auto registry = object->registry();
234  if ( !registry ) { return ""; } // RETURN
235  const auto _path = registry->identifier();
236  const auto n = _path.find( "/stat/" );
237  return ( 0 == n ? std::string( _path, 6 ) : _path ); // RETURN
238 }
239 // ============================================================================
240 /* Make the string representation of the histogram
241  * according to the specified format.
242  */
243 // ============================================================================
244 std::string Gaudi::Utils::Histos::format( const AIDA::IHistogram1D* histo, const std::string& fmt ) {
245  if ( !histo ) { return "<NULL>"; }
246  using namespace Gaudi::Utils;
247  using namespace boost::io;
248  boost::format _fmt( fmt );
249  // allow various number of arguments
250  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
251 
252  _fmt % ( "\"" + path( histo ) + "\"" ) // 1) histogram path
253  % ( "\"" + _title( histo ) + "\"" ) // 2) title
254  % histo->allEntries() // 3) # entries
255  % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) // 4) # underflow
256  % histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) // 5) # overflow
257  % HistoStats::nEff( histo ) // 6) equivalent entries
258  % histo->sumBinHeights() // 7) integral
259  % HistoStats::mean( histo ) // 8) mean value
260  % HistoStats::meanErr( histo ) // 9) error in mean
261  % HistoStats::rms( histo ) // 10) rms
262  % HistoStats::rmsErr( histo ) // 11) error in rms
263  % HistoStats::skewness( histo ) // 12) skewness
264  % HistoStats::skewnessErr( histo ) // 13) error in skewness
265  % HistoStats::kurtosis( histo ) // 14) kurtosis
266  % HistoStats::kurtosisErr( histo ) // 15) error in kurtosis
267  //
268  % histo->sumAllBinHeights() // 16) full integral (in and out range)
269  % HistoStats::sumAllBinHeightErr( histo ) // 17) error on 16
270  % HistoStats::sumBinHeightErr( histo ) // 18) error on 7
271  //
272  % ( 100 * HistoStats::underflowEntriesFrac( histo ) ) // 19) fraction of underflow entries
273  % ( 100 * HistoStats::underflowEntriesFracErr( histo ) ) // 20) error on 19
274  % ( 100 * HistoStats::overflowEntriesFrac( histo ) ) // 21) fraction of overflow entries
275  % ( 100 * HistoStats::overflowEntriesFracErr( histo ) ) // 22) error on 21
276  //
277  % HistoStats::underflowIntegralFrac( histo ) // 23) fraction of underflow integral
278  % HistoStats::underflowIntegralFracErr( histo ) // 24) error on 23
279  % HistoStats::overflowIntegralFrac( histo ) // 25) fraction of overflow intergal
280  % HistoStats::overflowIntegralFracErr( histo ) // 26) error on 25
281  ;
282 
283  return _fmt.str();
284 }
285 // ============================================================================
286 /* Make the string representation of the histogram
287  * according to the specified format.
288  */
289 // ============================================================================
290 std::string Gaudi::Utils::Histos::format( const AIDA::IProfile1D* histo, const std::string& fmt ) {
291  if ( !histo ) { return "<NULL>"; }
292  using namespace Gaudi::Utils;
293  using namespace boost::io;
294  boost::format _fmt( fmt );
295  // allow various number of arguments
296  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
297 
298  _fmt % ( "\"" + path( histo ) + "\"" ) // 1) histogram path
299  % ( "\"" + _title( histo ) + "\"" ) // 2) title
300  % histo->allEntries() // 3) # entries
301  % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) // 4) # underflow
302  % histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) // 5) # overflow
303  % HistoStats::nEff( histo ) // 6) equivalent entries
304  % histo->sumBinHeights() // 7) integral
305  % HistoStats::mean( histo ) // 8) mean value
306  % HistoStats::meanErr( histo ) // 9) error in mean
307  % HistoStats::rms( histo ) // 10) rms
308  % HistoStats::rmsErr( histo ) // 11) error in rms
309  % HistoStats::skewness( histo ) // 12) skewness
310  % HistoStats::skewnessErr( histo ) // 13) error in skewness
311  % HistoStats::kurtosis( histo ) // 14) kurtosis
312  % HistoStats::kurtosisErr( histo ) // 15) error in kurtosis
313  //
314  % histo->sumAllBinHeights() // 16) full integral (in and out range)
315  % HistoStats::sumAllBinHeightErr( histo ) // 17) error on 16
316  % HistoStats::sumBinHeightErr( histo ) // 18) error on 7
317  //
318  % ( 100 * HistoStats::underflowEntriesFrac( histo ) ) // 19) fraction of underflow entries
319  % ( 100 * HistoStats::underflowEntriesFracErr( histo ) ) // 20) error on 19
320  % ( 100 * HistoStats::overflowEntriesFrac( histo ) ) // 21) fraction of overflow entries
321  % ( 100 * HistoStats::overflowEntriesFracErr( histo ) ) // 22) error on 21
322  //
323  % HistoStats::underflowIntegralFrac( histo ) // 23) fraction of underflow integral
324  % HistoStats::underflowIntegralFracErr( histo ) // 24) error on 23
325  % HistoStats::overflowIntegralFrac( histo ) // 25) fraction of overflow intergal
326  % HistoStats::overflowIntegralFracErr( histo ) // 26) error on 25
327  ;
328 
329  return _fmt.str();
330 }
331 // ============================================================================
332 /* format a full row in table, including ID, label, path or any other
333  * "extra" identifier in string form
334  */
335 // ============================================================================
336 std::string Gaudi::Utils::Histos::format( const AIDA::IHistogram1D* histo, const std::string& ID,
337  const std::string& fmt1, const std::string& fmt2 ) {
338  using namespace boost::io;
339  boost::format _fmt( fmt1 );
340  // allow various number of arguments
341  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
342  //
343  _fmt % ID // format ID
344  % format( histo, fmt2 ); // format the histogram
345  //
346  return _fmt.str();
347 }
348 // ============================================================================
349 /* format a full row in table, including ID, label, path or any other
350  * "extra" identifier in string form
351  */
352 // ============================================================================
353 std::string Gaudi::Utils::Histos::format( const AIDA::IProfile1D* histo, const std::string& ID, const std::string& fmt1,
354  const std::string& fmt2 ) {
355  using namespace boost::io;
356  boost::format _fmt( fmt1 );
357  // allow various number of arguments
358  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
359  //
360  _fmt % ID // format ID
361  % format( histo, fmt2 ); // format the histogram
362  //
363  return _fmt.str();
364 }
365 // ============================================================================
366 // helper method to merge the headers for short format table
367 // ============================================================================
369  using namespace boost::io;
370  boost::format _fmt( fmt );
371  // allow various number of arguments
372  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
373  //
374  _fmt % val1 // format ID
375  % val2; // format the histogram
376  //
377  return _fmt.str();
378 }
379 // ============================================================================
380 // default constructor
381 // ============================================================================
383  : m_header( Gaudi::Utils::Histos::Formats::header( ID ) )
384  , m_footer()
385  , m_format( Gaudi::Utils::Histos::Formats::format( ID ) ) {}
386 // ============================================================================
388  : m_header( header ), m_footer( footer ), m_format( format ) {}
389 // ============================================================================
390 // format the table row using the default format
391 // ============================================================================
392 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IHistogram1D* histo ) const {
393  return Gaudi::Utils::Histos::format( histo, format() );
394 }
395 // ============================================================================
399 // ============================================================================
400 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IHistogram1D* histo, const std::string& ID,
401  const std::string& fmt ) const {
402  return Gaudi::Utils::Histos::format( histo, ID, fmt, format() );
403 }
404 // ============================================================================
405 
406 // ============================================================================
407 // format the table row using the default format
408 // ============================================================================
409 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IProfile1D* histo ) const {
410  return Gaudi::Utils::Histos::format( histo, format() );
411 }
412 // ============================================================================
416 // ============================================================================
417 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IProfile1D* histo, const std::string& ID,
418  const std::string& fmt ) const {
419  return Gaudi::Utils::Histos::format( histo, ID, fmt, format() );
420 }
421 // ============================================================================
422 
423 // ============================================================================
424 // The END
425 // ============================================================================
helper namespace to collect useful definitions, types, constants and functions, related to manipulati...
static double underflowIntegralFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of underflow integral
Definition: HistoStats.cpp:775
static double overflowIntegralFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of overflow intergal
Definition: HistoStats.cpp:763
GAUDI_API std::string htitle(const AIDA::IBaseHistogram *histo, const std::string &title="")
get the title
Definition: Fill.cpp:119
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
static double underflowEntriesFrac(const AIDA::IHistogram1D *histo)
the fraction of underflow entries (useful for shape comparison)
Definition: HistoStats.cpp:703
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
Definition: HistoStats.cpp:661
Table(const int ID=0)
constructor from enum
static double underflowIntegralFrac(const AIDA::IHistogram1D *histo)
the fraction of underflow integral (useful for shape comparison)
Definition: HistoStats.cpp:727
GAUDI_API std::string format(const AIDA::IHistogram1D *histo, const std::string &fmt)
Make the string representation of the histogram according to the specified format.
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
Definition: HistoStats.cpp:645
static double overflowIntegralFrac(const AIDA::IHistogram1D *histo)
the fraction of overflow intergal (useful for shape comparison)
Definition: HistoStats.cpp:715
GAUDI_API std::string header(const int ID=Default)
get the recommended header by enum
STL class.
static double rms(const AIDA::IHistogram1D *histo)
get the rms value for the histogram (just for completeness)
Definition: HistoStats.cpp:653
GAUDI_API std::string format(const int ID=Default)
get the format by enum
static double overflowEntriesFrac(const AIDA::IHistogram1D *histo)
the fraction of overflow entries (useful for shape comparison)
Definition: HistoStats.cpp:691
static double sumBinHeightErr(const AIDA::IHistogram1D *histo)
get an error in the sum bin height ("in-range integral")
Definition: HistoStats.cpp:669
static double overflowEntriesFracErr(const AIDA::IHistogram1D *histo)
error on fraction of overflow entries (useful for shape comparison)
Definition: HistoStats.cpp:739
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
static double sumAllBinHeightErr(const AIDA::IHistogram1D *histo)
get an error in the sum of all bin height ("integral")
Definition: HistoStats.cpp:679
std::string toString(const AIDA::IHistogram1D *histo) const
make the string representation according to the default format
static double kurtosisErr(const AIDA::IHistogram1D *histo)
get the error in kurtosis for the histogram
Definition: HistoStats.cpp:621
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
static double underflowEntriesFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of underflow entries (useful for shape comparison)
Definition: HistoStats.cpp:751
static double kurtosis(const AIDA::IHistogram1D *histo)
get the kurtosis for the histogram
Definition: HistoStats.cpp:613
static double nEff(const AIDA::IHistogram1D *histo)
get the effective entries (just for completeness)
Definition: HistoStats.cpp:629
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram
Definition: HistoStats.cpp:597