Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GaudiHistos.icpp
Go to the documentation of this file.
1 // $Id: GaudiHistos.icpp,v 1.17 2008/10/10 12:39:04 marcocle Exp $
2 // ============================================================================
3 #ifndef GAUDIALG_GAUDIHISTOS_ICPP
4 #define GAUDIALG_GAUDIHISTOS_ICPP 1
5 // ============================================================================
6 /* @file
7  *
8  * Implementation file for class : GaudiHistos
9  *
10  * @author Chris Jones Christopher.Rob.Jones@cern.ch
11  * @author Vanya BELYAEV Ivan.Belyaev@itep.ru
12  * @date 2005-08-08
13  */
14 // ============================================================================
15 // STD & STL
16 // ============================================================================
17 #include <algorithm>
18 #include <string>
19 #include <vector>
20 #include <set>
21 // ============================================================================
22 // GaudiKernel
23 // ============================================================================
24 #include "GaudiKernel/MsgStream.h"
26 // ============================================================================
27 // GaudiUtils
28 // ============================================================================
30 // ============================================================================
31 // GaudiAlg
32 // ============================================================================
33 #include "GaudiAlg/GaudiHistos.h"
34 #include "GaudiAlg/CheckForNaN.h"
35 #include "GaudiAlg/Print.h"
36 #include "GaudiAlg/Fill.h"
37 #include "GaudiAlg/HbookName.h"
38 // ============================================================================
39 // forward declarations from AIDA
40 // ============================================================================
41 namespace AIDA
42 {
43  class IBaseHistogram ;
44  class IHistogram ;
45  class IHistogram1D ;
46  class IHistogram2D ;
47  class IHistogram3D ;
48  class IProfile ;
49  class IProfile1D ;
50  class IProfile2D ;
51 }
52 // =============================================================================
53 // Constructor initialisation and job options
54 // =============================================================================
55 template <class PBASE>
57 {
58  // SWITCH ON/OFF the histograms
59  this->declareProperty
60  ( "HistoProduce" ,
61  m_produceHistos = true ,
62  "Switch on/off the production of histograms" ) ;
63  // print the histograms at finalization
64  this->declareProperty
65  ( "HistoPrint" ,
66  m_histosPrint = false ,
67  "Switch on/off the printout of histograms at finalization" )
68  -> declareUpdateHandler ( &GaudiHistos<PBASE>::printHistoHandler, this ) ;
69  this->declareProperty
70  ( "HistoCountersPrint" ,
71  m_histoCountersPrint = true ,
72  "Switch on/off the printout of histogram counters at finalization" ) ;
73  // check for NaN/Finite
74  this->declareProperty
75  ( "HistoCheckForNaN" ,
76  m_checkForNaN = true ,
77  "Switch on/off the checks for NaN and Infinity for histogram fill" ) ;
78  // for HBOOK persistency, 'true' can be useful
79  this->declareProperty
80  ( "HistoSplitDir" ,
81  m_splitHistoDir = false ,
82  "Split long directory names into short pieces (suitable for HBOOK)" );
83  // general OffSet for histogram ID
84  this->declareProperty
85  ( "HistoOffSet" ,
86  m_histoOffSet = 0 ,
87  "OffSet for automatically assigned histogram numerical identifiers " ) ;
88  // top level histogram directory
89  this->declareProperty
90  ( "HistoTopDir" ,
91  m_histoTopDir = "" ,
92  "Top level histogram directory (take care that it ends with '/')" ) ;
93  // histogram directory
94  this->declareProperty
95  ( "HistoDir" ,
96  m_histoDir = this->name() ,
97  "Histogram Directory" ) ;
98  // control output level of histograms
99  this->declareProperty ( "FullDetail" , m_fullDetail = false ) ;
100  // monitor histograms
101  this->declareProperty ( "MonitorHistograms" , m_declareMoniHists = true ) ;
102  // format for 1D-histograms printout
103  this->declareProperty
104  ( "FormatFor1DHistoTable" ,
105  m_histo1DTableFormat = Gaudi::Utils::Histos::Formats::format () ,
106  "Format string for printout of 1D histograms" ) ;
107  // "short" format for 1D-histograms printout
108  this->declareProperty
109  ( "ShortFormatFor1DHistoTable" ,
110  m_histo1DTableFormatShort = " | %1$-25.25s %2%" ,
111  "Format string for printout of 1D histograms" ) ;
112  // the header for 1D-histogram table
113  this->declareProperty
114  ( "HeaderFor1DHistoTable" ,
115  m_histo1DTableHeader = Gaudi::Utils::Histos::Formats::header () ,
116  "The table header for printout of 1D histograms " ) ;
117  this->declareProperty
118  ( "UseSequencialNumericAutoIDs", m_useNumericAutoIDs = false,
119  "Flag to allow users to switch back to the old style of creating numerical automatic IDs" );
120  m_idReplaceInfo.clear();
121  m_idReplaceInfo["/"] = "=SLASH=";
122  this->declareProperty
123  ( "AutoStringIDPurgeMap", m_idReplaceInfo,
124  "Map of strings to search and replace when using the title as the basis of automatically generated literal IDs" );
125 }
126 // ============================================================================
127 // Initialise Histogramming
128 // ============================================================================
129 template <class PBASE>
131 #ifdef __ICC
132 i_ghInitialize
133 #else
135 #endif
136 ()
137 {
138  // initialize base class
139  const StatusCode sc = PBASE::initialize();
140  if ( sc.isFailure() ) return sc;
141 
142  // produce histograms?
143  if ( !produceHistos() )
144  {
145  this->debug() << "Histogram production is switched OFF" << endmsg;
146  return sc;
147  }
148 
149  // check the validity of histogram service
150  if ( this->histoSvc() == NULL )
151  { return this->Error("initialize():: IHistogramSvc* is invalid"); }
152 
153  // Warn if the user has decided to use numerical automatic IDs
154  if ( useNumericAutoIDs() )
155  {
156  this ->
157  Warning( "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
158  StatusCode::SUCCESS ).ignore();
159  }
160 
161  // Finally, print the location histogram will be written to
162  this->Print
163  ( "The histogram path is set to be '" + histoPath() + "'",
164  StatusCode( StatusCode::SUCCESS, true ) , MSG::DEBUG ).ignore();
165 
166  return sc;
167 }
168 // ============================================================================
169 // Finalise Histogramming
170 // ============================================================================
171 template <class PBASE>
173 #ifdef __ICC
174 i_ghFinalize
175 #else
176 finalize
177 #endif
178 ()
179 {
180 
181  if ( produceHistos() )
182  {
183 
184  // Count how many histos of each type
185  if ( (!noHistos()) && histoCountersPrint() )
186  {
187  const unsigned int n1D = histo1DMapID () . size () ;
188  const unsigned int n2D = histo2DMapID () . size () ;
189  const unsigned int n3D = histo3DMapID () . size () ;
190  const unsigned int n1DP = profile1DMapID () . size () ;
191  const unsigned int n2DP = profile2DMapID () . size () ;
192  const unsigned int total = n1D+n2D+n3D+n1DP+n2DP;
193  if ( total>0 )
194  {
195  this->always() << "Booked " << total << " Histogram(s) : ";
196  if ( n1D>0 ) this->always() << "1D=" << n1D << " ";
197  if ( n2D>0 ) this->always() << "2D=" << n2D << " ";
198  if ( n3D>0 ) this->always() << "3D=" << n3D << " ";
199  if ( n1DP>0 ) this->always() << "1DProf=" << n1DP << " ";
200  if ( n2DP>0 ) this->always() << "2DProf=" << n2DP << " ";
201  this->always() << endmsg;
202  }
203  }
204 
205  // detailed printing
206  if ( histosPrint() ) { printHistos() ; }
207 
208  }
209 
210  // clear all maps
211  m_histo1DMapTitle . clear () ;
212  m_histo2DMapTitle . clear () ;
213  m_histo3DMapTitle . clear () ;
214  m_histo1DMapID . clear () ;
215  m_histo2DMapID . clear () ;
216  m_histo3DMapID . clear () ;
217  m_profile1DMapTitle . clear () ;
218  m_profile2DMapTitle . clear () ;
219  m_profile1DMapID . clear () ;
220  m_profile2DMapID . clear () ;
221 
222  // finalize base class
223  return PBASE::finalize();
224 }
225 // ============================================================================
226 // perform the actual detailed printout of histograms
227 // ============================================================================
228 template <class PBASE>
230 {
231  using namespace Gaudi::Utils::Histos ;
232 
233  if ( noHistos() )
234  {
235  if ( this->msgLevel(MSG::DEBUG) )
236  { this->msgStream(level) << "No histograms are booked" << endmsg ; }
237  return 0 ; // RETURN
238  }
239 
240  MsgStream & msg = this->msgStream(level);
241 
242  // Printout all histograms
243 
244  Gaudi::Utils::Histos::Table table
245  ( m_histo1DTableFormat ,
246  m_histo1DTableHeader ) ;
247 
248  if ( !histo1DMapID().empty() )
249  {
250  msg << "List of booked 1D histograms in directory "
251  << "\"" << histoPath() << "\" :-" ;
252 
253  if ( !table.header().empty() )
254  {
256  ( "ID" , table.header() , m_histo1DTableFormatShort ) ;
257  }
258  // temporary map to keep ordered IDs
259  typedef std::map<HistoID,const AIDA::IHistogram1D*> OrderedMapType;
260  OrderedMapType OrderedMap ( histo1DMapID().begin() , histo1DMapID().end() );
261  //
262  for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
263  OrderedMap.end() != entry ; ++entry )
264  {
265  const AIDA::IHistogram1D* aida = entry->second ;
266  if ( NULL == aida )
267  { this->error() << "IHistogram1D points to NULL" << endmsg ; continue ; }
268  // format and print the row
269  msg << std::endl << table.toString
270  ( aida ,
271  HistoID ( entry->first ) ,
272  m_histo1DTableFormatShort ) ;
273  }
274  msg << endmsg ;
275  }
276  // ==========================================================================
277  if ( !histo2DMapID().empty() )
278  {
279  msg << "List of booked 2D histograms in directory "
280  << "\"" << histoPath() << "\" :-" ;
281 
282  // temporary map to keep ordered IDs
283  typedef std::map<HistoID,const AIDA::IHistogram2D*> OrderedMapType;
284  OrderedMapType OrderedMap ( histo2DMapID().begin() , histo2DMapID().end() ) ;
285  //
286  for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
287  OrderedMap.end() != entry ; ++entry )
288  {
289  const AIDA::IHistogram2D* aida = entry->second ;
290  if ( NULL == aida )
291  { this->error() << "IHistogram2D points to NULL" << endmsg ; continue ; }
292  msg << std::endl
293  << GaudiAlg::Print2D::toString ( aida , entry->first );
294  }
295  msg << endmsg ;
296  }
297  // ==========================================================================
298  if ( !histo3DMapID().empty() )
299  {
300  msg << "List of booked 3D histograms in directory "
301  << "\"" << histoPath() << "\" :-" ;
302  // temporary map to keep ordered IDs
303  typedef std::map<HistoID,const AIDA::IHistogram3D*> OrderedMapType;
304  OrderedMapType OrderedMap ( histo3DMapID().begin() , histo3DMapID().end() ) ;
305  //
306  for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
307  OrderedMap.end() != entry ; ++entry )
308  {
309  const AIDA::IHistogram3D* aida = entry->second ;
310  if ( NULL == aida )
311  { this->error() << "IHistogram3D points to NULL" << endmsg ; continue ; }
312  msg << std::endl << GaudiAlg::Print3D::toString ( aida , entry->first );
313  }
314  msg << endmsg ;
315  }
316  // ==========================================================================
317  if ( !profile1DMapID().empty() )
318  {
319  msg << "List of booked 1D profile histograms in directory "
320  << "\"" << histoPath() << "\" :-" ;
321  // temporary map to keep ordered IDs
322  typedef std::map<HistoID,const AIDA::IProfile1D*> OrderedMapType;
323  OrderedMapType OrderedMap ( profile1DMapID().begin() , profile1DMapID().end() ) ;
324  //
325  for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
326  OrderedMap.end() != entry ; ++entry )
327  {
328  const AIDA::IProfile1D* aida = entry->second ;
329  if ( NULL == aida )
330  { this->error() << "IProfile1D points to NULL" << endmsg ; continue ; }
331  msg << std::endl << GaudiAlg::Print1DProf::toString ( aida , entry->first );
332  }
333  msg << endmsg ;
334  }
335  // ==========================================================================
336  if ( !profile2DMapID().empty() )
337  {
338  msg << "List of booked 2D profile histograms in directory "
339  << "\"" << histoPath() << "\" :-" ;
340  // temporary map to keep ordered IDs
341  typedef std::map<HistoID,const AIDA::IProfile2D*> OrderedMapType;
342  OrderedMapType OrderedMap ( profile2DMapID().begin() , profile2DMapID().end() ) ;
343  //
344  for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
345  OrderedMap.end() != entry ; ++entry )
346  {
347  const AIDA::IProfile2D* aida = entry->second ;
348  if ( NULL == aida )
349  { this->error() << "IProfile2D points to NULL" << endmsg ; continue ; }
350  msg << std::endl << GaudiAlg::Print2DProf::toString ( aida , entry->first );
351  }
352  msg << endmsg ;
353  }
354  //
355  return this->totalNumberOfHistos() ;
356 }
357 // ============================================================================
358 // Check if all histogram maps are empty
359 // ============================================================================
360 template <class PBASE>
362 {
363  return ( histo1DMapTitle () . empty() &&
364  histo2DMapTitle () . empty() &&
365  histo3DMapTitle () . empty() &&
366  profile1DMapTitle () . empty() &&
367  profile2DMapTitle () . empty() &&
368  histo1DMapID () . empty() &&
369  histo2DMapID () . empty() &&
370  histo3DMapID () . empty() &&
371  profile1DMapID () . empty() &&
372  profile2DMapID () . empty() );
373 }
374 // ============================================================================
375 // Declare a histogram to the monitor service
376 // ============================================================================
377 template <class PBASE>
379 ( const AIDA::IBaseHistogram* hist,
380  const HistoID& ID ) const
381 {
382  if ( hist && m_declareMoniHists )
383  {
384  if ( this->msgLevel(MSG::DEBUG) )
385  {
386  this->debug() << "Monitoring histogram '"
387  << ID.idAsString() << "' desc = '"
388  << Gaudi::Utils::Histos::htitle(hist) << "'" << endmsg;
389  }
390  this->declareInfo ( histoPath()+"/"+ID.idAsString() ,
391  hist ,
393  }
394 }
395 // ============================================================================
396 // access the EXISTING 1D histogram by ID
397 // ============================================================================
398 template <class PBASE>
399 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D ( const HistoID& ID ) const
400 {
401  AIDA::IHistogram1D * h(NULL);
402  //
403  Histo1DMapID::const_iterator found = histo1DMapID().find( ID ) ;
404  //
405  h = ( histo1DMapID().end() == found ? NULL : found->second );
406  //
407  return h ;
408 }
409 // ============================================================================
410 // access the EXISTING 2D histogram by ID
411 // ============================================================================
412 template <class PBASE>
413 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D ( const HistoID& ID ) const
414 {
415  AIDA::IHistogram2D * h(NULL);
416  //
417  Histo2DMapID::const_iterator found = histo2DMapID().find( ID ) ;
418  //
419  h = ( histo2DMapID().end() == found ? NULL : found->second );
420  //
421  return h;
422 }
423 // ============================================================================
424 // access the EXISTING 3D histogram by ID
425 // ============================================================================
426 template <class PBASE>
427 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D ( const HistoID& ID ) const
428 {
429  AIDA::IHistogram3D * h(NULL);
430  //
431  Histo3DMapID::const_iterator found = histo3DMapID().find( ID ) ;
432  h = ( histo3DMapID().end() == found ? NULL : found->second );
433  //
434  return h;
435 }
436 // ============================================================================
437 // access the EXISTING 1D profile histogram by ID
438 // ============================================================================
439 template <class PBASE>
440 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D ( const HistoID& ID ) const
441 {
442  AIDA::IProfile1D * h(NULL);
443  //
444  Profile1DMapID::const_iterator found = profile1DMapID().find( ID ) ;
445  //
446  h = ( profile1DMapID().end() == found ? NULL : found->second );
447  //
448  return h;
449 }
450 // ============================================================================
451 // access the EXISTING 2D profile histogram by ID
452 // ============================================================================
453 template <class PBASE>
454 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D ( const HistoID& ID ) const
455 {
456  AIDA::IProfile2D * h(NULL);
457  //
458  Profile2DMapID::const_iterator found = profile2DMapID().find( ID ) ;
459  //
460  h = ( profile2DMapID().end() == found ? NULL : found->second );
461  //
462  return h;
463 }
464 // ============================================================================
465 // Returns the total number of histograms (of all types) currently booked
466 // ============================================================================
467 template <class PBASE>
469 {
470  return
471  histo1DMapID () . size () +
472  histo2DMapID () . size () +
473  histo3DMapID () . size () +
474  profile1DMapID () . size () +
475  profile2DMapID () . size () ;
476 }
477 // ============================================================================
478 // Create a new histogram ID using the given title
479 // ============================================================================
480 template <class PBASE>
482 ( const std::string & title ,
483  HistoID& ID ) const
484 {
485  if ( useNumericAutoIDs() || title.empty() )
486  {
487  if ( !useNumericAutoIDs() )
488  {
489  this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
491  }
492  // propose the histogram ID (always numeric)
493  ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
494  // adjust the proposed ID
495  while ( histoExists( ID ) ) { ID = HistoID ( ID.numeric() + 1 ) ; }
496  }
497  else
498  {
499  // use the title to create a unique literal ID
500  ID = HistoID( this->convertTitleToID(title) );
501  // Just in case ...
502  while ( histoExists( ID ) ) { ID = HistoID(ID.idAsString()+"_"); }
503  }
504 }
505 // ============================================================================
506 // Create an ID string from a title string
507 // ============================================================================
508 template <class PBASE>
510 {
511  // clean up the ID string for all unwanted characters
512  std::string tmp_id = title;
514  m_idReplaceInfo.begin() ; i != m_idReplaceInfo.end(); ++i )
515  {
516  stringSearchReplace( tmp_id, i->first, i->second );
517  }
518  return tmp_id;
519 }
520 // ============================================================================
521 // Searches 'title' for all instancies of 'A' and replaces them with 'B'
522 // ============================================================================
523 template <class PBASE>
525 ( std::string & title ,
526  const std::string & A ,
527  const std::string & B ) const
528 {
529  std::string::size_type slash = title.find_first_of ( A ) ;
530  while ( std::string::npos != slash )
531  {
532  title = title.substr(0,slash) + B + title.substr(slash+A.size());
533  slash = title.find_first_of( A );
534  }
535 }
536 // ============================================================================
537 // the handler for "HistoPrint" property
538 // ============================================================================
539 template < class PBASE >
541 {
542  // no action if not yet initialized
543  if ( this -> FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
544  if ( this -> histosPrint() ) { this -> printHistos ( MSG::ALWAYS ) ; }
545 }
546 // ============================================================================
547 // get the constructed histogram path
548 // ============================================================================
549 template < class PBASE >
551 {
552  const std::string path = histoTopDir() + histoDir();
553  return ( splitHistoDir() ? dirHbookName(path) : path );
554 }
555 // ============================================================================
556 // 1D
559 // 2D
562 // 3D
565 // 1D Profile
568 // 2D Profile
571 // ============================================================================
572 // The END
573 // ============================================================================
574 #endif // GAUDIALG_GAUDIHISTOS_ICPP
575 // ============================================================================

Generated at Wed Dec 4 2013 14:33:07 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004