The Gaudi Framework  master (37c0b60a)
HistoTableFormat.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // ============================================================================
12 // Include files
13 // ============================================================================
14 // STD & STL
15 // ============================================================================
16 #include <cmath>
17 #include <string>
18 #include <vector>
19 // ============================================================================
20 // AIDA
21 // ============================================================================
22 #include <AIDA/IAxis.h>
23 #include <AIDA/IHistogram1D.h>
24 #include <AIDA/IProfile1D.h>
25 // ============================================================================
26 // GaudiKernel
27 // ============================================================================
28 #include <GaudiKernel/DataObject.h>
29 #include <GaudiKernel/IRegistry.h>
30 // ============================================================================
31 // Local
32 // ============================================================================
33 #include <GaudiUtils/HistoStats.h>
35 // ============================================================================
36 // Boost
37 // ============================================================================
38 #include <boost/algorithm/string/erase.hpp>
39 #include <boost/format.hpp>
40 // ============================================================================
46 // ============================================================================
47 namespace {
48  // ==========================================================================
49  // Examples of formats
50  // ==========================================================================
52  const std::string s_histoFormatStat = "| %2$-45.45s | %3$=7d |%8$11.5g | %10$-11.5g|%12$11.5g |%14$11.5g |";
53  // ==========================================================================
55  const std::string s_histoFormatStatOnly = "| %3$=7d |%8$11.5g | %10$-11.5g|%12$11.5g |%14$11.5g |";
56  // ==========================================================================
58  const std::string s_histoFormatStat1 =
59  "| %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|";
60  // ==========================================================================
64  const std::string s_histoFormatShapeOnly = "|%8$11.5g |%10$11.5g |%12$11.5g |%14$11.5g |%19$11.5g/%21$-11.5g|";
65  // ==========================================================================
70  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."
71  "3g|%19$9.3g+-%20$-9.3g|%21$9.3g+-%22$-9.3g|";
72  // ==========================================================================
74  const std::string s_histoFormatLineTitle =
75  " %2$-45.45s mean/sigma/skew/kurtosis = %8$10.4g/%10$10.4g/%12$10.4g/%14$10.4g";
76  // ==========================================================================
78  const std::string s_histoFormatLineOnly = " mean/sigma/skew/kurtosis = %8$10.4g/%10$10.4g/%12$10.4g/%14$10.4g";
79  // ==========================================================================
81  const std::string s_histoFormatOld = " %2$-45.45s Ents/All=%7$5s/%3$5s<X>/sX=%8$.5g/%10$-.5g";
82  // ==========================================================================
84  const std::string s_histoFormatPathTitle = "| %1$-45.45s | %2$-45.45s | ";
85  // ==========================================================================
87  const std::string s_histoFormatFull = "| %1$-45.45s | %2$-45.45s | %3$=7d |%4$5d/%5$-5d|%6$9.3g | "
88  "%7$-9.3g|%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9.3g+-%"
89  "15$-9.3g|";
91  const std::string s_histoFormatFullStat = "| %3$=7d |%4$5d/%5$-5d|%6$9.3g | "
92  "%7$-9.3g|%8$9.3g+-%9$-9.3g|%10$9.3g+-%11$-9.3g|%12$9.3g+-%13$-9.3g|%14$9."
93  "3g+-%15$-9.3g|";
94  // ==========================================================================
95  // headers:
96  // ==========================================================================
98  const std::string s_histoFormatStatHeader =
99  "| Title | # | Mean | RMS | Skewness | Kurtosis |";
100  // ==========================================================================
102  const std::string s_histoFormatStatOnlyHeader = "| # | Mean | RMS | Skewness | Kurtosis |";
103  // ==========================================================================
105  const std::string s_histoFormatStat1Header =
106  "| # | Mean+-Error | RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
107  // ==========================================================================
109  const std::string s_histoFormatShapeOnlyHeader =
110  "| Mean | RMS | Skewness | Kurtosis | Underflow%/Overflow% |";
111  // ==========================================================================
113  const std::string s_histoFormatShapeHeader = "| Mean | RMS | Skewness | "
114  "Kurtosis | Underflow [%] | Overflow [%] |";
115  // ==========================================================================
117  const std::string s_histoFormatLineTitleHeader = " Title ";
118  // ==========================================================================
120  const std::string s_histoFormatLineOnlyHeader = "";
121  // ==========================================================================
123  const std::string s_histoFormatOldHeader = "";
124  // ==========================================================================
126  const std::string s_histoFormatPathTitleHeader =
127  "| Path in Histogram Data Store | Title | ";
128  // ==========================================================================
130  const std::string s_histoFormatFullHeader = "| Path in Histogram Data Store | Title | "
131  "# |Udflw/Ovflw| nEff | Sum | Mean+-Error | "
132  "RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
133  // ==========================================================================
135  const std::string s_histoFormatFullStatHeader = "| # |Udflw/Ovflw| nEff | Sum | Mean+-Error | "
136  " RMS+-Error | Skewness+-Error | Kurtosis+-Error |";
137  // ==========================================================================
138  // Get cleaned up histogram title for table printout
139  template <typename HISTO>
140  decltype( auto ) _title( const HISTO* h ) {
141  // strip '|' from title as this is used as printout table delimiter and
142  // instances in the title can cause problems with automatic parsing of the
143  // table (e.g. LHCb QM tests) later on.
144  auto htitle = h->title();
145  boost::erase_all( htitle, "|" );
146  return htitle;
147  }
148  // ==========================================================================
149 } // namespace
150 // ============================================================================
151 // get the format by enum
152 // ============================================================================
154  switch ( ID ) {
155  case Old:
156  return s_histoFormatOld;
157  case Full:
158  return s_histoFormatFull;
159  case FullStat:
160  return s_histoFormatFullStat;
161  case Stat:
162  return s_histoFormatStat;
163  case StatOnly:
164  return s_histoFormatStatOnly;
165  case Stat1:
166  return s_histoFormatStat1;
167  case ShapeOnly:
168  return s_histoFormatShapeOnly;
169  case Shape:
170  return s_histoFormatShape;
171  case LineTitle:
172  return s_histoFormatLineTitle;
173  case LineOnly:
174  return s_histoFormatLineOnly;
175  case PathTitle:
176  return s_histoFormatPathTitle;
177  default:
178  break;
179  }
181  return s_histoFormatStat;
182 }
183 // ============================================================================
184 // get the recommended header by enum
185 // ============================================================================
187  switch ( ID ) {
188  case Old:
189  return s_histoFormatOldHeader;
190  case Full:
191  return s_histoFormatFullHeader;
192  case FullStat:
193  return s_histoFormatFullStatHeader;
194  case Stat:
195  return s_histoFormatStatHeader;
196  case Stat1:
197  return s_histoFormatStat1Header;
198  case StatOnly:
199  return s_histoFormatStatOnlyHeader;
200  case ShapeOnly:
201  return s_histoFormatShapeOnlyHeader;
202  case Shape:
203  return s_histoFormatShapeHeader;
204  case LineTitle:
205  return s_histoFormatLineTitleHeader;
206  case LineOnly:
207  return s_histoFormatLineOnlyHeader;
208  case PathTitle:
209  return s_histoFormatPathTitleHeader;
210  default:;
211  }
213  return s_histoFormatStatHeader;
214 }
215 // ============================================================================
216 // get the path in TES for AIDA histogram
217 // ============================================================================
218 std::string Gaudi::Utils::Histos::path( const AIDA::IBaseHistogram* aida ) {
219  if ( !aida ) { return ""; } // RETURN
220  const auto object = dynamic_cast<const DataObject*>( aida );
221  if ( !object ) { return ""; } // RETURN
222  const auto registry = object->registry();
223  if ( !registry ) { return ""; } // RETURN
224  const auto _path = registry->identifier();
225  const auto n = _path.find( "/stat/" );
226  return ( 0 == n ? std::string( _path, 6 ) : _path ); // RETURN
227 }
228 // ============================================================================
229 /* Make the string representation of the histogram
230  * according to the specified format.
231  */
232 // ============================================================================
233 std::string Gaudi::Utils::Histos::format( const AIDA::IHistogram1D* histo, const std::string& fmt ) {
234  if ( !histo ) { return "<NULL>"; }
235  using namespace Gaudi::Utils;
236  using namespace boost::io;
237  boost::format _fmt( fmt );
238  // allow various number of arguments
239  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
240 
241  _fmt % ( "\"" + path( histo ) + "\"" ) // 1) histogram path
242  % ( "\"" + _title( histo ) + "\"" ) // 2) title
243  % histo->allEntries() // 3) # entries
244  % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) // 4) # underflow
245  % histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) // 5) # overflow
246  % HistoStats::nEff( histo ) // 6) equivalent entries
247  % histo->sumBinHeights() // 7) integral
248  % HistoStats::mean( histo ) // 8) mean value
249  % HistoStats::meanErr( histo ) // 9) error in mean
250  % HistoStats::rms( histo ) // 10) rms
251  % HistoStats::rmsErr( histo ) // 11) error in rms
252  % HistoStats::skewness( histo ) // 12) skewness
253  % HistoStats::skewnessErr( histo ) // 13) error in skewness
254  % HistoStats::kurtosis( histo ) // 14) kurtosis
255  % HistoStats::kurtosisErr( histo ) // 15) error in kurtosis
256  //
257  % histo->sumAllBinHeights() // 16) full integral (in and out range)
258  % HistoStats::sumAllBinHeightErr( histo ) // 17) error on 16
259  % HistoStats::sumBinHeightErr( histo ) // 18) error on 7
260  //
261  % ( 100 * HistoStats::underflowEntriesFrac( histo ) ) // 19) fraction of underflow entries
262  % ( 100 * HistoStats::underflowEntriesFracErr( histo ) ) // 20) error on 19
263  % ( 100 * HistoStats::overflowEntriesFrac( histo ) ) // 21) fraction of overflow entries
264  % ( 100 * HistoStats::overflowEntriesFracErr( histo ) ) // 22) error on 21
265  //
266  % HistoStats::underflowIntegralFrac( histo ) // 23) fraction of underflow integral
267  % HistoStats::underflowIntegralFracErr( histo ) // 24) error on 23
268  % HistoStats::overflowIntegralFrac( histo ) // 25) fraction of overflow intergal
269  % HistoStats::overflowIntegralFracErr( histo ) // 26) error on 25
270  ;
271 
272  return _fmt.str();
273 }
274 // ============================================================================
275 /* Make the string representation of the histogram
276  * according to the specified format.
277  */
278 // ============================================================================
279 std::string Gaudi::Utils::Histos::format( const AIDA::IProfile1D* histo, const std::string& fmt ) {
280  if ( !histo ) { return "<NULL>"; }
281  using namespace Gaudi::Utils;
282  using namespace boost::io;
283  boost::format _fmt( fmt );
284  // allow various number of arguments
285  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
286 
287  _fmt % ( "\"" + path( histo ) + "\"" ) // 1) histogram path
288  % ( "\"" + _title( histo ) + "\"" ) // 2) title
289  % histo->allEntries() // 3) # entries
290  % histo->binEntries( AIDA::IAxis::UNDERFLOW_BIN ) // 4) # underflow
291  % histo->binEntries( AIDA::IAxis::OVERFLOW_BIN ) // 5) # overflow
292  % HistoStats::nEff( histo ) // 6) equivalent entries
293  % histo->sumBinHeights() // 7) integral
294  % HistoStats::mean( histo ) // 8) mean value
295  % HistoStats::meanErr( histo ) // 9) error in mean
296  % HistoStats::rms( histo ) // 10) rms
297  % HistoStats::rmsErr( histo ) // 11) error in rms
298  % HistoStats::skewness( histo ) // 12) skewness
299  % HistoStats::skewnessErr( histo ) // 13) error in skewness
300  % HistoStats::kurtosis( histo ) // 14) kurtosis
301  % HistoStats::kurtosisErr( histo ) // 15) error in kurtosis
302  //
303  % histo->sumAllBinHeights() // 16) full integral (in and out range)
304  % HistoStats::sumAllBinHeightErr( histo ) // 17) error on 16
305  % HistoStats::sumBinHeightErr( histo ) // 18) error on 7
306  //
307  % ( 100 * HistoStats::underflowEntriesFrac( histo ) ) // 19) fraction of underflow entries
308  % ( 100 * HistoStats::underflowEntriesFracErr( histo ) ) // 20) error on 19
309  % ( 100 * HistoStats::overflowEntriesFrac( histo ) ) // 21) fraction of overflow entries
310  % ( 100 * HistoStats::overflowEntriesFracErr( histo ) ) // 22) error on 21
311  //
312  % HistoStats::underflowIntegralFrac( histo ) // 23) fraction of underflow integral
313  % HistoStats::underflowIntegralFracErr( histo ) // 24) error on 23
314  % HistoStats::overflowIntegralFrac( histo ) // 25) fraction of overflow intergal
315  % HistoStats::overflowIntegralFracErr( histo ) // 26) error on 25
316  ;
317 
318  return _fmt.str();
319 }
320 // ============================================================================
321 /* format a full row in table, including ID, label, path or any other
322  * "extra" identifier in string form
323  */
324 // ============================================================================
325 std::string Gaudi::Utils::Histos::format( const AIDA::IHistogram1D* histo, const std::string& ID,
326  const std::string& fmt1, const std::string& fmt2 ) {
327  using namespace boost::io;
328  boost::format _fmt( fmt1 );
329  // allow various number of arguments
330  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
331  //
332  _fmt % ID // format ID
333  % format( histo, fmt2 ); // format the histogram
334  //
335  return _fmt.str();
336 }
337 // ============================================================================
338 /* format a full row in table, including ID, label, path or any other
339  * "extra" identifier in string form
340  */
341 // ============================================================================
342 std::string Gaudi::Utils::Histos::format( const AIDA::IProfile1D* histo, const std::string& ID, const std::string& fmt1,
343  const std::string& fmt2 ) {
344  using namespace boost::io;
345  boost::format _fmt( fmt1 );
346  // allow various number of arguments
347  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
348  //
349  _fmt % ID // format ID
350  % format( histo, fmt2 ); // format the histogram
351  //
352  return _fmt.str();
353 }
354 // ============================================================================
355 // helper method to merge the headers for short format table
356 // ============================================================================
358  using namespace boost::io;
359  boost::format _fmt( fmt );
360  // allow various number of arguments
361  _fmt.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
362  //
363  _fmt % val1 // format ID
364  % val2; // format the histogram
365  //
366  return _fmt.str();
367 }
368 // ============================================================================
369 // default constructor
370 // ============================================================================
372  : m_header( Gaudi::Utils::Histos::Formats::header( ID ) )
373  , m_footer()
374  , m_format( Gaudi::Utils::Histos::Formats::format( ID ) ) {}
375 // ============================================================================
377  : m_header( header ), m_footer( footer ), m_format( format ) {}
378 // ============================================================================
379 // format the table row using the default format
380 // ============================================================================
381 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IHistogram1D* histo ) const {
382  return Gaudi::Utils::Histos::format( histo, format() );
383 }
384 // ============================================================================
388 // ============================================================================
389 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IHistogram1D* histo, const std::string& ID,
390  const std::string& fmt ) const {
391  return Gaudi::Utils::Histos::format( histo, ID, fmt, format() );
392 }
393 // ============================================================================
394 
395 // ============================================================================
396 // format the table row using the default format
397 // ============================================================================
398 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IProfile1D* histo ) const {
399  return Gaudi::Utils::Histos::format( histo, format() );
400 }
401 // ============================================================================
405 // ============================================================================
406 std::string Gaudi::Utils::Histos::Table::toString( const AIDA::IProfile1D* histo, const std::string& ID,
407  const std::string& fmt ) const {
408  return Gaudi::Utils::Histos::format( histo, ID, fmt, format() );
409 }
410 // ============================================================================
411 
412 // ============================================================================
413 // The END
414 // ============================================================================
HistoStats.h
Gaudi::Utils::Histos::Formats::LineTitle
@ LineTitle
Definition: HistoTableFormat.h:105
std::string
STL class.
Gaudi::Utils::Histos::Formats::Stat1
@ Stat1
Definition: HistoTableFormat.h:102
cpluginsvc.registry
def registry()
Definition: cpluginsvc.py:83
Gaudi::Utils::HistoStats::nEff
static double nEff(const AIDA::IHistogram1D *histo)
get the effective entries (just for completeness)
Definition: HistoStats.cpp:620
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
Gaudi::Utils::Histos::Formats::Shape
@ Shape
Definition: HistoTableFormat.h:104
Gaudi::Utils::Histos::Formats::header
GAUDI_API std::string header(const int ID=Default)
get the recommended header by enum
Definition: HistoTableFormat.cpp:186
Gaudi::Utils::HistoStats::rmsErr
static double rmsErr(const AIDA::IHistogram1D *histo)
get an error in the rms value
Definition: HistoStats.cpp:652
Gaudi::Utils
Definition: Property.h:650
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::underflowEntriesFracErr
static double underflowEntriesFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of underflow entries (useful for shape comparison)
Definition: HistoStats.cpp:742
Gaudi::Utils::HistoStats::meanErr
static double meanErr(const AIDA::IHistogram1D *histo)
get an error in the mean value
Definition: HistoStats.cpp:636
Gaudi::Utils::Histos::Formats::Old
@ Old
Definition: HistoTableFormat.h:97
Gaudi::Utils::Histos::Formats::FullStat
@ FullStat
Definition: HistoTableFormat.h:99
Gaudi::Utils::Histos::Formats::ShapeOnly
@ ShapeOnly
Definition: HistoTableFormat.h:103
Gaudi::Utils::Histos::Formats::LineOnly
@ LineOnly
Definition: HistoTableFormat.h:106
AlgSequencer.h
h
Definition: AlgSequencer.py:31
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
Gaudi::Utils::HistoStats::overflowEntriesFrac
static double overflowEntriesFrac(const AIDA::IHistogram1D *histo)
the fraction of overflow entries (useful for shape comparison)
Definition: HistoStats.cpp:682
IRegistry.h
Gaudi::Utils::Histos::Formats::Full
@ Full
Definition: HistoTableFormat.h:98
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::Utils::HistoStats::overflowIntegralFracErr
static double overflowIntegralFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of overflow intergal
Definition: HistoStats.cpp:754
Gaudi::Utils::Histos::Formats::StatOnly
@ StatOnly
Definition: HistoTableFormat.h:101
Gaudi::Utils::HistoStats::underflowIntegralFrac
static double underflowIntegralFrac(const AIDA::IHistogram1D *histo)
the fraction of underflow integral (useful for shape comparison)
Definition: HistoStats.cpp:718
Gaudi::Utils::Histos::Formats::format
GAUDI_API std::string format(const int ID=Default)
get the format by enum
Definition: HistoTableFormat.cpp:153
Gaudi::Utils::Histos::Formats::Stat
@ Stat
Definition: HistoTableFormat.h:100
Gaudi::Utils::HistoStats::overflowEntriesFracErr
static double overflowEntriesFracErr(const AIDA::IHistogram1D *histo)
error on fraction of overflow entries (useful for shape comparison)
Definition: HistoStats.cpp:730
DataObject.h
Gaudi::Utils::Histos::Table::Table
Table(const int ID=0)
constructor from enum
Definition: HistoTableFormat.cpp:371
Gaudi::Utils::Histos::Formats::PathTitle
@ PathTitle
Definition: HistoTableFormat.h:107
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
fmt
DataObject
Definition: DataObject.h:36
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
Gaudi::Utils::HistoStats::kurtosis
static double kurtosis(const AIDA::IHistogram1D *histo)
get the kurtosis for the histogram
Definition: HistoStats.cpp:604
Gaudi::Utils::HistoStats::sumBinHeightErr
static double sumBinHeightErr(const AIDA::IHistogram1D *histo)
get an error in the sum bin height ("in-range integral")
Definition: HistoStats.cpp:660
Gaudi::Utils::HistoStats::sumAllBinHeightErr
static double sumAllBinHeightErr(const AIDA::IHistogram1D *histo)
get an error in the sum of all bin height ("integral")
Definition: HistoStats.cpp:670
Gaudi::Utils::Histos::path
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
Definition: HistoTableFormat.cpp:218
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::Utils::HistoStats::overflowIntegralFrac
static double overflowIntegralFrac(const AIDA::IHistogram1D *histo)
the fraction of overflow intergal (useful for shape comparison)
Definition: HistoStats.cpp:706
Gaudi::Utils::HistoStats::skewness
static double skewness(const AIDA::IHistogram1D *histo)
get the skewness for the histogram
Definition: HistoStats.cpp:588
Gaudi::Utils::Histos::format
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.
Definition: HistoTableFormat.cpp:233
Gaudi::Utils::Histos::Table::toString
std::string toString(const AIDA::IHistogram1D *histo) const
make the string representation according to the default format
Definition: HistoTableFormat.cpp:381
Gaudi::Utils::HistoStats::underflowIntegralFracErr
static double underflowIntegralFracErr(const AIDA::IHistogram1D *histo)
the error on fraction of underflow integral
Definition: HistoStats.cpp:766
Gaudi::Utils::HistoStats::underflowEntriesFrac
static double underflowEntriesFrac(const AIDA::IHistogram1D *histo)
the fraction of underflow entries (useful for shape comparison)
Definition: HistoStats.cpp:694