Gaudi Framework, version v23r8

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

Generated at Fri May 31 2013 15:09:03 for Gaudi Framework, version v23r8 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004