Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

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

Generated at Wed Feb 9 16:24:47 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004