| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# 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   // check for NaN/Finite
    00073   this->declareProperty
    00074     ( "HistoCheckForNaN"      ,
    00075       m_checkForNaN   = true  ,
    00076       "Swicth on/off the checks for NaN and Infinity for histogram fill" ) ;
    00077   // for HBOOK persistency, 'true' can be useful
    00078   this->declareProperty
    00079     ( "HistoSplitDir"         ,
    00080       m_splitHistoDir = false ,
    00081       "Split long directory names into short pieces (suitable for HBOOK)" );
    00082   // general OffSet for histogram ID
    00083   this->declareProperty
    00084     ( "HistoOffSet"           ,
    00085       m_histoOffSet   =   0   ,
    00086       "OffSet for automatically assigned histogram numerical identifiers " ) ;
    00087   // top level histogram directory
    00088   this->declareProperty
    00089     ( "HistoTopDir"           ,
    00090       m_histoTopDir   =   ""  ,
    00091       "Top level histogram directory (take care that it ends with '/')" ) ;
    00092   // histogram directory
    00093   this->declareProperty
    00094     ( "HistoDir"             ,
    00095       m_histoDir      = this->name() ,
    00096       "Histogram Directory" ) ;
    00097   // control output level of histograms
    00098   this->declareProperty ( "FullDetail"            , m_fullDetail    = false ) ;
    00099   // monitor histograms
    00100   this->declareProperty ( "MonitorHistograms"     , m_declareMoniHists = true ) ;
    00101   // format for 1D-histograms printout
    00102   this->declareProperty
    00103     ( "FormatFor1DHistoTable" ,
    00104       m_histo1DTableFormat   = Gaudi::Utils::Histos::Formats::format () ,
    00105       "Format string for printout of 1D histograms"      ) ;
    00106   // "short" format for 1D-histograms printout
    00107   this->declareProperty
    00108     ( "ShortFormatFor1DHistoTable" ,
    00109       m_histo1DTableFormatShort   = " | %1$-25.25s %2%"  ,
    00110       "Format string for printout of 1D histograms"      ) ;
    00111   // the header for 1D-histogram tabkle
    00112   this->declareProperty
    00113     ( "HeaderFor1DHistoTable" ,
    00114       m_histo1DTableHeader   = Gaudi::Utils::Histos::Formats::header () ,
    00115       "The table header for printout of 1D histograms "  ) ;
    00116   this->declareProperty
    00117     ( "UseSequencialNumericAutoIDs", m_useNumericAutoIDs = false,
    00118       "Flag to allow users to switch back to the old style of creating numerical automatic IDs" );
    00119   m_idReplaceInfo.clear();
    00120   m_idReplaceInfo["/"] = "=SLASH=";
    00121   this->declareProperty
    00122     ( "AutoStringIDPurgeMap", m_idReplaceInfo,
    00123       "Map of strings to search and replace when using the title as the basis of automatically generated literal IDs" );
    00124 }
    00125 // ============================================================================
    00126 // Initialise Histogramming
    00127 // ============================================================================
    00128 template <class PBASE>
    00129 StatusCode GaudiHistos<PBASE>::initialize()
    00130 {
    00131   // initialize base class
    00132   const StatusCode sc = PBASE::initialize();
    00133   if ( sc.isFailure() ) return sc;
    00134
    00135   // produce histograms?
    00136   if ( !produceHistos() )
    00137   {
    00138     this->debug() << "Histogram production is switched OFF" << endreq;
    00139     return sc;
    00140   }
    00141
    00142   // check the validity of histogram service
    00143   if ( 0 == this->histoSvc() )
    00144   { return this->Error("initialize():: IHistogramSvc* is invalid"); }
    00145
    00146   // Warn if the user has decided to use numerical automatic IDs
    00147   if ( useNumericAutoIDs() )
    00148   {
    00149     this ->
    00150       Warning( "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
    00151                StatusCode::SUCCESS );
    00152   }
    00153
    00154   // Finally, print the location histogram will be written to
    00155   Print
    00156     ( "The histogram path is set to be '" + histoPath() + "'",
    00157       StatusCode( StatusCode::SUCCESS, true )  , MSG::DEBUG );
    00158
    00159   return sc;
    00160 }
    00161 // ============================================================================
    00162 // Finalise Histogramming
    00163 // ============================================================================
    00164 template <class PBASE>
    00165 StatusCode GaudiHistos<PBASE>::finalize()
    00166 {
    00167
    00168   if ( produceHistos() )
    00169   {
    00170
    00171     // Count how many histos of each type
    00172     if ( !noHistos() )
    00173     {
    00174       const unsigned int n1D  = histo1DMapNumID().size()+histo1DMapLitID().size();
    00175       const unsigned int n2D  = histo2DMapNumID().size()+histo2DMapLitID().size();
    00176       const unsigned int n3D  = histo3DMapNumID().size()+histo3DMapLitID().size();
    00177       const unsigned int n1DP = profile1DMapNumID().size()+profile1DMapLitID().size();
    00178       const unsigned int n2DP = profile2DMapNumID().size()+profile2DMapLitID().size();
    00179       const unsigned int total = n1D+n2D+n3D+n1DP+n2DP;
    00180       if ( total>0 )
    00181       {
    00182         this->always() << "Booked " << total << " Histogram(s) : ";
    00183         if ( n1D>0  ) this->always() << "1D=" << n1D << " ";
    00184         if ( n2D>0  ) this->always() << "2D=" << n2D << " ";
    00185         if ( n3D>0  ) this->always() << "3D=" << n3D << " ";
    00186         if ( n1DP>0 ) this->always() << "1DProf=" << n1DP << " ";
    00187         if ( n2DP>0 ) this->always() << "2DProf=" << n2DP << " ";
    00188         this->always() << endreq;
    00189       }
    00190     }
    00191
    00192     // detailed printing
    00193     if ( histosPrint() ) { printHistos() ; }
    00194
    00195   }
    00196
    00197   // clear all maps
    00198   m_histo1DMapTitle   .clear() ;
    00199   m_histo2DMapTitle   .clear() ;
    00200   m_histo3DMapTitle   .clear() ;
    00201   m_histo1DMapNumID   .clear() ;
    00202   m_histo1DMapLitID   .clear() ;
    00203   m_histo2DMapNumID   .clear() ;
    00204   m_histo2DMapLitID   .clear() ;
    00205   m_histo3DMapNumID   .clear() ;
    00206   m_histo3DMapLitID   .clear() ;
    00207   m_profile1DMapTitle .clear() ;
    00208   m_profile2DMapTitle .clear() ;
    00209   m_profile1DMapNumID .clear() ;
    00210   m_profile1DMapLitID .clear() ;
    00211   m_profile2DMapNumID .clear() ;
    00212   m_profile2DMapLitID .clear() ;
    00213
    00214   // finalize base class
    00215   return PBASE::finalize();
    00216 }
    00217 // ============================================================================
    00218 // perform the actual detailed printout of histograms
    00219 // ============================================================================
    00220 template <class PBASE>
    00221 int GaudiHistos<PBASE>::printHistos ( const MSG::Level level ) const
    00222 {
    00223   // temporary storage
    00224   std::set<const AIDA::IBaseHistogram*> histos   ;
    00225   std::set<const AIDA::IBaseHistogram*> profiles ;
    00226
    00227   using namespace Gaudi::Utils::Histos ;
    00228
    00229   if ( noHistos() )
    00230   { if (this->msgLevel(MSG::DEBUG)) this->msgStream(level) << "No histograms are booked" << endreq ; }
    00231   else
    00232   {
    00233     MsgStream & msg = this->msgStream(level);
    00234
    00235     // Printout all histograms
    00236     // Note, each must appear in either the numeric or literal map
    00237
    00238     Gaudi::Utils::Histos::Table table
    00239       ( m_histo1DTableFormat ,
    00240         m_histo1DTableHeader ) ;
    00241
    00242     if ( !histo1DMapNumID().empty() || !histo1DMapLitID().empty() )
    00243     {
    00244       msg << "List of booked 1D histograms in directory         "
    00245           << "\"" << histoPath() << "\" :-"  ;
    00246
    00247       if ( !table.header().empty() )
    00248       {
    00249         msg << std::endl << Gaudi::Utils::Histos::format
    00250           ( "ID" , table.header() , m_histo1DTableFormatShort ) ;
    00251       }
    00252       {
    00253         for ( Histo1DMapNumID::const_iterator entry = histo1DMapNumID().begin() ;
    00254               histo1DMapNumID().end() != entry ; ++entry )
    00255         {
    00256           AIDA::IHistogram1D* aida = entry->second ;
    00257           if ( 0 == aida )
    00258           { this->error() << "IHistogram1D points to NULL" << endreq ; continue ; }
    00259           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00260           histos.insert ( toBase ( aida  ) ) ;
    00261           // format and print the row
    00262           msg << std::endl << table.toString
    00263             ( aida                      ,
    00264               HistoID ( entry->first )  ,
    00265               m_histo1DTableFormatShort ) ;
    00266         }
    00267       }
    00268       {
    00269         for ( Histo1DMapLitID::const_iterator entry = histo1DMapLitID().begin() ;
    00270               histo1DMapLitID().end() != entry ; ++entry )
    00271         {
    00272           AIDA::IHistogram1D* aida = entry->second ;
    00273           if ( 0 == aida )
    00274           { this->error() << "IHistogram1D points to NULL" << endreq ; continue ; }
    00275           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00276           histos.insert ( toBase ( aida  ) ) ;
    00277           // format and print the row
    00278           msg << std::endl << table.toString
    00279             ( aida                      ,
    00280               entry->first              ,
    00281               m_histo1DTableFormatShort ) ;
    00282         }
    00283       }
    00284       msg << endreq ;
    00285     }
    00286     if ( !histo2DMapNumID().empty() || !histo2DMapLitID().empty() )
    00287     {
    00288       msg << "List of booked 2D histograms in directory         "
    00289           << "\"" << histoPath() << "\" :-" ;
    00290       {
    00291         for ( Histo2DMapNumID::const_iterator entry = histo2DMapNumID().begin() ;
    00292               histo2DMapNumID().end() != entry ; ++entry )
    00293         {
    00294           AIDA::IHistogram2D* aida = entry->second ;
    00295           if ( 0 == aida )
    00296           { this->error() << "IHistogram2D points to NULL" << endreq ; continue ; }
    00297           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00298           histos.insert ( toBase ( aida  ) ) ;
    00299           msg << std::endl
    00300               << GaudiAlg::Print2D::toString ( aida , entry->first );
    00301         }
    00302       }
    00303       {
    00304         for ( Histo2DMapLitID::const_iterator entry = histo2DMapLitID().begin() ;
    00305               histo2DMapLitID().end() != entry ; ++entry )
    00306         {
    00307           AIDA::IHistogram2D* aida = entry->second ;
    00308           if ( 0 == aida )
    00309           { this->error() << "IHistogram2D points to NULL" << endreq ; continue ; }
    00310           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00311           histos.insert ( toBase ( aida  ) ) ;
    00312           msg << std::endl
    00313               << GaudiAlg::Print2D::toString ( aida , entry->first );
    00314         }
    00315       }
    00316       msg << endreq ;
    00317     }
    00318
    00319     if ( !histo3DMapNumID().empty() || !histo3DMapLitID().empty() )
    00320     {
    00321       msg << "List of booked 3D histograms in directory         "
    00322           << "\"" << histoPath() << "\" :-" ;
    00323       {
    00324         for ( Histo3DMapNumID::const_iterator entry = histo3DMapNumID().begin() ;
    00325               histo3DMapNumID().end() != entry ; ++entry )
    00326         {
    00327           AIDA::IHistogram3D* aida = entry->second ;
    00328           if ( 0 == aida )
    00329           { this->error() << "IHistogram3D points to NULL" << endreq ; continue ; }
    00330           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00331           histos.insert ( toBase ( aida  ) ) ;
    00332           msg << std::endl << GaudiAlg::Print3D::toString ( aida , entry->first );
    00333         }
    00334       }
    00335       {
    00336         for ( Histo3DMapLitID::const_iterator entry = histo3DMapLitID().begin() ;
    00337               histo3DMapLitID().end() != entry ; ++entry )
    00338         {
    00339           AIDA::IHistogram3D* aida = entry->second ;
    00340           if ( 0 == aida )
    00341           { this->error() << "IHistogram3D points to NULL" << endreq ; continue ; }
    00342           if ( histos.end() != histos.find( toBase ( aida ) ) ) { continue ; }
    00343           histos.insert ( toBase ( aida  ) ) ;
    00344           msg << std::endl << GaudiAlg::Print3D::toString ( aida , entry->first ) ;
    00345         }
    00346       }
    00347       msg << endreq ;
    00348     }
    00349     if ( !profile1DMapNumID().empty() || !profile1DMapLitID().empty() )
    00350     {
    00351       msg << "List of booked 1D profile histograms in directory "
    00352           << "\"" << histoPath() << "\" :-" ;
    00353       {
    00354         for ( Profile1DMapNumID::const_iterator entry = profile1DMapNumID().begin() ;
    00355               profile1DMapNumID().end() != entry ; ++entry )
    00356         {
    00357           AIDA::IProfile1D*   aida = entry->second ;
    00358           if ( 0 == aida )
    00359           { this->error() << "IProfile1D points to NULL" << endreq ; continue ; }
    00360           if ( profiles.end() != profiles.find( toBase ( aida ) ) ) { continue ; }
    00361           profiles.insert ( toBase ( aida  ) ) ;
    00362           msg << std::endl << GaudiAlg::Print1DProf::toString  ( aida , entry->first );
    00363         }
    00364       }
    00365       {
    00366         for ( Profile1DMapLitID::const_iterator entry = profile1DMapLitID().begin() ;
    00367               profile1DMapLitID().end() != entry ; ++entry )
    00368         {
    00369           AIDA::IProfile1D*   aida = entry->second ;
    00370           if ( 0 == aida )
    00371           { this->error() << "IProfile1D points to NULL" << endreq ; continue ; }
    00372           if ( profiles.end() != profiles.find( toBase ( aida ) ) ) { continue ; }
    00373           profiles.insert ( toBase ( aida  ) ) ;
    00374           msg << std::endl << GaudiAlg::Print1DProf::toString ( aida , entry->first );
    00375         }
    00376       }
    00377       msg << endreq ;
    00378     }
    00379     if ( !profile2DMapNumID().empty() || !profile2DMapLitID().empty() )
    00380     {
    00381       msg << "List of booked 2D profile histograms in directory "
    00382           << "\"" << histoPath() << "\" :-" ;
    00383       {
    00384         for ( Profile2DMapNumID::const_iterator entry = profile2DMapNumID().begin() ;
    00385               profile2DMapNumID().end() != entry ; ++entry )
    00386         {
    00387           AIDA::IProfile2D*   aida = entry->second ;
    00388           if ( 0 == aida )
    00389           { this->error() << "IProfile2D points to NULL" << endreq ; continue ; }
    00390           if ( profiles.end() != profiles.find( toBase ( aida ) ) ) { continue ; }
    00391           profiles.insert ( toBase ( aida  ) ) ;
    00392           msg << std::endl << GaudiAlg::Print2DProf::toString ( aida , entry->first );
    00393         }
    00394       }
    00395       {
    00396         for ( Profile2DMapLitID::const_iterator entry = profile2DMapLitID().begin() ;
    00397               profile2DMapLitID().end() != entry ; ++entry )
    00398         {
    00399           AIDA::IProfile2D*   aida = entry->second ;
    00400           if ( 0 == aida )
    00401           { this->error() << "IProfile2D points to NULL" << endreq ; continue ; }
    00402           if ( profiles.end() != profiles.find( toBase ( aida ) ) ) { continue ; }
    00403           profiles.insert ( toBase ( aida  ) ) ;
    00404           msg << std::endl << GaudiAlg::Print2DProf::toString ( aida , entry->first );
    00405         }
    00406       }
    00407       msg << endreq ;
    00408     }
    00409
    00410   }
    00411   return histos.size() + profiles.size() ;
    00412 }
    00413 // ============================================================================
    00414 // Check if all histogram maps are empty
    00415 // ============================================================================
    00416 template <class PBASE>
    00417 bool GaudiHistos<PBASE>::noHistos() const
    00418 {
    00419   return ( histo1DMapTitle()   .empty() &&
    00420            histo2DMapTitle()   .empty() &&
    00421            histo3DMapTitle()   .empty() &&
    00422            profile1DMapTitle() .empty() &&
    00423            profile2DMapTitle() .empty() &&
    00424            histo1DMapNumID()   .empty() &&
    00425            histo1DMapLitID()   .empty() &&
    00426            histo2DMapNumID()   .empty() &&
    00427            histo2DMapLitID()   .empty() &&
    00428            histo3DMapNumID()   .empty() &&
    00429            histo3DMapLitID()   .empty() &&
    00430            profile1DMapNumID() .empty() &&
    00431            profile1DMapLitID() .empty() &&
    00432            profile2DMapNumID() .empty() &&
    00433            profile2DMapLitID() .empty() );
    00434 }
    00435 // ============================================================================
    00436
    00437 // ============================================================================
    00438 // Declare a histogram to the monitor service
    00439 // ============================================================================
    00440 template <class PBASE>
    00441 void GaudiHistos<PBASE>::monitorHisto
    00442 ( const AIDA::IBaseHistogram* hist,
    00443   const HistoID& ID ) const
    00444 {
    00445   if ( hist && m_declareMoniHists )
    00446   {
    00447     if ( this->msgLevel(MSG::DEBUG) )
    00448     {
    00449       this->debug() << "Monitoring histogram '"
    00450                     << ID.idAsString() << "' desc = '"
    00451                     << Gaudi::Utils::Histos::htitle  ( hist ) << endreq;
    00452     }
    00453     this->declareInfo ( histoPath()+"/"+ID.idAsString() ,
    00454                         hist            ,
    00455                         Gaudi::Utils::Histos::htitle ( hist ) ) ;
    00456   }
    00457 }
    00458 // ============================================================================
    00459 // ==================================== 1D ====================================
    00460 // ============================================================================
    00461 // book the 1D histogram (book on demand)
    00462 // ============================================================================
    00463 template <class PBASE>
    00464 AIDA::IHistogram1D*  GaudiHistos<PBASE>::book1D
    00465 ( const std::string&  title        ,
    00466   const double        low          ,
    00467   const double        high         ,
    00468   const unsigned long bins         ) const
    00469 {
    00470   // exist?
    00471   AIDA::IHistogram1D* hist = histo1D ( title ) ;
    00472   // histogram is already booked
    00473   if( 0 != hist      )                           { return hist ; } // RETURN !!
    00474
    00475   // propose the histogram ID
    00476   HistoID ID;
    00477   newHistoID( title, ID );
    00478
    00479   // Create a new histogram and return
    00480   return this -> book1D ( ID, title, low, high, bins );
    00481 }
    00482 // ============================================================================
    00483 // book the 1D histogram with forced ID (book on demand)
    00484 // ============================================================================
    00485 template <class PBASE>
    00486 AIDA::IHistogram1D*  GaudiHistos<PBASE>::book1D
    00487 ( const HistoID&                ID     ,
    00488   const std::string&            title  ,
    00489   const double                  low    ,
    00490   const double                  high   ,
    00491   const unsigned long           bins   ) const
    00492 {
    00493   // Check ID
    00494   if (ID.undefined())
    00495   {
    00496     this->Error("Undefined Histogram ID : Title='"+title+"'");
    00497     return NULL;
    00498   }
    00499
    00500   // exist?
    00501   AIDA::IHistogram1D* hist = histo1D ( ID ) ;
    00502   // histogram is already booked
    00503   if ( 0 != hist       )                         { return hist ; } // RETURN !!
    00504
    00505   // Histogram title
    00506   const std::string & htitle =
    00507     ( title.empty() ? "Unnamed 1D Histogram ID="+ID.idAsString() : title ) ;
    00508
    00509   // book the histogram
    00510   if ( ID.numeric() )
    00511   {
    00512     hist = this->histoSvc() -> book ( histoPath()  ,
    00513                                       ID.numericID() ,
    00514                                       htitle       ,
    00515                                       bins         ,
    00516                                       low          ,
    00517                                       high         ) ;
    00518   }
    00519   else if ( ID.literal() )
    00520   {
    00521     hist = this->histoSvc() -> book ( histoPath()+"/"+
    00522                                       ID.literalID() ,
    00523                                       htitle         ,
    00524                                       bins           ,
    00525                                       low            ,
    00526                                       high         ) ;
    00527   }
    00528
    00529   // check OK
    00530   if( 0 == hist )
    00531   { this->Error( "IHistogram1D* points to NULL! ID='" + ID.idAsString() +
    00532                  "' title='"+htitle+"'" ) ; return 0; } // RETURN !!
    00533
    00534   // add histogram into histogram storages
    00535   if      ( ID.numeric() )
    00536   { m_histo1DMapNumID [ ID.numericID() ] = hist ; }
    00537   else if ( ID.literal() )
    00538   { m_histo1DMapLitID [ ID.literalID() ] = hist ; }
    00539   m_histo1DMapTitle [ title ] = hist ;
    00540
    00541   // Declare to monitoring service
    00542   monitorHisto( Gaudi::Utils::Histos::toBase ( hist ) , ID );
    00543
    00544   // Printout and return
    00545   if ( this->msgLevel(MSG::DEBUG) )
    00546   { this->debug() << "Booked 1D Histogram : ID='" << ID
    00547                   << "' Path=" << histoPath()
    00548                   << " Title='"
    00549                   << Gaudi::Utils::Histos::htitle ( hist )
    00550                   << "'" << endreq; }
    00551   return hist ;
    00552 }
    00553 // ============================================================================
    00554 // fill the 1D histogram with the value and weight
    00555 // ============================================================================
    00556 template <class PBASE>
    00557 AIDA::IHistogram1D* GaudiHistos<PBASE>::fill
    00558 ( AIDA::IHistogram1D*  histo  ,
    00559   const double         value  ,
    00560   const double         weight ,
    00561   const std::string&   title  ) const
    00562 {
    00563   if ( 0 != histo && produceHistos() )
    00564   {
    00565     if ( !checkForNaN() )
    00566     { Gaudi::Utils::Histos::fill ( histo , value , weight ) ; }
    00567     else if  ( lfin ( value ) && lfin ( weight ) )
    00568     { Gaudi::Utils::Histos::fill ( histo , value , weight ) ; }
    00569     else if  ( lnan ( value ) || lnan ( weight ) )
    00570     {
    00571       this -> Warning
    00572         ("fill():: 'NaN'      value is skipped from the histogram '"
    00573          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    00574     }
    00575     else
    00576     {
    00577       this -> Warning
    00578         ("fill():: 'Infinite' value is skipped from the histogram '"
    00579          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    00580     }
    00581   }
    00582   // return
    00583   return histo ;
    00584 }
    00585 // ============================================================================
    00586 // ==================================== 2D ====================================
    00587 // ============================================================================
    00588 // book the 2D histogram (book on demand)
    00589 // ============================================================================
    00590 template <class PBASE>
    00591 AIDA::IHistogram2D*  GaudiHistos<PBASE>::book2D
    00592 ( const std::string&  title   ,
    00593   const double        lowX    ,
    00594   const double        highX   ,
    00595   const unsigned long binsX   ,
    00596   const double        lowY    ,
    00597   const double        highY   ,
    00598   const unsigned long binsY   ) const
    00599 {
    00600   // exist?
    00601   AIDA::IHistogram2D* hist = histo2D ( title ) ;
    00602   // histogram is already booked
    00603   if( 0 != hist      )                                { return hist ; } // RETURN !!
    00604
    00605   // propose the histogram ID
    00606   HistoID ID;
    00607   newHistoID( title, ID );
    00608
    00609   // Create a new histogram and return
    00610   return this -> book2D ( ID, title, lowX, highX, binsX, lowY, highY, binsY );
    00611 }
    00612 // ============================================================================
    00613 // book the 2D histogram with forced ID (book on demand)
    00614 // ============================================================================
    00615 template <class PBASE>
    00616 AIDA::IHistogram2D*  GaudiHistos<PBASE>::book2D
    00617 ( const HistoID&      ID           ,
    00618   const std::string&  title   ,
    00619   const double        lowX    ,
    00620   const double        highX   ,
    00621   const unsigned long binsX   ,
    00622   const double        lowY    ,
    00623   const double        highY   ,
    00624   const unsigned long binsY   ) const
    00625 {
    00626   // Check ID
    00627   if (ID.undefined())
    00628   {
    00629     this->Error("Undefined Histogram ID : Title='"+title+"'");
    00630     return NULL;
    00631   }
    00632
    00633   // exist?
    00634   AIDA::IHistogram2D* hist = histo2D( ID ) ;
    00635   // histogram is already booked
    00636   if( 0 != hist       )                         { return hist ; } // RETURN !!
    00637
    00638   // Histogram title
    00639   const std::string & htitle =
    00640     ( title.empty() ? "Unnamed 2D Histogram ID="+ID.idAsString() : title ) ;
    00641
    00642   // book the histogram
    00643   if ( ID.numeric() )
    00644   {
    00645     hist = this->histoSvc() -> book ( histoPath()  ,
    00646                                       ID.numericID() ,
    00647                                       htitle       ,
    00648                                       binsX        ,
    00649                                       lowX         ,
    00650                                       highX        ,
    00651                                       binsY        ,
    00652                                       lowY         ,
    00653                                       highY        ) ;
    00654   }
    00655   else if ( ID.literal() )
    00656   {
    00657     hist = this->histoSvc() -> book ( histoPath()+"/"+
    00658                                       ID.literalID() ,
    00659                                       htitle       ,
    00660                                       binsX        ,
    00661                                       lowX         ,
    00662                                       highX        ,
    00663                                       binsY        ,
    00664                                       lowY         ,
    00665                                       highY        ) ;
    00666   }
    00667
    00668   // Check OK
    00669   if( 0 == hist )
    00670   { this->Error( "IHistogram2D* points to NULL! ID='" + ID.idAsString() +
    00671                  "' title='"+htitle+"'" ) ; return 0; } // RETURN !!
    00672
    00673   // add histogram into histogram storages
    00674   if      ( ID.numeric() )
    00675   { m_histo2DMapNumID [ ID.numericID() ] = hist ; }
    00676   else if ( ID.literal() )
    00677   { m_histo2DMapLitID [ ID.literalID() ] = hist ; }
    00678   m_histo2DMapTitle [ title ] = hist ;
    00679
    00680   // Declare to monitoring service
    00681   monitorHisto( Gaudi::Utils::Histos::toBase ( hist) , ID );
    00682
    00683   // Printout and return
    00684   if ( this->msgLevel(MSG::DEBUG) )
    00685   { this->debug() << "Booked 2D Histogram : ID='"
    00686                   << ID << "' Path=" << histoPath()
    00687                   << " Title='"
    00688                   << Gaudi::Utils::Histos::htitle ( hist )
    00689                   << "'" << endreq; }
    00690   // return
    00691   return hist ;
    00692 }
    00693 // ============================================================================
    00694 // fill the 2D histogram with the values and weight
    00695 // ============================================================================
    00696 template <class PBASE>
    00697 AIDA::IHistogram2D* GaudiHistos<PBASE>::fill
    00698 ( AIDA::IHistogram2D* histo  ,
    00699   const double        valueX ,
    00700   const double        valueY ,
    00701   const double        weight ,
    00702   const std::string&  title  ) const
    00703 {
    00704   if ( 0 != histo && produceHistos() )
    00705   {
    00706     if ( !checkForNaN() )
    00707     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , weight ) ; }
    00708     else if  ( lfin ( valueX ) && lfin ( valueY ) && lfin ( weight ) )
    00709     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , weight ) ; }
    00710     else if  ( lnan ( valueX ) || lnan ( valueY ) || lnan ( weight ) )
    00711     {
    00712       this -> Warning
    00713         ("fill():: 'NaN'      value is skipped from the histogram '"
    00714          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    00715     }
    00716     else
    00717     {
    00718       this -> Warning
    00719         ("fill():: 'Infinite' value is skipped from the histogram '"
    00720          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    00721     }
    00722   }
    00723   // return
    00724   return histo ;
    00725 }
    00726 // ============================================================================
    00727 // ==================================== 3D ====================================
    00728 // ============================================================================
    00729 // book the 3D histogram (book on demand)
    00730 // ============================================================================
    00731 template <class PBASE>
    00732 AIDA::IHistogram3D*  GaudiHistos<PBASE>::book3D
    00733 ( const std::string&  title   ,
    00734   const double        lowX    ,
    00735   const double        highX   ,
    00736   const unsigned long binsX   ,
    00737   const double        lowY    ,
    00738   const double        highY   ,
    00739   const unsigned long binsY   ,
    00740   const double        lowZ    ,
    00741   const double        highZ   ,
    00742   const unsigned long binsZ   ) const
    00743 {
    00744   // exist?
    00745   AIDA::IHistogram3D* hist = histo3D ( title ) ;
    00746   // histogram is already booked
    00747   if( 0 != hist      )                           { return hist ; } // RETURN !!
    00748
    00749   // propose the histogram ID
    00750   HistoID ID;
    00751   newHistoID( title, ID );
    00752
    00753   // Create a new histogram and return
    00754   return this -> book3D ( ID, title,
    00755                           lowX, highX, binsX,
    00756                           lowY, highY, binsY,
    00757                           lowZ, highZ, binsZ );
    00758 }
    00759 // ============================================================================
    00760 // book the 3D histogram with forced ID (book on demand)
    00761 // ============================================================================
    00762 template <class PBASE>
    00763 AIDA::IHistogram3D*  GaudiHistos<PBASE>::book3D
    00764 ( const HistoID&      ID           ,
    00765   const std::string&  title   ,
    00766   const double        lowX    ,
    00767   const double        highX   ,
    00768   const unsigned long binsX   ,
    00769   const double        lowY    ,
    00770   const double        highY   ,
    00771   const unsigned long binsY   ,
    00772   const double        lowZ    ,
    00773   const double        highZ   ,
    00774   const unsigned long binsZ   ) const
    00775 {
    00776   // Check ID
    00777   if (ID.undefined())
    00778   {
    00779     this->Error("Undefined Histogram ID : Title='"+title+"'");
    00780     return NULL;
    00781   }
    00782
    00783   // exist?
    00784   AIDA::IHistogram3D* hist = histo3D( ID ) ;
    00785   // histogram is already booked
    00786   if( 0 != hist       )                        { return hist ; } // RETURN !!
    00787
    00788   // Histogram title
    00789   const std::string & htitle =
    00790     ( title.empty() ? "Unnamed 3D Histogram ID="+ID.idAsString() : title ) ;
    00791
    00792   // book the histogram
    00793   if ( ID.numeric() )
    00794   {
    00795     hist = this->histoSvc() -> book ( histoPath()  ,
    00796                                       ID.numericID() ,
    00797                                       htitle       ,
    00798                                       binsX        ,
    00799                                       lowX         ,
    00800                                       highX        ,
    00801                                       binsY        ,
    00802                                       lowY         ,
    00803                                       highY        ,
    00804                                       binsZ        ,
    00805                                       lowZ         ,
    00806                                       highZ        ) ;
    00807   }
    00808   else if ( ID.literal() )
    00809   {
    00810     hist = this->histoSvc() -> book ( histoPath()+"/"+
    00811                                       ID.literalID() ,
    00812                                       htitle       ,
    00813                                       binsX        ,
    00814                                       lowX         ,
    00815                                       highX        ,
    00816                                       binsY        ,
    00817                                       lowY         ,
    00818                                       highY        ,
    00819                                       binsZ        ,
    00820                                       lowZ         ,
    00821                                       highZ        ) ;
    00822   }
    00823
    00824   // Check OK
    00825   if( 0 == hist )
    00826   { this->Error( "IHistogram3D* points to NULL! ID='" + ID.idAsString() +
    00827                  "' title='"+htitle+"'" ) ; return 0; } // RETURN !!
    00828
    00829   // add histogram into histogram storages
    00830   if      ( ID.numeric() )
    00831   { m_histo3DMapNumID [ ID.numericID() ] = hist ; }
    00832   else if ( ID.literal() )
    00833   { m_histo3DMapLitID [ ID.literalID() ] = hist ; }
    00834   m_histo3DMapTitle [ title ] = hist ;
    00835
    00836   // Declare to monitoring service
    00837   monitorHisto( Gaudi::Utils::Histos::toBase ( hist ) , ID );
    00838
    00839   // Printout and return
    00840   if ( this->msgLevel(MSG::DEBUG) )
    00841   { this->debug() << "Booked 3D Histogram : ID='"
    00842                   << ID << "' Path=" << histoPath()
    00843                   << " Title='"
    00844                   << Gaudi::Utils::Histos::htitle ( hist )
    00845                   << "'" << endreq; }
    00846   return hist ;
    00847 }
    00848 // ============================================================================
    00849 // fill the 3D histogram with the values and weight
    00850 // ============================================================================
    00851 template <class PBASE>
    00852 AIDA::IHistogram3D* GaudiHistos<PBASE>::fill
    00853 ( AIDA::IHistogram3D* histo  ,
    00854   const double        valueX ,
    00855   const double        valueY ,
    00856   const double        valueZ ,
    00857   const double        weight ,
    00858   const std::string&  title  ) const
    00859 {
    00860   if ( 0 != histo && produceHistos() )
    00861   {
    00862     if ( !checkForNaN() )
    00863     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , valueZ , weight ) ; }
    00864     else if  ( lfin ( valueX ) && lfin ( valueY ) &&
    00865                lfin ( valueZ ) && lfin ( weight ) )
    00866     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , valueZ , weight ) ; }
    00867     else if  ( lnan ( valueX ) || lnan ( valueY ) ||
    00868                lnan ( valueZ ) || lnan ( weight ) )
    00869     {
    00870       this -> Warning
    00871         ("fill():: 'NaN'      value is skipped from the histogram '"
    00872          + Gaudi::Utils::Histos::htitle ( histo , title  ) + "'" ) ;
    00873     }
    00874     else
    00875     {
    00876       this -> Warning
    00877         ("fill():: 'Infinite' value is skipped from the histogram '"
    00878          + Gaudi::Utils::Histos::htitle ( histo , title  ) + "'" ) ;
    00879     }
    00880   }
    00881   // return
    00882   return histo ;
    00883 }
    00884 // ============================================================================
    00885 // =========================== Profile Histograms =============================
    00886 // ============================================================================
    00887 // book the 1D profile histogram (book on demand)
    00888 // ============================================================================
    00889 template <class PBASE>
    00890 AIDA::IProfile1D*  GaudiHistos<PBASE>::bookProfile1D
    00891 ( const std::string&  title        ,
    00892   const double        low          ,
    00893   const double        high         ,
    00894   const unsigned long bins         ,
    00895   const std::string&  opt          ,
    00896   const double        lowY         ,
    00897   const double        highY        ) const
    00898 {
    00899   // exist?
    00900   AIDA::IProfile1D* hist = profile1D ( title ) ;
    00901   // histogram is already booked
    00902   if( 0 != hist      )                              { return hist ; } // RETURN !!
    00903
    00904   // propose the histogram ID
    00905   HistoID ID;
    00906   newHistoID( title, ID );
    00907
    00908   // Book the histo and return
    00909   return this -> bookProfile1D ( ID, title, low, high, bins , opt , lowY , highY );
    00910 }
    00911 // ============================================================================
    00912 // book the 1D profile histogram with forced ID (book on demand)
    00913 // ============================================================================
    00914 template <class PBASE>
    00915 AIDA::IProfile1D*  GaudiHistos<PBASE>::bookProfile1D
    00916 ( const HistoID&      ID           ,
    00917   const std::string&  title        ,
    00918   const double        low          ,
    00919   const double        high         ,
    00920   const unsigned long bins         ,
    00921   const std::string&  opt          ,
    00922   const double        lowY         ,
    00923   const double        highY        ) const
    00924 {
    00925   // Check ID
    00926   if (ID.undefined())
    00927   {
    00928     this->Error("Undefined Histogram ID : Title='"+title+"'");
    00929     return NULL;
    00930   }
    00931
    00932   // exist?
    00933   AIDA::IProfile1D* hist = profile1D ( ID ) ;
    00934   // histogram is already booked
    00935   if( 0 != hist       )                         { return hist ; } // RETURN !!
    00936
    00937   // Histogram title
    00938   const std::string & htitle =
    00939     ( title.empty() ?
    00940       "Unnamed 1D Profile Histogram ID="+ID.idAsString() : title ) ;
    00941
    00942   // book the histogram
    00943   if ( ID.numeric() )
    00944   {
    00945     hist = this->histoSvc() -> bookProf ( histoPath()  ,
    00946                                           ID.numericID() ,
    00947                                           htitle       ,
    00948                                           bins         ,
    00949                                           low          ,
    00950                                           high         ,
    00951                                           lowY         ,
    00952                                           highY        ,
    00953                                           opt          ) ;
    00954   }
    00955   else if ( ID.literal() )
    00956   {
    00957     hist = this->histoSvc() -> bookProf ( histoPath()+"/"+
    00958                                           ID.literalID() ,
    00959                                           htitle       ,
    00960                                           bins         ,
    00961                                           low          ,
    00962                                           high         ,
    00963                                           lowY         ,
    00964                                           highY        ,
    00965                                           opt          ) ;
    00966   }
    00967
    00968   // test ok
    00969   if( 0 == hist )
    00970   { this->Error( "IProfile1D* points to NULL! ID='" + ID.idAsString() +
    00971                  "' title='"+htitle+"'" ) ; return 0; } // RETURN !!
    00972
    00973   // add histogram into histogram storages
    00974   if      ( ID.numeric() )
    00975   { m_profile1DMapNumID [ ID.numericID() ] = hist ; }
    00976   else if ( ID.literal() )
    00977   { m_profile1DMapLitID [ ID.literalID() ] = hist ; }
    00978   m_profile1DMapTitle [ title ] = hist ;
    00979
    00980   // Declare to monitoring service
    00981   monitorHisto( Gaudi::Utils::Histos::toBase ( hist ) , ID );
    00982
    00983   // printout and return
    00984   if ( this->msgLevel(MSG::DEBUG) )
    00985   { this->debug() << "Booked 1D Profile Histogram : ID='"
    00986                   << ID << "' Path=" << histoPath()
    00987                   << " Title='"
    00988                   << Gaudi::Utils::Histos::htitle ( hist )
    00989                   << "'" << endreq; }
    00990   return hist ;
    00991 }
    00992 // ============================================================================
    00993 // fill the 1D profile histogram with the value and weight
    00994 // ============================================================================
    00995 template <class PBASE>
    00996 AIDA::IProfile1D* GaudiHistos<PBASE>::fill
    00997 ( AIDA::IProfile1D*    histo  ,
    00998   const double         valueX ,
    00999   const double         valueY ,
    01000   const double         weight ,
    01001   const std::string&   title  ) const
    01002 {
    01003   if ( 0 != histo && produceHistos() )
    01004   {
    01005     if ( !checkForNaN() )
    01006     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , weight ); }
    01007     else if  ( lfin ( valueX ) && lfin ( valueY ) && lfin ( weight ) )
    01008     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , weight ); }
    01009     else if  ( lnan ( valueX ) || lnan ( valueY ) || lnan ( weight ) )
    01010     {
    01011       this -> Warning
    01012         ("fill():: 'NaN'      value is skipped from the histogram '"
    01013          + Gaudi::Utils::Histos::htitle ( histo , title  ) + "'" ) ;
    01014     }
    01015     else
    01016     {
    01017       this -> Warning
    01018         ("fill():: 'Infinite' value is skipped from the histogram '"
    01019          + Gaudi::Utils::Histos::htitle ( histo , title  ) + "'" ) ;
    01020     }
    01021   }
    01022   // return
    01023   return histo ;
    01024 }
    01025 // ============================================================================
    01026 // book the 2D profile histogram (book on demand)
    01027 // ============================================================================
    01028 template <class PBASE>
    01029 AIDA::IProfile2D*  GaudiHistos<PBASE>::bookProfile2D
    01030 ( const std::string&  title        ,
    01031   const double        lowX         ,
    01032   const double        highX        ,
    01033   const unsigned long binsX        ,
    01034   const double        lowY         ,
    01035   const double        highY        ,
    01036   const unsigned long binsY         ) const
    01037 {
    01038   // exist?
    01039   AIDA::IProfile2D* hist = profile2D ( title ) ;
    01040   // histogram is already booked
    01041   if( 0 != hist      )                          { return hist ; } // RETURN !!
    01042
    01043   // propose the histogram ID
    01044   HistoID ID;
    01045   newHistoID( title, ID );
    01046
    01047   // book histogram and return
    01048   return this -> bookProfile2D ( ID, title, lowX, highX, binsX, lowY, highY, binsY );
    01049 }
    01050 // ============================================================================
    01051 // book the 2D profile histogram with forced ID (book on demand)
    01052 // ============================================================================
    01053 template <class PBASE>
    01054 AIDA::IProfile2D*  GaudiHistos<PBASE>::bookProfile2D
    01055 ( const HistoID&      ID           ,
    01056   const std::string&  title        ,
    01057   const double        lowX         ,
    01058   const double        highX        ,
    01059   const unsigned long binsX        ,
    01060   const double        lowY         ,
    01061   const double        highY        ,
    01062   const unsigned long binsY         ) const
    01063 {
    01064   // Check ID
    01065   if (ID.undefined())
    01066   {
    01067     this->Error("Undefined Histogram ID : Title='"+title+"'");
    01068     return NULL;
    01069   }
    01070
    01071   // exist?
    01072   AIDA::IProfile2D* hist = profile2D ( ID ) ;
    01073   // histogram is already booked
    01074   if( 0 != hist )                               { return hist ; } // RETURN !!
    01075
    01076   // Histogram title
    01077   const std::string & htitle =
    01078     ( title.empty() ?
    01079       "Unnamed 2D Profile Histogram ID="+ID.idAsString() : title ) ;
    01080
    01081   // book the histogram
    01082   if ( ID.numeric() )
    01083   {
    01084     hist = this->histoSvc() -> bookProf ( histoPath() ,
    01085                                           ID.numericID() ,
    01086                                           htitle      ,
    01087                                           binsX       ,
    01088                                           lowX        ,
    01089                                           highX       ,
    01090                                           binsY       ,
    01091                                           lowY        ,
    01092                                           highY        ) ;
    01093   }
    01094   else if ( ID.literal() )
    01095   {
    01096     hist = this->histoSvc() -> bookProf ( histoPath()+"/"+
    01097                                           ID.literalID() ,
    01098                                           htitle      ,
    01099                                           binsX       ,
    01100                                           lowX        ,
    01101                                           highX       ,
    01102                                           binsY       ,
    01103                                           lowY        ,
    01104                                           highY        ) ;
    01105   }
    01106
    01107   // test OK
    01108   if( 0 == hist )
    01109   { this->Error( "IProfile2D* points to NULL! ID='" + ID.idAsString() +
    01110                  "' title='"+htitle+"'" ) ; return 0; } // RETURN !!
    01111
    01112   // add histogram into histogram storages
    01113   if      ( ID.numeric() )
    01114   { m_profile2DMapNumID [ ID.numericID() ] = hist ; }
    01115   else if ( ID.literal() )
    01116   { m_profile2DMapLitID [ ID.literalID() ] = hist ; }
    01117   m_profile2DMapTitle [ title ] = hist ;
    01118
    01119   // Declare to monitoring service
    01120   monitorHisto( Gaudi::Utils::Histos::toBase ( hist ) , ID );
    01121
    01122   // printout and return
    01123   if ( this->msgLevel(MSG::DEBUG) )
    01124   {  this->debug() << "Booked 2D Profile Histogram : ID='" << ID
    01125                    << "' Path=" << histoPath()
    01126                    << " Title='"
    01127                    << Gaudi::Utils::Histos::htitle ( hist )
    01128                    << "'" << endreq; }
    01129   return hist ;
    01130 }
    01131 // ============================================================================
    01132 // fill the 2D profile histogram with the value and weight
    01133 // ============================================================================
    01134 template <class PBASE>
    01135 AIDA::IProfile2D* GaudiHistos<PBASE>::fill
    01136 ( AIDA::IProfile2D*    histo  ,
    01137   const double         valueX ,
    01138   const double         valueY ,
    01139   const double         valueZ ,
    01140   const double         weight ,
    01141   const std::string&   title  ) const
    01142 {
    01143   if ( 0 != histo && produceHistos() )
    01144   {
    01145     if ( !checkForNaN() )
    01146     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , valueZ , weight ); }
    01147     else if  ( lfin ( valueX ) && lfin ( valueY ) &&
    01148                lfin ( valueZ ) && lfin ( weight ) )
    01149     { Gaudi::Utils::Histos::fill ( histo , valueX , valueY , valueZ , weight ); }
    01150     else if  ( lnan ( valueX ) || lnan ( valueY ) ||
    01151                lnan ( valueZ ) || lnan ( weight ) )
    01152     {
    01153       this -> Warning
    01154         ("fill():: 'NaN'      value is skipped from the histogram '"
    01155          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    01156     }
    01157     else
    01158     {
    01159       this -> Warning
    01160         ("fill():: 'Infinite' value is skipped from the histogram '"
    01161          + Gaudi::Utils::Histos::htitle ( histo , title ) + "'" ) ;
    01162     }
    01163   }
    01164   // return
    01165   return histo ;
    01166 }
    01167 // ============================================================================
    01168 // fill the 1D histogram (book on demand)
    01169 // ============================================================================
    01170 template <class PBASE>
    01171 AIDA::IHistogram1D*
    01172 GaudiHistos<PBASE>::plot1D
    01173 ( const double        value  ,
    01174   const std::string&  title  ,
    01175   const double        low    ,
    01176   const double        high   ,
    01177   const unsigned long bins   ,
    01178   const double        weight ) const
    01179 {
    01180   AIDA::IHistogram1D * h(0);
    01181   if ( produceHistos() )
    01182   {
    01183     // retrieve or book the histogram
    01184     h = histo1D ( title ) ;
    01185     if ( 0 == h )     { h = book1D  ( title , low , high , bins ) ; }
    01186     // fill the histogram
    01187     h = fill ( h , value , weight , title );
    01188   }
    01189   return h;
    01190 }
    01191 // ============================================================================
    01192 // fill the 1D histogram with forced ID assignment (book on demand)
    01193 // ============================================================================
    01194 template <class PBASE>
    01195 AIDA::IHistogram1D*
    01196 GaudiHistos<PBASE>::plot1D
    01197 ( const double        value  ,
    01198   const HistoID&      ID     ,
    01199   const std::string&  title  ,
    01200   const double        low    ,
    01201   const double        high   ,
    01202   const unsigned long bins   ,
    01203   const double        weight ) const
    01204 {
    01205   AIDA::IHistogram1D* h(0);
    01206   if ( produceHistos() )
    01207   {
    01208     // retrieve or book the histogram
    01209     h = histo1D ( ID ) ;
    01210     if ( 0 == h ) {  h = book1D ( ID , title , low , high , bins ) ; }
    01211     // fill
    01212     h = fill ( h , value , weight , title ) ;
    01213   }
    01214   return h;
    01215 }
    01216 // ============================================================================
    01217 // fill the 2D histogram (book on demand)
    01218 // ============================================================================
    01219 template <class PBASE>
    01220 AIDA::IHistogram2D* GaudiHistos<PBASE>::plot2D
    01221 ( const double        valueX       ,
    01222   const double        valueY       ,
    01223   const std::string&  title        ,
    01224   const double        lowX         ,
    01225   const double        highX        ,
    01226   const double        lowY         ,
    01227   const double        highY        ,
    01228   const unsigned long binsX        ,
    01229   const unsigned long binsY        ,
    01230   const double        weight       ) const
    01231 {
    01232   AIDA::IHistogram2D * h(0);
    01233   if ( produceHistos() )
    01234   {
    01235     // retrieve or book the histogram
    01236     h = histo2D ( title ) ;
    01237     if ( 0 == h )
    01238     { h = book2D ( title , lowX , highX , binsX , lowY , highY , binsY ) ; }
    01239     // fill the histogram
    01240     h = fill ( h , valueX , valueY , weight , title ) ;
    01241   }
    01242   return h;
    01243 }
    01244 // ============================================================================
    01245 // fill the 2D histogram with forced ID assignment (book on demand)
    01246 // ============================================================================
    01247 template <class PBASE>
    01248 AIDA::IHistogram2D*  GaudiHistos<PBASE>::plot2D
    01249 ( const double        valueX       ,
    01250   const double        valueY       ,
    01251   const HistoID&      ID           ,
    01252   const std::string&  title        ,
    01253   const double        lowX         ,
    01254   const double        highX        ,
    01255   const double        lowY         ,
    01256   const double        highY        ,
    01257   const unsigned long binsX        ,
    01258   const unsigned long binsY        ,
    01259   const double        weight       ) const
    01260 {
    01261   AIDA::IHistogram2D * h(0);
    01262   // produce histograms ?
    01263   if ( produceHistos() )
    01264   {
    01265     // retrieve or book the histogram
    01266     h = histo2D ( ID ) ;
    01267     if ( 0 == h ) { h = book2D ( ID   , title ,
    01268                                  lowX , highX , binsX ,
    01269                                  lowY , highY , binsY ) ; }
    01270     // fill the histogram
    01271     h = fill ( h , valueX , valueY , weight , title ) ;
    01272   }
    01273   return h;
    01274 }
    01275 // ============================================================================
    01276 // fill the 3D histogram (book on demand)
    01277 // ============================================================================
    01278 template <class PBASE>
    01279 AIDA::IHistogram3D*  GaudiHistos<PBASE>::plot3D
    01280 ( const double        valueX       ,
    01281   const double        valueY       ,
    01282   const double        valueZ       ,
    01283   const std::string&  title        ,
    01284   const double        lowX         ,
    01285   const double        highX        ,
    01286   const double        lowY         ,
    01287   const double        highY        ,
    01288   const double        lowZ         ,
    01289   const double        highZ        ,
    01290   const unsigned long binsX        ,
    01291   const unsigned long binsY        ,
    01292   const unsigned long binsZ        ,
    01293   const double        weight       ) const
    01294 {
    01295   AIDA::IHistogram3D * h(0);
    01296   if ( produceHistos() )
    01297   {
    01298     // retrieve or book the histogram
    01299     h = histo3D ( title ) ;
    01300     if ( 0 == h ) { h = book3D ( title ,
    01301                                  lowX , highX , binsX ,
    01302                                  lowY , highY , binsY ,
    01303                                  lowZ , highZ , binsZ ) ; }
    01304     // fill the histogram
    01305     h = fill ( h , valueX , valueY , valueZ , weight , title ) ;
    01306   }
    01307   return h;
    01308 }
    01309 // ============================================================================
    01310 // fill the 3D histogram with forced ID assignment (book on demand)
    01311 // ============================================================================
    01312 template <class PBASE>
    01313 AIDA::IHistogram3D* GaudiHistos<PBASE>::plot3D
    01314 ( const double        valueX       ,
    01315   const double        valueY       ,
    01316   const double        valueZ       ,
    01317   const HistoID&      ID           ,
    01318   const std::string&  title        ,
    01319   const double        lowX         ,
    01320   const double        highX        ,
    01321   const double        lowY         ,
    01322   const double        highY        ,
    01323   const double        lowZ         ,
    01324   const double        highZ        ,
    01325   const unsigned long binsX        ,
    01326   const unsigned long binsY        ,
    01327   const unsigned long binsZ        ,
    01328   const double        weight       ) const
    01329 {
    01330   AIDA::IHistogram3D * h(0);
    01331   if ( produceHistos() )
    01332   {
    01333     // retrieve or book the histogram
    01334     h = histo3D ( ID ) ;
    01335     if ( 0 == h ) { h = book3D ( ID , title ,
    01336                                  lowX , highX , binsX ,
    01337                                  lowY , highY , binsY ,
    01338                                  lowZ , highZ , binsZ ) ; }
    01339     // fill the histogram
    01340     h = fill ( h , valueX , valueY , valueZ , weight , title ) ;
    01341   }
    01342   return h;
    01343 }
    01344 // ============================================================================
    01345 // fill the 1D profile histogram (book on demand)
    01346 // ============================================================================
    01347 template <class PBASE>
    01348 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D
    01349 ( const double        valueX       ,
    01350   const double        valueY       ,
    01351   const std::string&  title        ,
    01352   const double        lowX         ,
    01353   const double        highX        ,
    01354   const unsigned long binsX        ,
    01355   const std::string&  opt          ,
    01356   const double        lowY         ,
    01357   const double        highY        ,
    01358   const double        weight       ) const
    01359 {
    01360   AIDA::IProfile1D * h(0);
    01361   if ( produceHistos() )
    01362   {
    01363     // retrieve or book the histogram
    01364     h = profile1D ( title ) ;
    01365     if ( 0 == h )
    01366     { h = bookProfile1D ( title , lowX , highX , binsX , opt , lowY , highY ) ; }
    01367     // fill the histogram
    01368     h = fill ( h , valueX , valueY , weight , title ) ;
    01369   }
    01370   return h;
    01371 }
    01372 // ============================================================================
    01373 // fill the 1D profile histogram with forced ID assignment (book on demand)
    01374 // ============================================================================
    01375 template <class PBASE>
    01376 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D
    01377 ( const double        valueX       ,
    01378   const double        valueY       ,
    01379   const HistoID&      ID           ,
    01380   const std::string&  title        ,
    01381   const double        lowX         ,
    01382   const double        highX        ,
    01383   const unsigned long binsX        ,
    01384   const std::string&  opt          ,
    01385   const double        lowY         ,
    01386   const double        highY        ,
    01387   const double        weight       ) const
    01388 {
    01389   AIDA::IProfile1D * h(0);
    01390   if ( produceHistos() )
    01391   {
    01392     // retrieve or book the histogram
    01393     h = profile1D ( ID ) ;
    01394     if ( 0 == h )
    01395     { h = bookProfile1D ( ID , title , lowX , highX , binsX , opt , lowY , highY ) ; }
    01396     // fill the histogram
    01397     h = fill ( h , valueX , valueY , weight , title ) ;
    01398   }
    01399   return h;
    01400 }
    01401 // ============================================================================
    01402 // fill the 2D profile histogram (book on demand)
    01403 // ============================================================================
    01404 template <class PBASE>
    01405 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D
    01406 ( const double        valueX       ,
    01407   const double        valueY       ,
    01408   const double        valueZ       ,
    01409   const std::string&  title        ,
    01410   const double        lowX         ,
    01411   const double        highX        ,
    01412   const double        lowY         ,
    01413   const double        highY        ,
    01414   const unsigned long binsX        ,
    01415   const unsigned long binsY        ,
    01416   const double        weight       ) const
    01417 {
    01418   AIDA::IProfile2D * h(0);
    01419   if ( produceHistos() )
    01420   {
    01421     // retrieve or book the histogram
    01422     h = profile2D ( title ) ;
    01423     if ( 0 == h ) { h = bookProfile2D ( title ,
    01424                                         lowX , highX , binsX ,
    01425                                         lowY , highY , binsY ) ; }
    01426     // fill the histogram
    01427     h = fill ( h , valueX , valueY , valueZ , weight , title ) ;
    01428   }
    01429   return h;
    01430 }
    01431 // ============================================================================
    01432 // fill the 2D profile histogram with forced ID assignment (book on demand)
    01433 // ============================================================================
    01434 template <class PBASE>
    01435 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D
    01436 ( const double        valueX       ,
    01437   const double        valueY       ,
    01438   const double        valueZ       ,
    01439   const HistoID&      ID           ,
    01440   const std::string&  title        ,
    01441   const double        lowX         ,
    01442   const double        highX        ,
    01443   const double        lowY         ,
    01444   const double        highY        ,
    01445   const unsigned long binsX        ,
    01446   const unsigned long binsY        ,
    01447   const double        weight       ) const
    01448 {
    01449   AIDA::IProfile2D * h(0);
    01450   if ( produceHistos() )
    01451   {
    01452     // retrieve or book the histogram
    01453     h = profile2D ( ID ) ;
    01454     if ( 0 == h ) { h = bookProfile2D ( ID , title ,
    01455                                         lowX , highX , binsX ,
    01456                                         lowY , highY , binsY ) ; }
    01457     // fill the histogram
    01458     h = fill ( h , valueX , valueY , valueZ , weight , title ) ;
    01459   }
    01460   return h;
    01461 }
    01462 // ============================================================================
    01463 // book the 1D histogram
    01464 // ============================================================================
    01465 template <class PBASE>
    01466 AIDA::IHistogram1D*
    01467 GaudiHistos<PBASE>::book
    01468 ( const Gaudi::Histo1DDef& hdef ) const
    01469 {
    01470   return book1D ( hdef.title    () ,
    01471                   hdef.lowEdge  () ,
    01472                   hdef.highEdge () ,
    01473                   hdef.bins     () ) ;
    01474 }
    01475 // ============================================================================
    01476 // book the 1D histogram with forced ID
    01477 // ============================================================================
    01478 template <class PBASE>
    01479 AIDA::IHistogram1D*
    01480 GaudiHistos<PBASE>::book
    01481 ( const HistoID&           ID   ,
    01482   const Gaudi::Histo1DDef& hdef ) const
    01483 {
    01484   return book1D ( ID               ,
    01485                   hdef.title    () ,
    01486                   hdef.lowEdge  () ,
    01487                   hdef.highEdge () ,
    01488                   hdef.bins     () ) ;
    01489 }
    01490 // ============================================================================
    01491 // fill the 1D histogram (book on demand)
    01492 // ============================================================================
    01493 template <class PBASE>
    01494 AIDA::IHistogram1D*
    01495 GaudiHistos<PBASE>::plot
    01496 ( const double             value  ,
    01497   const Gaudi::Histo1DDef& hdef   ,
    01498   const double             weight ) const
    01499 {
    01500   return plot1D
    01501     ( value  ,
    01502       hdef.title() , hdef.lowEdge() , hdef.highEdge() , hdef.bins() ,
    01503       weight ) ;
    01504 }
    01505 // ============================================================================
    01506 // fill the 1D histogram with forced ID assignment (book on demand)
    01507 // ============================================================================
    01508 template <class PBASE>
    01509 AIDA::IHistogram1D*
    01510 GaudiHistos<PBASE>::plot
    01511 ( const double             value  ,
    01512   const HistoID&           ID     ,
    01513   const Gaudi::Histo1DDef& hdef   ,
    01514   const double             weight ) const
    01515 {
    01516   return plot1D
    01517     ( value  , ID ,
    01518       hdef.title() , hdef.lowEdge() , hdef.highEdge() , hdef.bins() ,
    01519       weight ) ;
    01520 }
    01521 // ============================================================================
    01522 // access the EXISTING 1D histogram by ID
    01523 // ============================================================================
    01524 template <class PBASE>
    01525 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D ( const HistoID& ID )  const
    01526 {
    01527   AIDA::IHistogram1D * h(0);
    01528   if ( ID.numeric() )
    01529   {
    01530     Histo1DMapNumID::const_iterator found =
    01531       histo1DMapNumID().find( ID.numericID() ) ;
    01532     h = ( histo1DMapNumID().end() == found ? 0 : found->second );
    01533   }
    01534   else
    01535   {
    01536     Histo1DMapLitID::const_iterator found =
    01537       histo1DMapLitID().find( ID.literalID() ) ;
    01538     h = ( histo1DMapLitID().end() == found ? 0 : found->second );
    01539   }
    01540   return h;
    01541 }
    01542 // ============================================================================
    01543 // access the EXISTING 2D histogram by ID
    01544 // ============================================================================
    01545 template <class PBASE>
    01546 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D ( const HistoID& ID )  const
    01547 {
    01548   AIDA::IHistogram2D * h(0);
    01549   if ( ID.numeric() )
    01550   {
    01551     Histo2DMapNumID::const_iterator found =
    01552       histo2DMapNumID().find( ID.numericID() ) ;
    01553     h = ( histo2DMapNumID().end() == found ? 0 : found->second );
    01554   }
    01555   else
    01556   {
    01557     Histo2DMapLitID::const_iterator found =
    01558       histo2DMapLitID().find( ID.literalID() ) ;
    01559     h = ( histo2DMapLitID().end() == found ? 0 : found->second );
    01560   }
    01561   return h;
    01562 }
    01563 // ============================================================================
    01564 // access the EXISTING 3D histogram by ID
    01565 // ============================================================================
    01566 template <class PBASE>
    01567 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D ( const HistoID& ID )  const
    01568 {
    01569   AIDA::IHistogram3D * h(0);
    01570   if ( ID.numeric() )
    01571   {
    01572     Histo3DMapNumID::const_iterator found =
    01573       histo3DMapNumID().find( ID.numericID() ) ;
    01574     h = ( histo3DMapNumID().end() == found ? 0 : found->second );
    01575   }
    01576   else
    01577   {
    01578     Histo3DMapLitID::const_iterator found =
    01579       histo3DMapLitID().find( ID.literalID() ) ;
    01580     h = ( histo3DMapLitID().end() == found ? 0 : found->second );
    01581   }
    01582   return h;
    01583 }
    01584 // ============================================================================
    01585 // access the EXISTING 1D profile histogram by ID
    01586 // ============================================================================
    01587 template <class PBASE>
    01588 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D ( const HistoID& ID )  const
    01589 {
    01590   AIDA::IProfile1D * h(0);
    01591   if ( ID.numeric() )
    01592   {
    01593     Profile1DMapNumID::const_iterator found =
    01594       profile1DMapNumID().find( ID.numericID() ) ;
    01595     h = ( profile1DMapNumID().end() == found ? 0 : found->second );
    01596   }
    01597   else
    01598   {
    01599     Profile1DMapLitID::const_iterator found =
    01600       profile1DMapLitID().find( ID.literalID() ) ;
    01601     h = ( profile1DMapLitID().end() == found ? 0 : found->second );
    01602   }
    01603   return h;
    01604 }
    01605 // ============================================================================
    01606 // access the EXISTING 2D profile histogram by ID
    01607 // ============================================================================
    01608 template <class PBASE>
    01609 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D ( const HistoID& ID )  const
    01610 {
    01611   AIDA::IProfile2D * h(0);
    01612   if ( ID.numeric() )
    01613   {
    01614     Profile2DMapNumID::const_iterator found =
    01615       profile2DMapNumID().find( ID.numericID() ) ;
    01616     h = ( profile2DMapNumID().end() == found ? 0 : found->second );
    01617   }
    01618   else
    01619   {
    01620     Profile2DMapLitID::const_iterator found =
    01621       profile2DMapLitID().find( ID.literalID() ) ;
    01622     h = ( profile2DMapLitID().end() == found ? 0 : found->second );
    01623   }
    01624   return h;
    01625 }
    01626 // ============================================================================
    01627 // Returns the total number of histograms (of all types) currently booked
    01628 // ============================================================================
    01629 template <class PBASE>
    01630 unsigned int GaudiHistos<PBASE>::totalNumberOfHistos() const
    01631 {
    01632   const unsigned int n1D  = histo1DMapNumID().size()+histo1DMapLitID().size();
    01633   const unsigned int n2D  = histo2DMapNumID().size()+histo2DMapLitID().size();
    01634   const unsigned int n3D  = histo3DMapNumID().size()+histo3DMapLitID().size();
    01635   const unsigned int n1DP = profile1DMapNumID().size()+profile1DMapLitID().size();
    01636   const unsigned int n2DP = profile2DMapNumID().size()+profile2DMapLitID().size();
    01637   return n1D+n2D+n3D+n1DP+n2DP;
    01638 }
    01639 // ============================================================================
    01640 // Create a new histogram ID using the given title
    01641 // ============================================================================
    01642 template <class PBASE>
    01643 void GaudiHistos<PBASE>::newHistoID( const std::string & title,
    01644                                      HistoID& ID ) const
    01645 {
    01646   if ( useNumericAutoIDs() || title.empty() )
    01647   {
    01648     if ( !useNumericAutoIDs() )
    01649     {
    01650       this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
    01651                        StatusCode::SUCCESS );
    01652     }
    01653     // propose the histogram ID (always numeric)
    01654     ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
    01655     // adjust the proposed ID
    01656     while ( histoExists( ID ) ) { ++ID; }
    01657   }
    01658   else
    01659   {
    01660     // use the title to create a unique literal ID
    01661     ID = HistoID( this->convertTitleToID(title) );
    01662     // Just in case ...
    01663     while ( histoExists( ID ) ) { ID = HistoID(ID.idAsString()+"_"); }
    01664   }
    01665 }
    01666 // ============================================================================
    01667 // Create an ID string from a title string
    01668 // ============================================================================
    01669 template <class PBASE>
    01670 std::string GaudiHistos<PBASE>::convertTitleToID( const std::string & title ) const
    01671 {
    01672   // clean up the ID string for all unwanted characters
    01673   std::string tmp_id = title;
    01674   for ( std::map<std::string,std::string>::const_iterator i = m_idReplaceInfo.begin();
    01675         i != m_idReplaceInfo.end(); ++i )
    01676   {
    01677     stringSearchReplace( tmp_id, i->first, i->second );
    01678   }
    01679   return tmp_id;
    01680 }
    01681 // ============================================================================
    01682 // Searches 'title' for all instancies of 'A' and replaces them with 'B'
    01683 // ============================================================================
    01684 template <class PBASE>
    01685 void GaudiHistos<PBASE>::stringSearchReplace( std::string & title,
    01686                                               const std::string & A,
    01687                                               const std::string & B ) const
    01688 {
    01689   std::string::size_type slash = title.find_first_of ( A ) ;
    01690   while ( std::string::npos != slash )
    01691   {
    01692     title = title.substr(0,slash) + B + title.substr(slash+A.size());
    01693     slash = title.find_first_of( A );
    01694   }
    01695 }
    01696 // ============================================================================
    01697 // The END
    01698 // ============================================================================
    01699 #endif // GAUDIALG_GAUDIHISTOS_ICPP
    01700 // ============================================================================