Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/GaudiAlg/GaudiHistos.icpp is written in an unsupported language. File is not indexed.

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIALG_GAUDIHISTOS_ICPP
0012 #define GAUDIALG_GAUDIHISTOS_ICPP 1
0013 // ============================================================================
0014 /* @file
0015  *
0016  *  Implementation file for class : GaudiHistos
0017  *
0018  *  @author Chris Jones   Christopher.Rob.Jones@cern.ch
0019  *  @author Vanya BELYAEV Ivan.Belyaev@itep.ru
0020  *  @date   2005-08-08
0021  */
0022 // ============================================================================
0023 // STD & STL
0024 // ============================================================================
0025 #include <algorithm>
0026 #include <cmath>
0027 #include <set>
0028 #include <string>
0029 #include <vector>
0030 // ============================================================================
0031 // GaudiKernel
0032 // ============================================================================
0033 #include "GaudiKernel/IHistogramSvc.h"
0034 #include "GaudiKernel/MsgStream.h"
0035 // ============================================================================
0036 // GaudiAlg
0037 // ============================================================================
0038 #include "GaudiAlg/Fill.h"
0039 #include "GaudiAlg/GaudiHistos.h"
0040 #include "GaudiAlg/HbookName.h"
0041 #include "GaudiAlg/Print.h"
0042 // ============================================================================
0043 // forward declarations from AIDA
0044 // ============================================================================
0045 namespace AIDA {
0046   class IBaseHistogram;
0047   class IHistogram;
0048   class IHistogram1D;
0049   class IHistogram2D;
0050   class IHistogram3D;
0051   class IProfile;
0052   class IProfile1D;
0053   class IProfile2D;
0054 } // namespace AIDA
0055 // ============================================================================
0056 // utility to allow iteration in order
0057 // ============================================================================
0058 namespace {
0059   constexpr struct ordered_t {
0060     template <typename C>
0061     std::map<typename C::key_type, typename C::mapped_type> operator()( const C& c ) const {
0062       return { std::begin( c ), std::end( c ) };
0063     }
0064   } ordered{};
0065 
0066   template <typename Map>
0067   typename Map::mapped_type lookup_( const Map& map, const typename Map::key_type& ID ) {
0068     auto found = map.find( ID );
0069     return found != std::end( map ) ? found->second : nullptr;
0070   }
0071 
0072   // ============================================================================
0073   // Searches 'title' for all instances of 'A' and replaces them with 'B'
0074   // ============================================================================
0075   inline void stringSearchReplace( std::string& title, const std::string& A, const std::string& B ) {
0076     for ( auto slash = title.find_first_of( A ); slash != std::string::npos; slash = title.find_first_of( A ) ) {
0077       title = title.substr( 0, slash ) + B + title.substr( slash + A.size() );
0078     }
0079   }
0080 } // namespace
0081 // ============================================================================
0082 // Initialise Histogramming
0083 // ============================================================================
0084 template <class PBASE>
0085 StatusCode GaudiHistos<PBASE>::
0086 #ifdef __ICC
0087     i_ghInitialize
0088 #else
0089     initialize
0090 #endif
0091     () {
0092   // initialize base class
0093   const StatusCode sc = PBASE::initialize();
0094   if ( sc.isFailure() ) return sc;
0095 
0096   // produce histograms?
0097   if ( !produceHistos() ) {
0098     this->debug() << "Histogram production is switched OFF" << endmsg;
0099     return sc;
0100   }
0101 
0102   // check the validity of histogram service
0103   if ( !this->histoSvc() ) { return this->Error( "initialize():: IHistogramSvc* is invalid" ); }
0104 
0105   // Warn if the user has decided to use numerical automatic IDs
0106   if ( useNumericAutoIDs() ) {
0107     this->Warning(
0108             "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
0109             StatusCode::SUCCESS )
0110         .ignore();
0111   }
0112 
0113   // Finally, print the location histogram will be written to
0114   this->Print( "The histogram path is set to be '" + histoPath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
0115 
0116   return sc;
0117 }
0118 // ============================================================================
0119 // Finalise Histogramming
0120 // ============================================================================
0121 template <class PBASE>
0122 StatusCode GaudiHistos<PBASE>::
0123 #ifdef __ICC
0124     i_ghFinalize
0125 #else
0126     finalize
0127 #endif
0128     () {
0129 
0130   if ( produceHistos() ) {
0131 
0132     // Count how many histos of each type
0133     if ( ( !noHistos() ) && histoCountersPrint() ) {
0134       const unsigned int n1D   = histo1DMapID().size();
0135       const unsigned int n2D   = histo2DMapID().size();
0136       const unsigned int n3D   = histo3DMapID().size();
0137       const unsigned int n1DP  = profile1DMapID().size();
0138       const unsigned int n2DP  = profile2DMapID().size();
0139       const unsigned int total = n1D + n2D + n3D + n1DP + n2DP;
0140       if ( total > 0 ) {
0141         this->always() << "Booked " << total << " Histogram(s) : ";
0142         if ( n1D > 0 ) this->always() << "1D=" << n1D << " ";
0143         if ( n2D > 0 ) this->always() << "2D=" << n2D << " ";
0144         if ( n3D > 0 ) this->always() << "3D=" << n3D << " ";
0145         if ( n1DP > 0 ) this->always() << "1DProf=" << n1DP << " ";
0146         if ( n2DP > 0 ) this->always() << "2DProf=" << n2DP << " ";
0147         this->always() << endmsg;
0148       }
0149     }
0150 
0151     // detailed printing
0152     if ( histosPrint() ) { printHistos(); }
0153   }
0154 
0155   // clear all maps
0156   m_histo1DMapTitle.clear();
0157   m_histo2DMapTitle.clear();
0158   m_histo3DMapTitle.clear();
0159   m_histo1DMapID.clear();
0160   m_histo2DMapID.clear();
0161   m_histo3DMapID.clear();
0162   m_profile1DMapTitle.clear();
0163   m_profile2DMapTitle.clear();
0164   m_profile1DMapID.clear();
0165   m_profile2DMapID.clear();
0166 
0167   // finalize base class
0168   return PBASE::finalize();
0169 }
0170 // ============================================================================
0171 // perform the actual detailed printout of histograms
0172 // ============================================================================
0173 template <class PBASE>
0174 int GaudiHistos<PBASE>::printHistos( const MSG::Level level ) const {
0175   using namespace Gaudi::Utils::Histos;
0176 
0177   if ( noHistos() ) {
0178     if ( this->msgLevel( MSG::DEBUG ) ) { this->msgStream( level ) << "No histograms are booked" << endmsg; }
0179     return 0; // RETURN
0180   }
0181 
0182   MsgStream& msg = this->msgStream( level );
0183 
0184   // Printout all histograms
0185 
0186   if ( !histo1DMapID().empty() ) {
0187     msg << "1D histograms in directory "
0188         << "\"" << histoPath() << "\" : " << histo1DMapID().size();
0189     const Gaudi::Utils::Histos::Table table( m_histo1DTableFormat, m_histo1DTableHeader );
0190     if ( !table.header().empty() ) {
0191       msg << std::endl << Gaudi::Utils::Histos::format( "ID", table.header(), m_histo1DTableFormatShort );
0192     }
0193     for ( const auto& entry : ordered( histo1DMapID() ) ) {
0194       const auto* aida = entry.second;
0195       if ( !aida ) {
0196         this->error() << "IHistogram1D points to NULL" << endmsg;
0197         continue;
0198       }
0199       // format and print the row
0200       msg << std::endl << table.toString( aida, HistoID( entry.first ), m_histo1DTableFormatShort );
0201     }
0202     msg << endmsg;
0203   }
0204   // ==========================================================================
0205   if ( !histo2DMapID().empty() ) {
0206     msg << "2D histograms in directory "
0207         << "\"" << histoPath() << "\" : " << histo2DMapID().size();
0208 
0209     for ( const auto& entry : ordered( histo2DMapID() ) ) {
0210       const auto* aida = entry.second;
0211       if ( !aida ) {
0212         this->error() << "IHistogram2D points to NULL" << endmsg;
0213         continue;
0214       }
0215       msg << std::endl << GaudiAlg::Print2D::toString( aida, entry.first );
0216     }
0217     msg << endmsg;
0218   }
0219   // ==========================================================================
0220   if ( !histo3DMapID().empty() ) {
0221     msg << "3D histograms in directory "
0222         << "\"" << histoPath() << "\" : " << histo3DMapID().size();
0223     for ( const auto& entry : ordered( histo3DMapID() ) ) {
0224       const auto* aida = entry.second;
0225       if ( !aida ) {
0226         this->error() << "IHistogram3D points to NULL" << endmsg;
0227         continue;
0228       }
0229       msg << std::endl << GaudiAlg::Print3D::toString( aida, entry.first );
0230     }
0231     msg << endmsg;
0232   }
0233   // ==========================================================================
0234   if ( !profile1DMapID().empty() ) {
0235     msg << "1D profile histograms in directory "
0236         << "\"" << histoPath() << "\" : " << profile1DMapID().size();
0237     const Gaudi::Utils::Histos::Table table( m_histo1DTableFormat, m_histo1DTableHeader );
0238     if ( !table.header().empty() ) {
0239       msg << std::endl << Gaudi::Utils::Histos::format( "ID", table.header(), m_histo1DTableFormatShort );
0240     }
0241     for ( const auto& entry : ordered( profile1DMapID() ) ) {
0242       const auto* aida = entry.second;
0243       if ( !aida ) {
0244         this->error() << "IProfile1D points to NULL" << endmsg;
0245         continue;
0246       }
0247       msg << std::endl << table.toString( aida, HistoID( entry.first ), m_histo1DTableFormatShort );
0248     }
0249     msg << endmsg;
0250   }
0251   // ==========================================================================
0252   if ( !profile2DMapID().empty() ) {
0253     msg << "2D profile histograms in directory "
0254         << "\"" << histoPath() << "\" : " << profile2DMapID().size();
0255     for ( const auto& entry : ordered( profile2DMapID() ) ) {
0256       const auto* aida = entry.second;
0257       if ( !aida ) {
0258         this->error() << "IProfile2D points to NULL" << endmsg;
0259         continue;
0260       }
0261       msg << std::endl << GaudiAlg::Print2DProf::toString( aida, entry.first );
0262     }
0263     msg << endmsg;
0264   }
0265   //
0266   return this->totalNumberOfHistos();
0267 }
0268 // ============================================================================
0269 // Check if all histogram maps are empty
0270 // ============================================================================
0271 template <class PBASE>
0272 bool GaudiHistos<PBASE>::noHistos() const {
0273   return ( histo1DMapTitle().empty() && histo2DMapTitle().empty() && histo3DMapTitle().empty() &&
0274            profile1DMapTitle().empty() && profile2DMapTitle().empty() && histo1DMapID().empty() &&
0275            histo2DMapID().empty() && histo3DMapID().empty() && profile1DMapID().empty() && profile2DMapID().empty() );
0276 }
0277 // ============================================================================
0278 // Declare a histogram to the monitor service
0279 // ============================================================================
0280 template <class PBASE>
0281 void GaudiHistos<PBASE>::monitorHisto( const AIDA::IBaseHistogram* hist, const HistoID& ID ) const {
0282   if ( hist && m_declareMoniHists ) {
0283     if ( this->msgLevel( MSG::DEBUG ) ) {
0284       this->debug() << "Monitoring histogram '" << ID.idAsString() << "' desc = '"
0285                     << Gaudi::Utils::Histos::htitle( hist ) << "'" << endmsg;
0286     }
0287     this->declareInfo( histoPath() + "/" + ID.idAsString(), hist, Gaudi::Utils::Histos::htitle( hist ) );
0288   }
0289 }
0290 // ============================================================================
0291 // access the EXISTING 1D histogram by ID
0292 // ============================================================================
0293 template <class PBASE>
0294 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D( const HistoID& ID ) const {
0295   return lookup_( histo1DMapID(), ID );
0296 }
0297 // ============================================================================
0298 // access the EXISTING 2D histogram by ID
0299 // ============================================================================
0300 template <class PBASE>
0301 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D( const HistoID& ID ) const {
0302   return lookup_( histo2DMapID(), ID );
0303 }
0304 // ============================================================================
0305 // access the EXISTING 3D histogram by ID
0306 // ============================================================================
0307 template <class PBASE>
0308 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D( const HistoID& ID ) const {
0309   return lookup_( histo3DMapID(), ID );
0310 }
0311 // ============================================================================
0312 // access the EXISTING 1D profile histogram by ID
0313 // ============================================================================
0314 template <class PBASE>
0315 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D( const HistoID& ID ) const {
0316   return lookup_( profile1DMapID(), ID );
0317 }
0318 // ============================================================================
0319 // access the EXISTING 2D profile histogram by ID
0320 // ============================================================================
0321 template <class PBASE>
0322 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D( const HistoID& ID ) const {
0323   return lookup_( profile2DMapID(), ID );
0324 }
0325 // ============================================================================
0326 // Returns the total number of histograms (of all types) currently booked
0327 // ============================================================================
0328 template <class PBASE>
0329 unsigned int GaudiHistos<PBASE>::totalNumberOfHistos() const {
0330   return histo1DMapID().size() + histo2DMapID().size() + histo3DMapID().size() + profile1DMapID().size() +
0331          profile2DMapID().size();
0332 }
0333 // ============================================================================
0334 // Create a new histogram ID using the given title
0335 // ============================================================================
0336 template <class PBASE>
0337 void GaudiHistos<PBASE>::newHistoID( const std::string& title, HistoID& ID ) const {
0338   if ( useNumericAutoIDs() || title.empty() ) {
0339     if ( !useNumericAutoIDs() ) {
0340       this->Warning(
0341               "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
0342               StatusCode::SUCCESS )
0343           .ignore();
0344     }
0345     // propose the histogram ID (always numeric)
0346     ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
0347     // adjust the proposed ID
0348     while ( histoExists( ID ) ) { ID = HistoID( ID.numeric() + 1 ); }
0349   } else {
0350     // use the title to create a unique literal ID
0351     ID = HistoID( this->convertTitleToID( title ) );
0352     // Just in case ...
0353     while ( histoExists( ID ) ) { ID = HistoID( ID.idAsString() + "_" ); }
0354   }
0355 }
0356 // ============================================================================
0357 // Create an ID string from a title string
0358 // ============================================================================
0359 template <class PBASE>
0360 std::string GaudiHistos<PBASE>::convertTitleToID( std::string title ) const {
0361   // clean up the ID string for all unwanted characters
0362   for ( const auto& i : m_idReplaceInfo ) { stringSearchReplace( title, i.first, i.second ); }
0363   return title;
0364 }
0365 // get the constructed histogram path
0366 // ============================================================================
0367 template <class PBASE>
0368 std::string GaudiHistos<PBASE>::histoPath() const {
0369   std::string path = histoTopDir() + histoDir();
0370   return splitHistoDir() ? dirHbookName( path ) : path;
0371 }
0372 // ============================================================================
0373 // 1D
0374 #include "GaudiAlg/GaudiHistos_1DFixedBinning.icpp"
0375 #include "GaudiAlg/GaudiHistos_1DVariableBinning.icpp"
0376 // 2D
0377 #include "GaudiAlg/GaudiHistos_2DFixedBinning.icpp"
0378 #include "GaudiAlg/GaudiHistos_2DVariableBinning.icpp"
0379 // 3D
0380 #include "GaudiAlg/GaudiHistos_3DFixedBinning.icpp"
0381 #include "GaudiAlg/GaudiHistos_3DVariableBinning.icpp"
0382 // 1D Profile
0383 #include "GaudiAlg/GaudiHistos_1DProfFixedBinning.icpp"
0384 #include "GaudiAlg/GaudiHistos_1DProfVariableBinning.icpp"
0385 // 2D Profile
0386 #include "GaudiAlg/GaudiHistos_2DProfFixedBinning.icpp"
0387 #include "GaudiAlg/GaudiHistos_2DProfVariableBinning.icpp"
0388 // ============================================================================
0389 // The END
0390 // ============================================================================
0391 #endif // GAUDIALG_GAUDIHISTOS_ICPP