Gaudi Framework, version v21r6

Home   Generated: 11 Nov 2009

GaudiHistos.icpp

Go to the documentation of this file.
00001 // $Id: GaudiHistos.icpp,v 1.17 2008/10/10 12:39:04 marcocle Exp $
00002 // ============================================================================
00003 #ifndef GAUDIALG_GAUDIHISTOS_ICPP
00004 #define GAUDIALG_GAUDIHISTOS_ICPP 1
00005 // ============================================================================
00006 /* @file
00007  *
00008  *  Implementation file for class : GaudiHistos
00009  *
00010  *  @author Chris Jones   Christopher.Rob.Jones@cern.ch
00011  *  @author Vanya BELYAEV Ivan.Belyaev@itep.ru
00012  *  @date   2005-08-08
00013  */
00014 // ============================================================================
00015 // STD & STL
00016 // ============================================================================
00017 #include <algorithm>
00018 #include <string>
00019 #include <vector>
00020 #include <set>
00021 // ============================================================================
00022 // GaudiKernel
00023 // ============================================================================
00024 #include "GaudiKernel/MsgStream.h"
00025 #include "GaudiKernel/IHistogramSvc.h"
00026 // ============================================================================
00027 // GaudiUtils
00028 // ============================================================================
00029 #include "GaudiUtils/HistoTableFormat.h"
00030 // ============================================================================
00031 // GaudiAlg
00032 // ============================================================================
00033 #include "GaudiAlg/GaudiHistos.h"
00034 #include "GaudiAlg/CheckForNaN.h"
00035 #include "GaudiAlg/Print.h"
00036 #include "GaudiAlg/Fill.h"
00037 // ============================================================================
00038 // forward declarations from AIDA
00039 // ============================================================================
00040 namespace AIDA
00041 {
00042   class IBaseHistogram ;
00043   class IHistogram     ;
00044   class IHistogram1D   ;
00045   class IHistogram2D   ;
00046   class IHistogram3D   ;
00047   class IProfile       ;
00048   class IProfile1D     ;
00049   class IProfile2D     ;
00050 }
00051 // ============================================================================
00052 // Destructor
00053 // ============================================================================
00054 template <class PBASE>
00055 GaudiHistos<PBASE>::~GaudiHistos() {}
00056 // =============================================================================
00057 // Constructor initialisation and job options
00058 // =============================================================================
00059 template <class PBASE>
00060 void GaudiHistos<PBASE>::initGaudiHistosConstructor()
00061 {
00062   // SWITCH ON/OFF the histograms
00063   this->declareProperty
00064     ( "HistoProduce"          ,
00065       m_produceHistos = true  ,
00066       "Swith on/off the production of histograms "   ) ;
00067   // print the histograms at finalization
00068   this->declareProperty
00069     ( "HistoPrint"            ,
00070       m_histosPrint   = false ,
00071       "Switch on/off the printout of histograms at finalization"    )
00072     -> declareUpdateHandler ( &GaudiHistos<PBASE>::printHistoHandler, this ) ;
00073   // check for NaN/Finite
00074   this->declareProperty
00075     ( "HistoCheckForNaN"      ,
00076       m_checkForNaN   = true  ,
00077       "Swicth on/off the checks for NaN and Infinity for histogram fill" ) ;
00078   // for HBOOK persistency, 'true' can be useful
00079   this->declareProperty
00080     ( "HistoSplitDir"         ,
00081       m_splitHistoDir = false ,
00082       "Split long directory names into short pieces (suitable for HBOOK)" );
00083   // general OffSet for histogram ID
00084   this->declareProperty
00085     ( "HistoOffSet"           ,
00086       m_histoOffSet   =   0   ,
00087       "OffSet for automatically assigned histogram numerical identifiers " ) ;
00088   // top level histogram directory
00089   this->declareProperty
00090     ( "HistoTopDir"           ,
00091       m_histoTopDir   =   ""  ,
00092       "Top level histogram directory (take care that it ends with '/')" ) ;
00093   // histogram directory
00094   this->declareProperty
00095     ( "HistoDir"             ,
00096       m_histoDir      = this->name() ,
00097       "Histogram Directory" ) ;
00098   // control output level of histograms
00099   this->declareProperty ( "FullDetail"            , m_fullDetail    = false ) ;
00100   // monitor histograms
00101   this->declareProperty ( "MonitorHistograms"     , m_declareMoniHists = true ) ;
00102   // format for 1D-histograms printout
00103   this->declareProperty
00104     ( "FormatFor1DHistoTable" ,
00105       m_histo1DTableFormat   = Gaudi::Utils::Histos::Formats::format () ,
00106       "Format string for printout of 1D histograms"      ) ;
00107   // "short" format for 1D-histograms printout
00108   this->declareProperty
00109     ( "ShortFormatFor1DHistoTable" ,
00110       m_histo1DTableFormatShort   = " | %1$-25.25s %2%"  ,
00111       "Format string for printout of 1D histograms"      ) ;
00112   // the header for 1D-histogram tabkle
00113   this->declareProperty
00114     ( "HeaderFor1DHistoTable" ,
00115       m_histo1DTableHeader   = Gaudi::Utils::Histos::Formats::header () ,
00116       "The table header for printout of 1D histograms "  ) ;
00117   this->declareProperty
00118     ( "UseSequencialNumericAutoIDs", m_useNumericAutoIDs = false,
00119       "Flag to allow users to switch back to the old style of creating numerical automatic IDs" );
00120   m_idReplaceInfo.clear();
00121   m_idReplaceInfo["/"] = "=SLASH=";
00122   this->declareProperty
00123     ( "AutoStringIDPurgeMap", m_idReplaceInfo,
00124       "Map of strings to search and replace when using the title as the basis of automatically generated literal IDs" );
00125 }
00126 // ============================================================================
00127 // Initialise Histogramming
00128 // ============================================================================
00129 template <class PBASE>
00130 StatusCode GaudiHistos<PBASE>::initialize()
00131 {
00132   // initialize base class
00133   const StatusCode sc = PBASE::initialize();
00134   if ( sc.isFailure() ) return sc;
00135 
00136   // produce histograms?
00137   if ( !produceHistos() )
00138   {
00139     this->debug() << "Histogram production is switched OFF" << endmsg;
00140     return sc;
00141   }
00142 
00143   // check the validity of histogram service
00144   if ( this->histoSvc() == NULL )
00145   { return this->Error("initialize():: IHistogramSvc* is invalid"); }
00146 
00147   // Warn if the user has decided to use numerical automatic IDs
00148   if ( useNumericAutoIDs() )
00149   {
00150     this ->
00151       Warning( "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
00152                StatusCode::SUCCESS );
00153   }
00154 
00155   // Finally, print the location histogram will be written to
00156   Print
00157     ( "The histogram path is set to be '" + histoPath() + "'",
00158       StatusCode( StatusCode::SUCCESS, true )  , MSG::DEBUG );
00159 
00160   return sc;
00161 }
00162 // ============================================================================
00163 // Finalise Histogramming
00164 // ============================================================================
00165 template <class PBASE>
00166 StatusCode GaudiHistos<PBASE>::finalize()
00167 {
00168 
00169   if ( produceHistos() )
00170   {
00171 
00172     // Count how many histos of each type
00173     if ( !noHistos() )
00174     {
00175       const unsigned int n1D  = histo1DMapID   () . size () ;
00176       const unsigned int n2D  = histo2DMapID   () . size () ;
00177       const unsigned int n3D  = histo3DMapID   () . size () ;
00178       const unsigned int n1DP = profile1DMapID () . size () ;
00179       const unsigned int n2DP = profile2DMapID () . size () ;
00180       const unsigned int total = n1D+n2D+n3D+n1DP+n2DP;
00181       if ( total>0 )
00182       {
00183         this->always() << "Booked " << total << " Histogram(s) : ";
00184         if ( n1D>0  ) this->always() << "1D=" << n1D << " ";
00185         if ( n2D>0  ) this->always() << "2D=" << n2D << " ";
00186         if ( n3D>0  ) this->always() << "3D=" << n3D << " ";
00187         if ( n1DP>0 ) this->always() << "1DProf=" << n1DP << " ";
00188         if ( n2DP>0 ) this->always() << "2DProf=" << n2DP << " ";
00189         this->always() << endmsg;
00190       }
00191     }
00192 
00193     // detailed printing
00194     if ( histosPrint() ) { printHistos() ; }
00195 
00196   }
00197 
00198   // clear all maps
00199   m_histo1DMapTitle   . clear () ;
00200   m_histo2DMapTitle   . clear () ;
00201   m_histo3DMapTitle   . clear () ;
00202   m_histo1DMapID      . clear () ;
00203   m_histo2DMapID      . clear () ;
00204   m_histo3DMapID      . clear () ;
00205   m_profile1DMapTitle . clear () ;
00206   m_profile2DMapTitle . clear () ;
00207   m_profile1DMapID    . clear () ;
00208   m_profile2DMapID    . clear () ;
00209 
00210   // finalize base class
00211   return PBASE::finalize();
00212 }
00213 // ============================================================================
00214 // perform the actual detailed printout of histograms
00215 // ============================================================================
00216 template <class PBASE>
00217 int GaudiHistos<PBASE>::printHistos ( const MSG::Level level ) const
00218 {
00219   using namespace Gaudi::Utils::Histos ;
00220 
00221   if ( noHistos() )
00222   {
00223     if ( this->msgLevel(MSG::DEBUG) )
00224     { this->msgStream(level) << "No histograms are booked" << endmsg ; }
00225     return 0 ;                                                        // RETURN
00226   }
00227 
00228   MsgStream & msg = this->msgStream(level);
00229 
00230   // Printout all histograms
00231 
00232   Gaudi::Utils::Histos::Table table
00233     ( m_histo1DTableFormat ,
00234       m_histo1DTableHeader ) ;
00235 
00236   if ( !histo1DMapID().empty() )
00237   {
00238     msg << "List of booked 1D histograms in directory         "
00239         << "\"" << histoPath() << "\" :-"  ;
00240 
00241     if ( !table.header().empty() )
00242     {
00243       msg << std::endl << Gaudi::Utils::Histos::format
00244         ( "ID" , table.header() , m_histo1DTableFormatShort ) ;
00245     }
00246     // temporary map to keep ordered IDs
00247     typedef std::map<HistoID,const AIDA::IHistogram1D*> OrderedMapType;
00248     OrderedMapType OrderedMap ( histo1DMapID().begin() , histo1DMapID().end() );
00249     //
00250     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
00251           OrderedMap.end() != entry ; ++entry )
00252     {
00253       const AIDA::IHistogram1D* aida = entry->second ;
00254       if ( NULL == aida )
00255       { this->error() << "IHistogram1D points to NULL" << endmsg ; continue ; }
00256       // format and print the row
00257       msg << std::endl << table.toString
00258         ( aida                      ,
00259           HistoID ( entry->first )  ,
00260           m_histo1DTableFormatShort ) ;
00261     }
00262     msg << endmsg ;
00263   }
00264   // ==========================================================================
00265   if ( !histo2DMapID().empty() )
00266   {
00267     msg << "List of booked 2D histograms in directory         "
00268         << "\"" << histoPath() << "\" :-" ;
00269 
00270     // temporary map to keep ordered IDs
00271     typedef std::map<HistoID,const AIDA::IHistogram2D*> OrderedMapType;
00272     OrderedMapType OrderedMap ( histo2DMapID().begin() , histo2DMapID().end() ) ;
00273     //
00274     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
00275           OrderedMap.end() != entry ; ++entry )
00276     {
00277       const AIDA::IHistogram2D* aida = entry->second ;
00278       if ( NULL == aida )
00279       { this->error() << "IHistogram2D points to NULL" << endmsg ; continue ; }
00280       msg << std::endl
00281           << GaudiAlg::Print2D::toString ( aida , entry->first );
00282     }
00283     msg << endmsg ;
00284   }
00285   // ==========================================================================
00286   if ( !histo3DMapID().empty() )
00287   {
00288     msg << "List of booked 3D histograms in directory         "
00289         << "\"" << histoPath() << "\" :-" ;
00290     // temporary map to keep ordered IDs
00291     typedef std::map<HistoID,const AIDA::IHistogram3D*> OrderedMapType;
00292     OrderedMapType OrderedMap ( histo3DMapID().begin() , histo3DMapID().end() ) ;
00293     //
00294     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
00295           OrderedMap.end() != entry ; ++entry )
00296     {
00297       const AIDA::IHistogram3D* aida = entry->second ;
00298       if ( NULL == aida )
00299       { this->error() << "IHistogram3D points to NULL" << endmsg ; continue ; }
00300       msg << std::endl << GaudiAlg::Print3D::toString ( aida , entry->first );
00301     }
00302     msg << endmsg ;
00303   }
00304   // ==========================================================================
00305   if ( !profile1DMapID().empty() )
00306   {
00307     msg << "List of booked 1D profile histograms in directory "
00308         << "\"" << histoPath() << "\" :-" ;
00309     // temporary map to keep ordered IDs
00310     typedef std::map<HistoID,const AIDA::IProfile1D*> OrderedMapType;
00311     OrderedMapType OrderedMap ( profile1DMapID().begin() , profile1DMapID().end() ) ;
00312     //
00313     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
00314           OrderedMap.end() != entry ; ++entry )
00315     {
00316       const AIDA::IProfile1D*   aida = entry->second ;
00317       if ( NULL == aida )
00318       { this->error() << "IProfile1D points to NULL" << endmsg ; continue ; }
00319       msg << std::endl << GaudiAlg::Print1DProf::toString  ( aida , entry->first );
00320     }
00321     msg << endmsg ;
00322   }
00323   // ==========================================================================
00324   if ( !profile2DMapID().empty() )
00325   {
00326     msg << "List of booked 2D profile histograms in directory "
00327         << "\"" << histoPath() << "\" :-" ;
00328     // temporary map to keep ordered IDs
00329     typedef std::map<HistoID,const AIDA::IProfile2D*> OrderedMapType;
00330     OrderedMapType OrderedMap ( profile2DMapID().begin() , profile2DMapID().end() ) ;
00331     //
00332     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
00333           OrderedMap.end() != entry ; ++entry )
00334     {
00335       const AIDA::IProfile2D*   aida = entry->second ;
00336       if ( NULL == aida )
00337       { this->error() << "IProfile2D points to NULL" << endmsg ; continue ; }
00338       msg << std::endl << GaudiAlg::Print2DProf::toString ( aida , entry->first );
00339     }
00340     msg << endmsg ;
00341   }
00342   //
00343   return this->totalNumberOfHistos() ;
00344 }
00345 // ============================================================================
00346 // Check if all histogram maps are empty
00347 // ============================================================================
00348 template <class PBASE>
00349 bool GaudiHistos<PBASE>::noHistos() const
00350 {
00351   return ( histo1DMapTitle   () . empty() &&
00352            histo2DMapTitle   () . empty() &&
00353            histo3DMapTitle   () . empty() &&
00354            profile1DMapTitle () . empty() &&
00355            profile2DMapTitle () . empty() &&
00356            histo1DMapID      () . empty() &&
00357            histo2DMapID      () . empty() &&
00358            histo3DMapID      () . empty() &&
00359            profile1DMapID    () . empty() &&
00360            profile2DMapID    () . empty() );
00361 }
00362 // ============================================================================
00363 // Declare a histogram to the monitor service
00364 // ============================================================================
00365 template <class PBASE>
00366 void GaudiHistos<PBASE>::monitorHisto
00367 ( const AIDA::IBaseHistogram* hist,
00368   const HistoID& ID ) const
00369 {
00370   if ( hist && m_declareMoniHists )
00371   {
00372     if ( this->msgLevel(MSG::DEBUG) )
00373     {
00374       this->debug() << "Monitoring histogram '"
00375                     << ID.idAsString() << "' desc = '"
00376                     << Gaudi::Utils::Histos::htitle(hist) << "'" << endmsg;
00377     }
00378     this->declareInfo ( histoPath()+"/"+ID.idAsString() ,
00379                         hist            ,
00380                         Gaudi::Utils::Histos::htitle(hist) ) ;
00381   }
00382 }
00383 // ============================================================================
00384 // access the EXISTING 1D histogram by ID
00385 // ============================================================================
00386 template <class PBASE>
00387 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D ( const HistoID& ID )  const
00388 {
00389   AIDA::IHistogram1D * h(NULL);
00390   //
00391   Histo1DMapID::const_iterator found = histo1DMapID().find( ID ) ;
00392   //
00393   h = ( histo1DMapID().end() == found ? NULL : found->second );
00394   //
00395   return h ;
00396 }
00397 // ============================================================================
00398 // access the EXISTING 2D histogram by ID
00399 // ============================================================================
00400 template <class PBASE>
00401 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D ( const HistoID& ID )  const
00402 {
00403   AIDA::IHistogram2D * h(NULL);
00404   //
00405   Histo2DMapID::const_iterator found = histo2DMapID().find( ID ) ;
00406   //
00407   h = ( histo2DMapID().end() == found ? NULL : found->second );
00408   //
00409   return h;
00410 }
00411 // ============================================================================
00412 // access the EXISTING 3D histogram by ID
00413 // ============================================================================
00414 template <class PBASE>
00415 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D ( const HistoID& ID )  const
00416 {
00417   AIDA::IHistogram3D * h(NULL);
00418   //
00419   Histo3DMapID::const_iterator found = histo3DMapID().find( ID ) ;
00420   h = ( histo3DMapID().end() == found ? NULL : found->second );
00421   //
00422   return h;
00423 }
00424 // ============================================================================
00425 // access the EXISTING 1D profile histogram by ID
00426 // ============================================================================
00427 template <class PBASE>
00428 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D ( const HistoID& ID )  const
00429 {
00430   AIDA::IProfile1D * h(NULL);
00431   //
00432   Profile1DMapID::const_iterator found = profile1DMapID().find( ID ) ;
00433   //
00434   h = ( profile1DMapID().end() == found ? NULL : found->second );
00435   //
00436   return h;
00437 }
00438 // ============================================================================
00439 // access the EXISTING 2D profile histogram by ID
00440 // ============================================================================
00441 template <class PBASE>
00442 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D ( const HistoID& ID )  const
00443 {
00444   AIDA::IProfile2D * h(NULL);
00445   //
00446   Profile2DMapID::const_iterator found = profile2DMapID().find( ID ) ;
00447   //
00448   h = ( profile2DMapID().end() == found ? NULL : found->second );
00449   //
00450   return h;
00451 }
00452 // ============================================================================
00453 // Returns the total number of histograms (of all types) currently booked
00454 // ============================================================================
00455 template <class PBASE>
00456 unsigned int GaudiHistos<PBASE>::totalNumberOfHistos() const
00457 {
00458   return
00459     histo1DMapID   () . size () +
00460     histo2DMapID   () . size () +
00461     histo3DMapID   () . size () +
00462     profile1DMapID () . size () +
00463     profile2DMapID () . size () ;
00464 }
00465 // ============================================================================
00466 // Create a new histogram ID using the given title
00467 // ============================================================================
00468 template <class PBASE>
00469 void GaudiHistos<PBASE>::newHistoID
00470 ( const std::string & title ,
00471   HistoID&            ID    ) const
00472 {
00473   if ( useNumericAutoIDs() || title.empty() )
00474   {
00475     if ( !useNumericAutoIDs() )
00476     {
00477       this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
00478                        StatusCode::SUCCESS );
00479     }
00480     // propose the histogram ID (always numeric)
00481     ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
00482     // adjust the proposed ID
00483     while ( histoExists( ID ) ) { ID = HistoID ( ID.numeric() + 1 ) ; }
00484   }
00485   else
00486   {
00487     // use the title to create a unique literal ID
00488     ID = HistoID( this->convertTitleToID(title) );
00489     // Just in case ...
00490     while ( histoExists( ID ) ) { ID = HistoID(ID.idAsString()+"_"); }
00491   }
00492 }
00493 // ============================================================================
00494 // Create an ID string from a title string
00495 // ============================================================================
00496 template <class PBASE>
00497 std::string GaudiHistos<PBASE>::convertTitleToID( const std::string & title ) const
00498 {
00499   // clean up the ID string for all unwanted characters
00500   std::string tmp_id = title;
00501   for ( std::map<std::string,std::string>::const_iterator i =
00502           m_idReplaceInfo.begin() ; i != m_idReplaceInfo.end(); ++i )
00503   {
00504     stringSearchReplace( tmp_id, i->first, i->second );
00505   }
00506   return tmp_id;
00507 }
00508 // ============================================================================
00509 // Searches 'title' for all instancies of 'A' and replaces them with 'B'
00510 // ============================================================================
00511 template <class PBASE>
00512 void GaudiHistos<PBASE>::stringSearchReplace
00513 ( std::string       & title ,
00514   const std::string & A     ,
00515   const std::string & B     ) const
00516 {
00517   std::string::size_type slash = title.find_first_of ( A ) ;
00518   while ( std::string::npos != slash )
00519   {
00520     title = title.substr(0,slash) + B + title.substr(slash+A.size());
00521     slash = title.find_first_of( A );
00522   }
00523 }
00524 // ============================================================================
00525 // the handler for "HistoPrint" property
00526 // ============================================================================
00527 template < class PBASE >
00528 void GaudiHistos<PBASE>::printHistoHandler( Property& )
00529 {
00530   // no action if not yet initialized
00531   if ( this -> FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00532   if ( this -> histosPrint() ) { this -> printHistos ( MSG::ALWAYS ) ; }
00533 }
00534 // ============================================================================
00535 // 1D
00536 #include "GaudiAlg/GaudiHistos_1DFixedBinning.icpp"
00537 #include "GaudiAlg/GaudiHistos_1DVariableBinning.icpp"
00538 // 2D
00539 #include "GaudiAlg/GaudiHistos_2DFixedBinning.icpp"
00540 #include "GaudiAlg/GaudiHistos_2DVariableBinning.icpp"
00541 // 3D
00542 #include "GaudiAlg/GaudiHistos_3DFixedBinning.icpp"
00543 #include "GaudiAlg/GaudiHistos_3DVariableBinning.icpp"
00544 // 1D Profile
00545 #include "GaudiAlg/GaudiHistos_1DProfFixedBinning.icpp"
00546 #include "GaudiAlg/GaudiHistos_1DProfVariableBinning.icpp"
00547 // 2D Profile
00548 #include "GaudiAlg/GaudiHistos_2DProfFixedBinning.icpp"
00549 #include "GaudiAlg/GaudiHistos_2DProfVariableBinning.icpp"
00550 // ============================================================================
00551 // The END
00552 // ============================================================================
00553 #endif // GAUDIALG_GAUDIHISTOS_ICPP
00554 // ============================================================================

Generated at Wed Nov 11 16:22:56 2009 for Gaudi Framework, version v21r6 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004