| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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"
25 #include "GaudiKernel/IHistogramSvc.h"
26 // ============================================================================
27 // GaudiUtils
28 // ============================================================================
29 #include "GaudiUtils/HistoTableFormat.h"
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>
56 void GaudiHistos<PBASE>::initGaudiHistosConstructor()
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>
130 StatusCode GaudiHistos<PBASE>::
131 #ifdef __ICC
132 i_ghInitialize
133 #else
134 initialize
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>
172 StatusCode GaudiHistos<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>
229 int GaudiHistos<PBASE>::printHistos ( const MSG::Level level ) const
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 {
255 msg << std::endl << Gaudi::Utils::Histos::format
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>
361 bool GaudiHistos<PBASE>::noHistos() const
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>
378 void GaudiHistos<PBASE>::monitorHisto
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 ,
392 Gaudi::Utils::Histos::htitle(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>
468 unsigned int GaudiHistos<PBASE>::totalNumberOfHistos() const
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>
481 void GaudiHistos<PBASE>::newHistoID
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",
490 StatusCode::SUCCESS );
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>
509 std::string GaudiHistos<PBASE>::convertTitleToID( const std::string & title ) const
510 {
511 // clean up the ID string for all unwanted characters
512 std::string tmp_id = title;
513 for ( std::map<std::string,std::string>::const_iterator i =
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>
524 void GaudiHistos<PBASE>::stringSearchReplace
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 >
540 void GaudiHistos<PBASE>::printHistoHandler( Property& )
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 >
550 std::string GaudiHistos<PBASE>::histoPath () const
551 {
552 const std::string path = histoTopDir() + histoDir();
553 return ( splitHistoDir() ? dirHbookName(path) : path );
554 }
555 // ============================================================================
556 // 1D
557 #include "GaudiAlg/GaudiHistos_1DFixedBinning.icpp"
558 #include "GaudiAlg/GaudiHistos_1DVariableBinning.icpp"
559 // 2D
560 #include "GaudiAlg/GaudiHistos_2DFixedBinning.icpp"
561 #include "GaudiAlg/GaudiHistos_2DVariableBinning.icpp"
562 // 3D
563 #include "GaudiAlg/GaudiHistos_3DFixedBinning.icpp"
564 #include "GaudiAlg/GaudiHistos_3DVariableBinning.icpp"
565 // 1D Profile
566 #include "GaudiAlg/GaudiHistos_1DProfFixedBinning.icpp"
567 #include "GaudiAlg/GaudiHistos_1DProfVariableBinning.icpp"
568 // 2D Profile
569 #include "GaudiAlg/GaudiHistos_2DProfFixedBinning.icpp"
570 #include "GaudiAlg/GaudiHistos_2DProfVariableBinning.icpp"
571 // ============================================================================
572 // The END
573 // ============================================================================
574 #endif // GAUDIALG_GAUDIHISTOS_ICPP
575 // ============================================================================