Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:27

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 GAUDISVC_GENERIC2D_H
0012 #define GAUDISVC_GENERIC2D_H 1
0013 
0014 #include "AIDA/IProfile2D.h"
0015 #include "Annotation.h"
0016 #include "Axis.h"
0017 #include "GaudiKernel/HistogramBase.h"
0018 #include "TFile.h"
0019 #include <memory>
0020 #include <stdexcept>
0021 
0022 // Hide warning message:
0023 // warning: 'XYZ' overrides a member function but is not marked 'override'
0024 #ifdef __clang__
0025 #  pragma clang diagnostic push
0026 #  pragma clang diagnostic ignored "-Wsuggest-override"
0027 #  pragma clang diagnostic ignored "-Winconsistent-missing-override"
0028 #elif defined( __GNUC__ ) && __GNUC__ >= 5
0029 #  pragma GCC diagnostic push
0030 #  pragma GCC diagnostic ignored "-Wsuggest-override"
0031 #endif
0032 
0033 namespace Gaudi {
0034 
0035   /** @class Generic2D Generic2D.h GaudiPI/Generic2D.h
0036    *
0037    * Common AIDA implementation stuff for histograms and profiles
0038    * using ROOT implementations
0039    *
0040    * Credits: This code is the result of some stripdown implementation
0041    * of LCG/PI. Credits to them!
0042    *
0043    *  @author M.Frank
0044    */
0045   template <class INTERFACE, class IMPLEMENTATION>
0046   class GAUDI_API Generic2D : virtual public INTERFACE, virtual public HistogramBase {
0047   public:
0048     typedef Generic2D<INTERFACE, IMPLEMENTATION> Base;
0049 
0050     Generic2D() = default;
0051 
0052   protected:
0053     /// constructor
0054     Generic2D( IMPLEMENTATION* p ) : m_rep( p ) {}
0055 
0056   public:
0057     /// ROOT object implementation
0058     TObject* representation() const override { return m_rep.get(); }
0059     /// Adopt ROOT histogram representation
0060     void adoptRepresentation( TObject* rep ) override;
0061     /// Get the title of the object
0062     std::string title() const override { return m_annotation.value( "Title" ); }
0063     /// Set the title of the object
0064     bool setTitle( const std::string& title ) override;
0065     /// object name
0066     std::string name() const { return m_annotation.value( "Name" ); }
0067     /// Set the name of the object
0068     bool setName( const std::string& newName );
0069     /// Access annotation object
0070     AIDA::IAnnotation& annotation() override { return m_annotation; }
0071     /// Access annotation object (cons)
0072     const AIDA::IAnnotation& annotation() const override { return m_annotation; }
0073 
0074     /// Return the X axis.
0075     const AIDA::IAxis& xAxis() const override { return m_xAxis; }
0076     /// Return the Y axis.
0077     const AIDA::IAxis& yAxis() const override { return m_yAxis; }
0078     /// operator methods
0079     virtual int rIndexX( int index ) const { return m_xAxis.rIndex( index ); }
0080     /// operator methods
0081     virtual int rIndexY( int index ) const { return m_yAxis.rIndex( index ); }
0082 
0083     /// Get the number or all the entries
0084     int entries() const override;
0085     /// Get the number or all the entries, both in range and underflow/overflow bins of the IProfile.
0086     int allEntries() const override;
0087     /// Get the number of entries in the underflow and overflow bins.
0088     int extraEntries() const override;
0089     /// Get the sum of in range bin heights in the IProfile.
0090     double sumBinHeights() const override;
0091     /// Get the sum of all the bins heights (including underflow and overflow bin).
0092     double sumAllBinHeights() const override;
0093     /// Get the sum of the underflow and overflow bin height.
0094     double sumExtraBinHeights() const override { return sumAllBinHeights() - sumBinHeights(); }
0095     /// Get the minimum height of the in-range bins.
0096     double minBinHeight() const override;
0097     /// Get the maximum height of the in-range bins.
0098     double maxBinHeight() const override;
0099 
0100     /// The weighted mean along x of a given bin.
0101     double binMeanX( int indexX, int indexY ) const override;
0102     /// The weighted mean along y of a given bin.
0103     double binMeanY( int indexX, int indexY ) const override;
0104     /// The number of entries (ie the number of times fill was called for this bin).
0105     int binEntries( int indexX, int indexY ) const override;
0106     /// Equivalent to <tt>projectionX().binEntries(indexX)</tt>.
0107     int binEntriesX( int indexX ) const override;
0108     /// Equivalent to <tt>projectionY().binEntries(indexY)</tt>.
0109     int binEntriesY( int indexY ) const override;
0110     /// Total height of the corresponding bin (ie the sum of the weights in this bin).
0111     double binHeight( int indexX, int indexY ) const override;
0112     /// Equivalent to <tt>projectionX().binHeight(indexX)</tt>.
0113     double binHeightX( int indexX ) const override;
0114     /// Equivalent to <tt>projectionY().binHeight(indexY)</tt>.
0115     double binHeightY( int indexY ) const override;
0116     /// The error on this bin.
0117     double binError( int indexX, int indexY ) const override;
0118     /// The spread (RMS) of this bin.
0119     virtual double binRms( int indexX, int indexY ) const;
0120     /// Returns the mean of the profile, as calculated on filling-time projected on the X axis.
0121     double meanX() const override;
0122     /// Returns the mean of the profile, as calculated on filling-time projected on the Y axis.
0123     double meanY() const override;
0124     /// Returns the rms of the profile as calculated on filling-time projected on the X axis.
0125     double rmsX() const override;
0126     /// Returns the rms of the profile as calculated on filling-time projected on the Y axis.
0127     double rmsY() const override;
0128     /// Convenience method, equivalent to <tt>xAxis().coordToIndex(coord)</tt>.
0129     int coordToIndexX( double coordX ) const override;
0130     /// Convenience method, equivalent to <tt>yAxis().coordToIndex(coord)</tt>.
0131     int coordToIndexY( double coordY ) const override;
0132     /// Number of equivalent entries, i.e. <tt>SUM[ weight ] ^ 2 / SUM[ weight^2 ]</tt>
0133     virtual double equivalentBinEntries() const;
0134     /// Scale the weights and the errors of all the IHistogram's bins (in-range and out-of-range ones) by a given scale
0135     /// factor.
0136     virtual bool scale( double scaleFactor );
0137     /// Modifies this profile by adding the contents of profile to it.
0138     bool add( const INTERFACE& h ) override;
0139     // overwrite reset
0140     bool reset() override;
0141     /// Introspection method
0142     void* cast( const std::string& className ) const override;
0143     /// The AIDA user-level unterface leaf class type
0144     const std::string& userLevelClassType() const { return m_classType; }
0145     /// Get the Histogram's dimension.
0146     int dimension() const override { return 2; }
0147     /// Print (ASCII) the histogram into the output stream
0148     std::ostream& print( std::ostream& s ) const override;
0149     /// Write (ASCII) the histogram table into the output stream
0150     std::ostream& write( std::ostream& s ) const override;
0151     /// Write (ASCII) the histogram table into a file
0152     int write( const char* file_name ) const override;
0153 
0154   protected:
0155     /// X axis member
0156     Axis m_xAxis;
0157     /// Y axis member
0158     Axis m_yAxis;
0159     /// Object annotations
0160     mutable AIDA::Annotation m_annotation;
0161     /// Reference to underlying implementation
0162     std::unique_ptr<IMPLEMENTATION> m_rep;
0163     /// class type
0164     std::string m_classType;
0165     /// cache sumEntries (allEntries)   when setting contents since Root can't compute by himself
0166     int m_sumEntries = 0;
0167   };
0168 
0169   template <class INTERFACE, class IMPLEMENTATION>
0170   bool Generic2D<INTERFACE, IMPLEMENTATION>::setTitle( const std::string& title ) {
0171     m_rep->SetTitle( title.c_str() );
0172     if ( !annotation().addItem( "Title", title ) ) m_annotation.setValue( "Title", title );
0173     if ( !annotation().addItem( "title", title ) ) annotation().setValue( "title", title );
0174     return true;
0175   }
0176 
0177   template <class INTERFACE, class IMPLEMENTATION>
0178   bool Generic2D<INTERFACE, IMPLEMENTATION>::setName( const std::string& newName ) {
0179     m_rep->SetName( newName.c_str() );
0180     m_annotation.setValue( "Name", newName );
0181     return true;
0182   }
0183 
0184   template <class INTERFACE, class IMPLEMENTATION>
0185   int Generic2D<INTERFACE, IMPLEMENTATION>::entries() const {
0186     return m_rep->GetEntries();
0187   }
0188 
0189   template <class INTERFACE, class IMPLEMENTATION>
0190   int Generic2D<INTERFACE, IMPLEMENTATION>::allEntries() const {
0191     return m_rep->GetEntries();
0192   }
0193 
0194   template <class INTERFACE, class IMPLEMENTATION>
0195   double Generic2D<INTERFACE, IMPLEMENTATION>::minBinHeight() const {
0196     return m_rep->GetMinimum();
0197   }
0198 
0199   template <class INTERFACE, class IMPLEMENTATION>
0200   double Generic2D<INTERFACE, IMPLEMENTATION>::maxBinHeight() const {
0201     return m_rep->GetMaximum();
0202   }
0203 
0204   template <class INTERFACE, class IMPLEMENTATION>
0205   double Generic2D<INTERFACE, IMPLEMENTATION>::sumBinHeights() const {
0206     return m_rep->GetSumOfWeights();
0207   }
0208 
0209   template <class INTERFACE, class IMPLEMENTATION>
0210   double Generic2D<INTERFACE, IMPLEMENTATION>::sumAllBinHeights() const {
0211     return m_rep->GetSum();
0212   }
0213 
0214   template <class INTERFACE, class IMPLEMENTATION>
0215   double Generic2D<INTERFACE, IMPLEMENTATION>::binRms( int indexX, int indexY ) const {
0216     return m_rep->GetBinError( rIndexX( indexX ), rIndexY( indexY ) );
0217   }
0218 
0219   template <class INTERFACE, class IMPLEMENTATION>
0220   double Generic2D<INTERFACE, IMPLEMENTATION>::binMeanX( int indexX, int ) const {
0221     return m_rep->GetXaxis()->GetBinCenter( rIndexX( indexX ) );
0222   }
0223 
0224   template <class INTERFACE, class IMPLEMENTATION>
0225   double Generic2D<INTERFACE, IMPLEMENTATION>::binMeanY( int, int indexY ) const {
0226     return m_rep->GetYaxis()->GetBinCenter( rIndexY( indexY ) );
0227   }
0228 
0229   template <class INTERFACE, class IMPLEMENTATION>
0230   int Generic2D<INTERFACE, IMPLEMENTATION>::binEntriesX( int index ) const {
0231     int n = 0;
0232     for ( int iY = -2; iY < yAxis().bins(); ++iY ) n += binEntries( index, iY );
0233     return n;
0234   }
0235 
0236   template <class INTERFACE, class IMPLEMENTATION>
0237   int Generic2D<INTERFACE, IMPLEMENTATION>::binEntriesY( int index ) const {
0238     int n = 0;
0239     for ( int iX = -2; iX < xAxis().bins(); ++iX ) n += binEntries( iX, index );
0240     return n;
0241   }
0242 
0243   template <class INTERFACE, class IMPLEMENTATION>
0244   double Generic2D<INTERFACE, IMPLEMENTATION>::binHeight( int indexX, int indexY ) const {
0245     return m_rep->GetBinContent( rIndexX( indexX ), rIndexY( indexY ) );
0246   }
0247 
0248   template <class INTERFACE, class IMPLEMENTATION>
0249   double Generic2D<INTERFACE, IMPLEMENTATION>::binHeightX( int index ) const {
0250     double s = 0;
0251     for ( int iY = -2; iY < yAxis().bins(); ++iY ) { s += binHeight( index, iY ); }
0252     return s;
0253   }
0254 
0255   template <class INTERFACE, class IMPLEMENTATION>
0256   double Generic2D<INTERFACE, IMPLEMENTATION>::binHeightY( int index ) const {
0257     double s = 0;
0258     for ( int iX = -2; iX < xAxis().bins(); ++iX ) s += binHeight( iX, index );
0259     return s;
0260   }
0261 
0262   template <class INTERFACE, class IMPLEMENTATION>
0263   double Generic2D<INTERFACE, IMPLEMENTATION>::binError( int indexX, int indexY ) const {
0264     return m_rep->GetBinError( rIndexX( indexX ), rIndexY( indexY ) );
0265   }
0266 
0267   template <class INTERFACE, class IMPLEMENTATION>
0268   double Generic2D<INTERFACE, IMPLEMENTATION>::meanX() const {
0269     return m_rep->GetMean( 1 );
0270   }
0271 
0272   template <class INTERFACE, class IMPLEMENTATION>
0273   double Generic2D<INTERFACE, IMPLEMENTATION>::meanY() const {
0274     return m_rep->GetMean( 2 );
0275   }
0276 
0277   template <class INTERFACE, class IMPLEMENTATION>
0278   double Generic2D<INTERFACE, IMPLEMENTATION>::rmsX() const {
0279     return m_rep->GetRMS( 1 );
0280   }
0281 
0282   template <class INTERFACE, class IMPLEMENTATION>
0283   double Generic2D<INTERFACE, IMPLEMENTATION>::rmsY() const {
0284     return m_rep->GetRMS( 2 );
0285   }
0286 
0287   template <class INTERFACE, class IMPLEMENTATION>
0288   int Generic2D<INTERFACE, IMPLEMENTATION>::coordToIndexX( double coord ) const {
0289     return xAxis().coordToIndex( coord );
0290   }
0291 
0292   template <class INTERFACE, class IMPLEMENTATION>
0293   int Generic2D<INTERFACE, IMPLEMENTATION>::coordToIndexY( double coord ) const {
0294     return yAxis().coordToIndex( coord );
0295   }
0296 
0297   template <class INTERFACE, class IMPLEMENTATION>
0298   bool Generic2D<INTERFACE, IMPLEMENTATION>::add( const INTERFACE& hist ) {
0299     const Base* p = dynamic_cast<const Base*>( &hist );
0300     if ( !p ) throw std::runtime_error( "Cannot add profile histograms of different implementations." );
0301     m_rep->Add( p->m_rep.get() );
0302     return true;
0303   }
0304 
0305   template <class INTERFACE, class IMPLEMENTATION>
0306   int Generic2D<INTERFACE, IMPLEMENTATION>::extraEntries() const {
0307     return binEntries( AIDA::IAxis::UNDERFLOW_BIN, AIDA::IAxis::UNDERFLOW_BIN ) +
0308            binEntries( AIDA::IAxis::UNDERFLOW_BIN, AIDA::IAxis::OVERFLOW_BIN ) +
0309            binEntries( AIDA::IAxis::OVERFLOW_BIN, AIDA::IAxis::UNDERFLOW_BIN ) +
0310            binEntries( AIDA::IAxis::OVERFLOW_BIN, AIDA::IAxis::OVERFLOW_BIN );
0311   }
0312 
0313   template <class INTERFACE, class IMPLEMENTATION>
0314   double Generic2D<INTERFACE, IMPLEMENTATION>::equivalentBinEntries() const {
0315     if ( sumBinHeights() <= 0 ) return 0;
0316     Stat_t stats[11]; // cover up to 3D...
0317     m_rep->GetStats( stats );
0318     return stats[0] * stats[0] / stats[1];
0319   }
0320 
0321   template <class INTERFACE, class IMPLEMENTATION>
0322   bool Generic2D<INTERFACE, IMPLEMENTATION>::scale( double scaleFactor ) {
0323     m_rep->Scale( scaleFactor );
0324     return true;
0325   }
0326 
0327   template <class INTERFACE, class IMPLEMENTATION>
0328   bool Generic2D<INTERFACE, IMPLEMENTATION>::reset() {
0329     m_sumEntries = 0;
0330     m_rep->Reset();
0331     return true;
0332   }
0333 
0334   template <class INTERFACE, class IMPLEMENTATION>
0335   std::ostream& Generic2D<INTERFACE, IMPLEMENTATION>::print( std::ostream& s ) const {
0336     /// bin contents and errors are printed for all bins including under and overflows
0337     m_rep->Print( "all" );
0338     return s;
0339   }
0340 
0341   /// Write (ASCII) the histogram table into the output stream
0342   template <class INTERFACE, class IMPLEMENTATION>
0343   std::ostream& Generic2D<INTERFACE, IMPLEMENTATION>::write( std::ostream& s ) const {
0344     s << std::endl << "2D Histogram Table: " << std::endl;
0345     s << "BinX, BinY, Height, Error " << std::endl;
0346     for ( int i = 0; i < xAxis().bins(); ++i ) {
0347       for ( int j = 0; j < yAxis().bins(); ++j ) {
0348         s << binMeanX( i, j ) << ", " << binMeanY( i, j ) << ", " << binHeight( i, j ) << ", " << binError( i, j )
0349           << std::endl;
0350       }
0351     }
0352     s << std::endl;
0353     return s;
0354   }
0355 
0356   /// Write (ASCII) the histogram table into a file
0357   template <class INTERFACE, class IMPLEMENTATION>
0358   int Generic2D<INTERFACE, IMPLEMENTATION>::write( const char* file_name ) const {
0359     TFile* f      = TFile::Open( file_name, "RECREATE" );
0360     Int_t  nbytes = m_rep->Write();
0361     f->Close();
0362     return nbytes;
0363   }
0364 } // namespace Gaudi
0365 
0366 #ifdef __clang__
0367 #  pragma clang diagnostic pop
0368 #elif defined( __GNUC__ ) && __GNUC__ >= 5
0369 #  pragma GCC diagnostic pop
0370 #endif
0371 
0372 #endif // GAUDIPI_GENERIC2D_H