Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:38:40

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2022 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 GAUDIKERNEL_RNDMGENGENERATORS_H
0012 #define GAUDIKERNEL_RNDMGENGENERATORS_H
0013 
0014 // STL include files
0015 #include <vector>
0016 
0017 // Framework include files
0018 #include "GaudiKernel/IRndmGen.h"
0019 #include "GaudiKernel/SmartIF.h"
0020 
0021 // Forward declarations
0022 class IRndmGen;
0023 class IRndmGenSvc;
0024 
0025 namespace Rndm {
0026 
0027   template <class TYPE>
0028   class Generator;
0029 
0030   /** Parameters for the Gauss random number generation
0031    */
0032   class GAUDI_API Gauss : public IRndmGen::Param {
0033   protected:
0034     /// Generator is the friend
0035     friend class Generator<Gauss>;
0036     /// Mean of the Gauss distribution
0037     double m_mean;
0038     /// Sigma of the Gauss distribution
0039     double m_sigma;
0040 
0041   public:
0042     /// Standard Constructor
0043     Gauss( double m, double s ) : IRndmGen::Param( IID_IRndmGauss ), m_mean( m ), m_sigma( s ) {}
0044     /// Access mean value of the distribution
0045     double mean() const { return m_mean; }
0046     /// Access width of the distribution
0047     double sigma() const { return m_sigma; }
0048     /// Identifier for factory
0049     static const InterfaceID& typeID() { return IID_IRndmGauss; }
0050     /// Clone parameters
0051     Gauss* clone() const override { return new Gauss( m_mean, m_sigma ); }
0052   };
0053 
0054   /** Parameters for the Gauss random number generation
0055    */
0056   class GAUDI_API Exponential : public IRndmGen::Param {
0057   protected:
0058     /// Mean value of the exponential distribution
0059     double m_mean;
0060 
0061   public:
0062     /// Standard Constructor
0063     Exponential( double m ) : IRndmGen::Param( IID_IRndmExponential ), m_mean( m ) {}
0064     /// Access mean value of the distribution
0065     double mean() const { return m_mean; }
0066     /// Identifier for factory
0067     static const InterfaceID& typeID() { return IID_IRndmExponential; }
0068     /// Clone parameters
0069     Exponential* clone() const override { return new Exponential( m_mean ); }
0070   };
0071 
0072   /** Parameters for the Chi2 distributed random number generation
0073    */
0074   class GAUDI_API Chi2 : public IRndmGen::Param {
0075     friend class Generator<Chi2>;
0076 
0077   protected:
0078     /// Number of degrees of freedom
0079     long m_nDOF;
0080 
0081   public:
0082     /// Standard Constructor
0083     Chi2( long n_dof ) : IRndmGen::Param( IID_IRndmChi2 ), m_nDOF( n_dof ) {}
0084     /// Access mean value of the distribution
0085     long nDOF() const { return m_nDOF; }
0086     /// Identifier for factory
0087     static const InterfaceID& typeID() { return IID_IRndmChi2; }
0088     /// Clone parameters
0089     Chi2* clone() const override { return new Chi2( m_nDOF ); }
0090   };
0091 
0092   /** Parameters for the BreitWigner distributed random number generation
0093    */
0094   class GAUDI_API BreitWigner : public IRndmGen::Param {
0095     friend class Generator<BreitWigner>;
0096 
0097   protected:
0098     /// Mean and Gamma parameter of the Breit-Wigner distribution
0099     double m_mean, m_gamma;
0100 
0101   public:
0102     /// Standard Constructor
0103     BreitWigner( double m, double g ) : IRndmGen::Param( IID_IRndmBreitWigner ), m_mean( m ), m_gamma( g ) {}
0104     /// Access mean value of the distribution
0105     double mean() const { return m_mean; }
0106     /// Access width of the distribution
0107     double gamma() const { return m_gamma; }
0108     /// Identifier for factory
0109     static const InterfaceID& typeID() { return IID_IRndmBreitWigner; }
0110     /// Clone parameters
0111     BreitWigner* clone() const override { return new BreitWigner( m_mean, m_gamma ); }
0112   };
0113 
0114   /** Parameters for the Landau distributed random number generation
0115    */
0116   class GAUDI_API Landau : public IRndmGen::Param {
0117     friend class Generator<Landau>;
0118 
0119   protected:
0120     /// Mean and Gamma parameter of the Breit-Wigner distribution
0121     double m_mean, m_sigma;
0122 
0123   public:
0124     /// Standard Constructor
0125     Landau( double m, double s ) : IRndmGen::Param( IID_IRndmLandau ), m_mean( m ), m_sigma( s ) {}
0126     /// Access mean value of the distribution
0127     double mean() const { return m_mean; }
0128     /// Access width of the distribution
0129     double sigma() const { return m_sigma; }
0130     /// Identifier for factory
0131     static const InterfaceID& typeID() { return IID_IRndmLandau; }
0132     /// Clone parameters
0133     Landau* clone() const override { return new Landau( m_mean, m_sigma ); }
0134   };
0135 
0136   /** Parameters for the BreitWigner distributed random number generation
0137       with cut off;
0138   */
0139   class GAUDI_API BreitWignerCutOff : public IRndmGen::Param {
0140     friend class Generator<BreitWignerCutOff>;
0141 
0142   protected:
0143     /// Mean, Gamma and cut off parameter of the Breit-Wigner distribution
0144     double m_mean, m_gamma, m_cut;
0145 
0146   public:
0147     /// Standard Constructor
0148     BreitWignerCutOff( double m, double g, double c )
0149         : IRndmGen::Param( IID_IRndmBreitWignerCutOff ), m_mean( m ), m_gamma( g ), m_cut( c ) {}
0150     /// Access mean value of the distribution
0151     double mean() const { return m_mean; }
0152     /// Access width of the distribution
0153     double gamma() const { return m_gamma; }
0154     /// Access width of the distribution
0155     double cutOff() const { return m_cut; }
0156     /// Identifier for factory
0157     static const InterfaceID& typeID() { return IID_IRndmBreitWignerCutOff; }
0158     /// Clone parameters
0159     BreitWignerCutOff* clone() const override { return new BreitWignerCutOff( m_mean, m_gamma, m_cut ); }
0160   };
0161 
0162   /** Parameters for the StudentT distributed random number generation
0163    */
0164   class GAUDI_API StudentT : public IRndmGen::Param {
0165     friend class Generator<StudentT>;
0166 
0167   protected:
0168     /// StudentT distribution parameter
0169     double m_aValue;
0170 
0171   public:
0172     /// Standard Constructor
0173     StudentT( double a ) : IRndmGen::Param( IID_IRndmStudentT ), m_aValue( a ) {}
0174     /// Access A parameter
0175     double aValue() const { return m_aValue; }
0176     /// Identifier for factory
0177     static const InterfaceID& typeID() { return IID_IRndmStudentT; }
0178     /// Clone parameters
0179     StudentT* clone() const override { return new StudentT( m_aValue ); }
0180   };
0181 
0182   /** Parameters for the Gamma distributed  random number generation
0183    */
0184   class GAUDI_API Gamma : public IRndmGen::Param {
0185     friend class Generator<Gamma>;
0186 
0187   protected:
0188     /// k Value
0189     double m_kValue;
0190     /// Lambda parameter
0191     double m_lambda;
0192 
0193   public:
0194     /// Standard Constructor
0195     Gamma( double k, double l ) : IRndmGen::Param( IID_IRndmGamma ), m_kValue( k ), m_lambda( l ) {}
0196     /// Access K parameter
0197     double kValue() const { return m_kValue; }
0198     /// Access Lambda parameter
0199     double lambda() const { return m_lambda; }
0200     /// Identifier for factory
0201     static const InterfaceID& typeID() { return IID_IRndmGamma; }
0202     /// Clone parameters
0203     Gamma* clone() const override { return new Gamma( m_kValue, m_lambda ); }
0204   };
0205 
0206   /** Parameters for the Poisson distributed random number generation with
0207    *  a given mean.
0208    */
0209   class GAUDI_API Poisson : public IRndmGen::Param {
0210     friend class Generator<Poisson>;
0211 
0212   protected:
0213     /// Mean value of the Poisson distribution
0214     double m_mean;
0215 
0216   public:
0217     /// Standard Constructor
0218     Poisson( double m ) : IRndmGen::Param( IID_IRndmPoisson ), m_mean( m ) {}
0219     /// Access mean value of the distribution
0220     double mean() const { return m_mean; }
0221     /// Identifier for factory
0222     static const InterfaceID& typeID() { return IID_IRndmPoisson; }
0223     /// Clone parameters
0224     Poisson* clone() const override { return new Poisson( m_mean ); }
0225   };
0226 
0227   /** Parameters for the Binomial distributed random number generation.
0228       The returned values are in fact integers
0229   */
0230   class GAUDI_API Binomial : public IRndmGen::Param {
0231   protected:
0232     /// Number of events the binomial destribution corresponds to
0233     long m_nEvent;
0234     /// And the probability for having success
0235     double m_probability;
0236 
0237   public:
0238     /// Standard Constructor
0239     Binomial( long n, double p ) : IRndmGen::Param( IID_IRndmBinomial ), m_nEvent( n ), m_probability( p ) {}
0240     /// Access number of events
0241     long nEvent() const { return m_nEvent; }
0242     /// Access number of events
0243     double probability() const { return m_probability; }
0244     /// Identifier for factory
0245     static const InterfaceID& typeID() { return IID_IRndmBinomial; }
0246     /// Clone parameters
0247     Binomial* clone() const override { return new Binomial( m_nEvent, m_probability ); }
0248   };
0249 
0250   /** Parameters for the flat random number generation within boundaries
0251    *  [minimum, maximum]
0252    */
0253   class GAUDI_API Flat : public IRndmGen::Param {
0254   protected:
0255     /// Lower boundary for random numbers
0256     double m_minimum;
0257     /// Upper boundary for random numbers
0258     double m_maximum;
0259 
0260   public:
0261     /// Standard Constructor
0262     Flat( double mi, double ma ) : IRndmGen::Param( IID_IRndmFlat ), m_minimum( mi ), m_maximum( ma ) {}
0263     /// Access lower edge
0264     double minimum() const { return m_minimum; }
0265     /// Access upper edge
0266     double maximum() const { return m_maximum; }
0267     /// Identifier for factory
0268     static const InterfaceID& typeID() { return IID_IRndmFlat; }
0269     /// Clone parameters
0270     Flat* clone() const override { return new Flat( m_minimum, m_maximum ); }
0271   };
0272 
0273   /** Parameters for the bit value generation: returns values 0 and 1
0274    */
0275   class GAUDI_API Bit : public IRndmGen::Param {
0276   public:
0277     /// Standard Constructor
0278     Bit() : IRndmGen::Param( IID_IRndmBit ) {}
0279     /// Identifier for factory
0280     static const InterfaceID& typeID() { return IID_IRndmBit; }
0281     /// Clone parameters
0282     Bit* clone() const override { return new Bit(); }
0283   };
0284 
0285   /** Generate a random number Generator following generally distributed random
0286       values, given a user-defined probability distribution function.
0287 
0288       The probability distribution function (Pdf) must be provided by the user
0289       as an array of positive real number. The array size must also be
0290       provided. The Pdf doesn't need to be normalized to 1.
0291       if IntType = 0 ( default value ) a uniform random number is
0292       generated. The uniform number is then transformed
0293       to the user's distribution using the cumulative probability
0294       distribution constructed from his histogram. The cumulative
0295       distribution is inverted using a binary search for the nearest
0296       bin boundary and a linear interpolation within the
0297       bin. Therefore a constant density within each bin is generated.
0298       if IntType = 1 no interpolation is performed and the result is a
0299       discrete distribution.
0300   */
0301   class GAUDI_API DefinedPdf : public IRndmGen::Param {
0302   protected:
0303     /// Vector containing probability distribution function
0304     std::vector<double> m_pdf;
0305     /// Interpolation type
0306     long m_interpolation;
0307 
0308   public:
0309     /// Standard Constructor
0310     DefinedPdf( const std::vector<double>& pdf, long intpol )
0311         : IRndmGen::Param( IID_IRndmDefinedPdf ), m_pdf( pdf ), m_interpolation( intpol ) {}
0312     /// Access pdf
0313     std::vector<double>& pdf() { return m_pdf; }
0314     /// Access interpolation type
0315     long interpolation() const { return m_interpolation; }
0316     /// Identifier for factory
0317     static const InterfaceID& typeID() { return IID_IRndmDefinedPdf; }
0318     /// Clone parameters
0319     DefinedPdf* clone() const override { return new DefinedPdf( m_pdf, m_interpolation ); }
0320   };
0321 
0322   /** Parameters for the Gaussian tail number generation
0323    */
0324   class GAUDI_API GaussianTail : public IRndmGen::Param {
0325   protected:
0326     /// Cut on the Gaussian tail distribution
0327     double m_cut;
0328     /// Sigma of the Gauss ditribution
0329     double m_sigma;
0330 
0331   public:
0332     /// Standard Constructor
0333     GaussianTail( double a, double s ) : IRndmGen::Param( IID_IRndmGaussianTail ), m_cut( a ), m_sigma( s ) {}
0334     /// Access cut value of the distribution
0335     double cut() const { return m_cut; }
0336     /// Access sigma of the distribution
0337     double sigma() const { return m_sigma; }
0338     /// Identifier for factory
0339     static const InterfaceID& typeID() { return IID_IRndmGaussianTail; }
0340     /// Clone parameters
0341     GaussianTail* clone() const override { return new GaussianTail( m_cut, m_sigma ); }
0342   };
0343 
0344   /** Random number accessor
0345       This small class encapsulates the use of the random number generator.
0346       The sole pupose of this class is to hide the usage of the interface and
0347       make the whole thing more user friendly. The object is usable
0348       directly after creation.
0349 
0350       The typical usage is:
0351       Rndm::Numbers numbers();
0352       if ( numbers.initialize(rndmGenSvc, Rndm::Gauss(0.5,0.2)).isSuccess() )   {
0353         for ( int i = 0; i < 10; i++ )  {
0354           value = numbers();
0355           ...
0356         }
0357       }
0358   */
0359   class GAUDI_API Numbers {
0360   protected:
0361     /// Pointer to random number generator
0362     SmartIF<IRndmGen> m_generator;
0363 
0364   public:
0365     /// Standard constructor
0366     Numbers() = default;
0367     /// Copy constructor
0368     Numbers( const Numbers& ) = default;
0369     /// Initializing constructor
0370     Numbers( const SmartIF<IRndmGenSvc>& svc, const IRndmGen::Param& par );
0371     /// Standard destructor
0372     virtual ~Numbers();
0373     /// Initialization
0374     virtual StatusCode initialize( const SmartIF<IRndmGenSvc>& svc, const IRndmGen::Param& par );
0375 #if !defined( GAUDI_V22_API ) || defined( G22_NEW_SVCLOCATOR )
0376     /// Initializing constructor
0377     Numbers( IRndmGenSvc* svc, const IRndmGen::Param& par );
0378     /// Initialization
0379     virtual StatusCode initialize( IRndmGenSvc* svc, const IRndmGen::Param& par );
0380 #endif
0381     /// Finalization
0382     virtual StatusCode finalize();
0383     /// Check if the number supply is possible
0384     operator bool() const { return m_generator; }
0385     /// Operator () for the use within STL
0386     double operator()() const { return this->shoot(); }
0387     /// Pop a new number from the buffer
0388     double pop() const { return this->shoot(); }
0389     /// Pop a new number from the buffer
0390     double shoot() const { return m_generator ? m_generator->shoot() : -1; }
0391     /// Pop a new number from the buffer
0392     StatusCode shootArray( std::vector<double>& array, long num, long start = 0 ) const {
0393       return m_generator ? m_generator->shootArray( array, num, start ) : StatusCode::FAILURE;
0394     }
0395   };
0396 } // namespace Rndm
0397 #endif // GAUDIKERNEL_RNDMGENGENERATORS_H