Gaudi Framework, version v23r6

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

Generated at Wed Jan 30 2013 17:13:37 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004