The Gaudi Framework  v36r11 (bdb84f5f)
GaudiHistos.icpp
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 #ifndef GAUDIALG_GAUDIHISTOS_ICPP
12 #define GAUDIALG_GAUDIHISTOS_ICPP 1
13 // ============================================================================
14 /* @file
15  *
16  * Implementation file for class : GaudiHistos
17  *
18  * @author Chris Jones Christopher.Rob.Jones@cern.ch
19  * @author Vanya BELYAEV Ivan.Belyaev@itep.ru
20  * @date 2005-08-08
21  */
22 // ============================================================================
23 // STD & STL
24 // ============================================================================
25 #include <algorithm>
26 #include <cmath>
27 #include <set>
28 #include <string>
29 #include <vector>
30 // ============================================================================
31 // GaudiKernel
32 // ============================================================================
34 #include "GaudiKernel/MsgStream.h"
35 // ============================================================================
36 // GaudiAlg
37 // ============================================================================
38 #include "GaudiAlg/Fill.h"
39 #include "GaudiAlg/GaudiHistos.h"
40 #include "GaudiAlg/HbookName.h"
41 #include "GaudiAlg/Print.h"
42 // ============================================================================
43 // forward declarations from AIDA
44 // ============================================================================
45 namespace AIDA {
46  class IBaseHistogram;
47  class IHistogram;
48  class IHistogram1D;
49  class IHistogram2D;
50  class IHistogram3D;
51  class IProfile;
52  class IProfile1D;
53  class IProfile2D;
54 } // namespace AIDA
55 // ============================================================================
56 // utility to allow iteration in order
57 // ============================================================================
58 namespace {
59  constexpr struct ordered_t {
60  template <typename C>
61  std::map<typename C::key_type, typename C::mapped_type> operator()( const C& c ) const {
62  return { std::begin( c ), std::end( c ) };
63  }
64  } ordered{};
65 
66  template <typename Map>
67  typename Map::mapped_type lookup_( const Map& map, const typename Map::key_type& ID ) {
68  auto found = map.find( ID );
69  return found != std::end( map ) ? found->second : nullptr;
70  }
71 
72  // ============================================================================
73  // Searches 'title' for all instances of 'A' and replaces them with 'B'
74  // ============================================================================
75  inline void stringSearchReplace( std::string& title, const std::string& A, const std::string& B ) {
76  for ( auto slash = title.find_first_of( A ); slash != std::string::npos; slash = title.find_first_of( A ) ) {
77  title = title.substr( 0, slash ) + B + title.substr( slash + A.size() );
78  }
79  }
80 } // namespace
81 // ============================================================================
82 // Initialise Histogramming
83 // ============================================================================
84 template <class PBASE>
86 #ifdef __ICC
87  i_ghInitialize
88 #else
89  initialize
90 #endif
91  () {
92  // initialize base class
93  const StatusCode sc = PBASE::initialize();
94  if ( sc.isFailure() ) return sc;
95 
96  // produce histograms?
97  if ( !produceHistos() ) {
98  this->debug() << "Histogram production is switched OFF" << endmsg;
99  return sc;
100  }
101 
102  // check the validity of histogram service
103  if ( !this->histoSvc() ) { return this->Error( "initialize():: IHistogramSvc* is invalid" ); }
104 
105  // Warn if the user has decided to use numerical automatic IDs
106  if ( useNumericAutoIDs() ) {
107  this->Warning(
108  "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
110  .ignore();
111  }
112 
113  // Finally, print the location histogram will be written to
114  this->Print( "The histogram path is set to be '" + histoPath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
115 
116  return sc;
117 }
118 // ============================================================================
119 // Finalise Histogramming
120 // ============================================================================
121 template <class PBASE>
123 #ifdef __ICC
124  i_ghFinalize
125 #else
126  finalize
127 #endif
128  () {
129 
130  if ( produceHistos() ) {
131 
132  // Count how many histos of each type
133  if ( ( !noHistos() ) && histoCountersPrint() ) {
134  const unsigned int n1D = histo1DMapID().size();
135  const unsigned int n2D = histo2DMapID().size();
136  const unsigned int n3D = histo3DMapID().size();
137  const unsigned int n1DP = profile1DMapID().size();
138  const unsigned int n2DP = profile2DMapID().size();
139  const unsigned int total = n1D + n2D + n3D + n1DP + n2DP;
140  if ( total > 0 ) {
141  this->always() << "Booked " << total << " Histogram(s) : ";
142  if ( n1D > 0 ) this->always() << "1D=" << n1D << " ";
143  if ( n2D > 0 ) this->always() << "2D=" << n2D << " ";
144  if ( n3D > 0 ) this->always() << "3D=" << n3D << " ";
145  if ( n1DP > 0 ) this->always() << "1DProf=" << n1DP << " ";
146  if ( n2DP > 0 ) this->always() << "2DProf=" << n2DP << " ";
147  this->always() << endmsg;
148  }
149  }
150 
151  // detailed printing
152  if ( histosPrint() ) { printHistos(); }
153  }
154 
155  // clear all maps
156  m_histo1DMapTitle.clear();
157  m_histo2DMapTitle.clear();
158  m_histo3DMapTitle.clear();
159  m_histo1DMapID.clear();
160  m_histo2DMapID.clear();
161  m_histo3DMapID.clear();
162  m_profile1DMapTitle.clear();
163  m_profile2DMapTitle.clear();
164  m_profile1DMapID.clear();
165  m_profile2DMapID.clear();
166 
167  // finalize base class
168  return PBASE::finalize();
169 }
170 // ============================================================================
171 // perform the actual detailed printout of histograms
172 // ============================================================================
173 template <class PBASE>
175  using namespace Gaudi::Utils::Histos;
176 
177  if ( noHistos() ) {
178  if ( this->msgLevel( MSG::DEBUG ) ) { this->msgStream( level ) << "No histograms are booked" << endmsg; }
179  return 0; // RETURN
180  }
181 
182  MsgStream& msg = this->msgStream( level );
183 
184  // Printout all histograms
185 
186  if ( !histo1DMapID().empty() ) {
187  msg << "1D histograms in directory "
188  << "\"" << histoPath() << "\" : " << histo1DMapID().size();
189  const Gaudi::Utils::Histos::Table table( m_histo1DTableFormat, m_histo1DTableHeader );
190  if ( !table.header().empty() ) {
191  msg << std::endl << Gaudi::Utils::Histos::format( "ID", table.header(), m_histo1DTableFormatShort );
192  }
193  for ( const auto& entry : ordered( histo1DMapID() ) ) {
194  const auto* aida = entry.second;
195  if ( !aida ) {
196  this->error() << "IHistogram1D points to NULL" << endmsg;
197  continue;
198  }
199  // format and print the row
200  msg << std::endl << table.toString( aida, HistoID( entry.first ), m_histo1DTableFormatShort );
201  }
202  msg << endmsg;
203  }
204  // ==========================================================================
205  if ( !histo2DMapID().empty() ) {
206  msg << "2D histograms in directory "
207  << "\"" << histoPath() << "\" : " << histo2DMapID().size();
208 
209  for ( const auto& entry : ordered( histo2DMapID() ) ) {
210  const auto* aida = entry.second;
211  if ( !aida ) {
212  this->error() << "IHistogram2D points to NULL" << endmsg;
213  continue;
214  }
215  msg << std::endl << GaudiAlg::Print2D::toString( aida, entry.first );
216  }
217  msg << endmsg;
218  }
219  // ==========================================================================
220  if ( !histo3DMapID().empty() ) {
221  msg << "3D histograms in directory "
222  << "\"" << histoPath() << "\" : " << histo3DMapID().size();
223  for ( const auto& entry : ordered( histo3DMapID() ) ) {
224  const auto* aida = entry.second;
225  if ( !aida ) {
226  this->error() << "IHistogram3D points to NULL" << endmsg;
227  continue;
228  }
229  msg << std::endl << GaudiAlg::Print3D::toString( aida, entry.first );
230  }
231  msg << endmsg;
232  }
233  // ==========================================================================
234  if ( !profile1DMapID().empty() ) {
235  msg << "1D profile histograms in directory "
236  << "\"" << histoPath() << "\" : " << profile1DMapID().size();
237  const Gaudi::Utils::Histos::Table table( m_histo1DTableFormat, m_histo1DTableHeader );
238  if ( !table.header().empty() ) {
239  msg << std::endl << Gaudi::Utils::Histos::format( "ID", table.header(), m_histo1DTableFormatShort );
240  }
241  for ( const auto& entry : ordered( profile1DMapID() ) ) {
242  const auto* aida = entry.second;
243  if ( !aida ) {
244  this->error() << "IProfile1D points to NULL" << endmsg;
245  continue;
246  }
247  msg << std::endl << table.toString( aida, HistoID( entry.first ), m_histo1DTableFormatShort );
248  }
249  msg << endmsg;
250  }
251  // ==========================================================================
252  if ( !profile2DMapID().empty() ) {
253  msg << "2D profile histograms in directory "
254  << "\"" << histoPath() << "\" : " << profile2DMapID().size();
255  for ( const auto& entry : ordered( profile2DMapID() ) ) {
256  const auto* aida = entry.second;
257  if ( !aida ) {
258  this->error() << "IProfile2D points to NULL" << endmsg;
259  continue;
260  }
261  msg << std::endl << GaudiAlg::Print2DProf::toString( aida, entry.first );
262  }
263  msg << endmsg;
264  }
265  //
266  return this->totalNumberOfHistos();
267 }
268 // ============================================================================
269 // Check if all histogram maps are empty
270 // ============================================================================
271 template <class PBASE>
273  return ( histo1DMapTitle().empty() && histo2DMapTitle().empty() && histo3DMapTitle().empty() &&
274  profile1DMapTitle().empty() && profile2DMapTitle().empty() && histo1DMapID().empty() &&
275  histo2DMapID().empty() && histo3DMapID().empty() && profile1DMapID().empty() && profile2DMapID().empty() );
276 }
277 // ============================================================================
278 // Declare a histogram to the monitor service
279 // ============================================================================
280 template <class PBASE>
281 void GaudiHistos<PBASE>::monitorHisto( const AIDA::IBaseHistogram* hist, const HistoID& ID ) const {
282  if ( hist && m_declareMoniHists ) {
283  if ( this->msgLevel( MSG::DEBUG ) ) {
284  this->debug() << "Monitoring histogram '" << ID.idAsString() << "' desc = '"
285  << Gaudi::Utils::Histos::htitle( hist ) << "'" << endmsg;
286  }
287  this->declareInfo( histoPath() + "/" + ID.idAsString(), hist, Gaudi::Utils::Histos::htitle( hist ) );
288  }
289 }
290 // ============================================================================
291 // access the EXISTING 1D histogram by ID
292 // ============================================================================
293 template <class PBASE>
294 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D( const HistoID& ID ) const {
295  return lookup_( histo1DMapID(), ID );
296 }
297 // ============================================================================
298 // access the EXISTING 2D histogram by ID
299 // ============================================================================
300 template <class PBASE>
301 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D( const HistoID& ID ) const {
302  return lookup_( histo2DMapID(), ID );
303 }
304 // ============================================================================
305 // access the EXISTING 3D histogram by ID
306 // ============================================================================
307 template <class PBASE>
308 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D( const HistoID& ID ) const {
309  return lookup_( histo3DMapID(), ID );
310 }
311 // ============================================================================
312 // access the EXISTING 1D profile histogram by ID
313 // ============================================================================
314 template <class PBASE>
315 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D( const HistoID& ID ) const {
316  return lookup_( profile1DMapID(), ID );
317 }
318 // ============================================================================
319 // access the EXISTING 2D profile histogram by ID
320 // ============================================================================
321 template <class PBASE>
322 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D( const HistoID& ID ) const {
323  return lookup_( profile2DMapID(), ID );
324 }
325 // ============================================================================
326 // Returns the total number of histograms (of all types) currently booked
327 // ============================================================================
328 template <class PBASE>
330  return histo1DMapID().size() + histo2DMapID().size() + histo3DMapID().size() + profile1DMapID().size() +
331  profile2DMapID().size();
332 }
333 // ============================================================================
334 // Create a new histogram ID using the given title
335 // ============================================================================
336 template <class PBASE>
337 void GaudiHistos<PBASE>::newHistoID( const std::string& title, HistoID& ID ) const {
338  if ( useNumericAutoIDs() || title.empty() ) {
339  if ( !useNumericAutoIDs() ) {
340  this->Warning(
341  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
343  .ignore();
344  }
345  // propose the histogram ID (always numeric)
346  ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
347  // adjust the proposed ID
348  while ( histoExists( ID ) ) { ID = HistoID( ID.numeric() + 1 ); }
349  } else {
350  // use the title to create a unique literal ID
351  ID = HistoID( this->convertTitleToID( title ) );
352  // Just in case ...
353  while ( histoExists( ID ) ) { ID = HistoID( ID.idAsString() + "_" ); }
354  }
355 }
356 // ============================================================================
357 // Create an ID string from a title string
358 // ============================================================================
359 template <class PBASE>
361  // clean up the ID string for all unwanted characters
362  for ( const auto& i : m_idReplaceInfo ) { stringSearchReplace( title, i.first, i.second ); }
363  return title;
364 }
365 // get the constructed histogram path
366 // ============================================================================
367 template <class PBASE>
369  std::string path = histoTopDir() + histoDir();
370  return splitHistoDir() ? dirHbookName( path ) : path;
371 }
372 // ============================================================================
373 // 1D
376 // 2D
379 // 3D
382 // 1D Profile
385 // 2D Profile
388 // ============================================================================
389 // The END
390 // ============================================================================
391 #endif // GAUDIALG_GAUDIHISTOS_ICPP
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
GaudiHistos_2DProfVariableBinning.icpp
AIDA
GaudiKernel.
Definition: Fill.h:20
std::string
STL class.
GaudiHistos_3DFixedBinning.icpp
GaudiAlg::ID
Definition: GaudiHistoID.h:53
GaudiHistos::histo2D
AIDA::IHistogram2D * histo2D(const std::string &title) const
access the EXISTING 2D histogram by title return the pointer to existing 2D histogram or NULL
Definition: GaudiHistos.h:2297
GaudiHistos::histoPath
std::string histoPath() const
get the constructed histogram path
Definition: GaudiHistos.icpp:368
GaudiHistos::convertTitleToID
std::string convertTitleToID(std::string title) const
Create an ID string from a title string.
Definition: GaudiHistos.icpp:360
GaudiHistos
Definition: GaudiHistos.h:65
std::string::size
T size(T... args)
GaudiHistos::histo3D
AIDA::IHistogram3D * histo3D(const std::string &title) const
access the EXISTING 3D histogram by title return the pointer to existing 3D histogram or NULL
Definition: GaudiHistos.h:2305
GaudiHistos_2DVariableBinning.icpp
Histos::HistoID
GaudiAlg::ID HistoID
The actual type for histogram identifier.
Definition: HistoID.h:33
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:19
GaudiHistos::newHistoID
void newHistoID(const std::string &title, HistoID &ID) const
Create a new histogram ID using the given title.
Definition: GaudiHistos.icpp:337
GaudiHistos::monitorHisto
void monitorHisto(const AIDA::IBaseHistogram *hist, const HistoID &ID) const
Declare a histogram to the monitor service.
Definition: GaudiHistos.icpp:281
GaudiHistos_2DFixedBinning.icpp
HbookName.h
gaudirun.c
c
Definition: gaudirun.py:525
Containers::map
struct GAUDI_API map
Parametrisation class for map-like implementation.
Definition: KeyedObjectManager.h:35
GaudiAlg::Print2DProf::toString
static std::string toString(const AIDA::IProfile2D *aida, const GaudiAlg::HistoID &ID)
Definition: Print.cpp:98
GaudiAlg::Print3D::toString
static std::string toString(const AIDA::IHistogram3D *aida, const GaudiAlg::HistoID &ID)
Definition: Print.cpp:77
StatusCode
Definition: StatusCode.h:65
GaudiHistos_3DVariableBinning.icpp
GaudiHistos::totalNumberOfHistos
unsigned int totalNumberOfHistos() const
Returns the total number of histograms (of all types) currently booked.
Definition: GaudiHistos.icpp:329
GaudiHistos_1DProfFixedBinning.icpp
GaudiPython.HistoUtils.path
path
Definition: HistoUtils.py:961
Gaudi::Utils::Histos::htitle
GAUDI_API std::string htitle(const AIDA::IBaseHistogram *histo, const std::string &title="")
get the title
Definition: Fill.cpp:119
GaudiHistos_2DProfFixedBinning.icpp
GaudiHistos_1DVariableBinning.icpp
Fill.h
GaudiHistos::printHistos
int printHistos(const MSG::Level level=MSG::ALWAYS) const
perform the actual printout of histograms
Definition: GaudiHistos.icpp:174
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
std::map
STL class.
GaudiHistos::noHistos
bool noHistos() const
Check if all histogram maps are empty.
Definition: GaudiHistos.icpp:272
gaudirun.level
level
Definition: gaudirun.py:364
MsgStream
Definition: MsgStream.h:34
Gaudi::Utils::Histos::Table
Definition: HistoTableFormat.h:437
GaudiHistos::profile1D
AIDA::IProfile1D * profile1D(const double valueX, const double valueY, const std::string &title, const double lowX, const double highX, const unsigned long binsX=100, const std::string &opt="", const double lowY=-std::numeric_limits< double >::max(), const double highY=std::numeric_limits< double >::max(), const double weight=1.0) const
fill the 1D profile histogram (book on demand)
Definition: GaudiHistos_1DProfFixedBinning.icpp:114
GaudiAlg::Print2D::toString
static std::string toString(const AIDA::IHistogram2D *aida, const GaudiAlg::HistoID &ID)
Definition: Print.cpp:66
std::string::substr
T substr(T... args)
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
Print.h
MSG::Level
Level
Definition: IMessageSvc.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
std::endl
T endl(T... args)
std::begin
T begin(T... args)
GaudiHistos::histo1D
AIDA::IHistogram1D * histo1D(const std::string &title) const
access the EXISTING 1D histogram by title return the pointer to existing 1D histogram or NULL
Definition: GaudiHistos.h:2280
std::string::empty
T empty(T... args)
std::string::find_first_of
T find_first_of(T... args)
GaudiHistos::profile2D
AIDA::IProfile2D * profile2D(const double valueX, const double valueY, const double valueZ, const std::string &title, const double lowX, const double highX, const double lowY, const double highY, const unsigned long binsX=50, const unsigned long binsY=50, const double weight=1.0) const
fill the 2D profile histogram (book on demand)
Definition: GaudiHistos_2DProfFixedBinning.icpp:113
GaudiHistos_1DProfVariableBinning.icpp
Gaudi::Utils::Histos::Table::header
const std::string & header() const
the table header
Definition: HistoTableFormat.h:485
std::end
T end(T... args)
Gaudi::Utils::Histos
Definition: Fill.h:36
GaudiHistos_1DFixedBinning.icpp
GaudiAlg::ID::idAsString
GAUDI_API LiteralID idAsString() const
Return ID as string, for both numeric and literal IDs.
Definition: GaudiHistoID.cpp:30
GaudiHistos.h
Containers::Map
KeyedObjectManager< map > Map
Forward declaration of specialized std::map-like object manager.
Definition: KeyedObjectManager.h:105
GaudiAlg::ID::numeric
bool numeric() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:74
IHistogramSvc.h
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
MsgStream.h