Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:13:40

0001 // -*- C++ -*-
0002 #ifndef RIVET_MomentumSmearingFunctions_HH
0003 #define RIVET_MomentumSmearingFunctions_HH
0004 
0005 #include "Rivet/Math/Vector4.hh"
0006 #include "Rivet/Tools/Random.hh"
0007 
0008 namespace Rivet {
0009 
0010 
0011   /// @ingroup smearing
0012   /// @{
0013 
0014   /// @defgroup smearing_mom Generic 4-momentum filtering, efficiency and smearing utils
0015   /// @{
0016 
0017   /// @brief Struct for holding momentum-smearing parameters
0018   ///
0019   /// Contains a nominal 4-momentum (maybe shifted in energy or angle)
0020   /// and absolute resolutions in momentum, energy, phi, and eta, with
0021   /// which to smear the nominal.
0022   struct P4SmearParams {
0023     P4SmearParams(const FourMomentum& p4nom, double pres=0.0, double eres=0.0, double phires=0.0, double etares=0.0)
0024       : p4Nominal(p4nom), pResolution(pres), eResolution(pres),
0025         phiResolution(phires), etaResolution(etares) {}
0026     FourMomentum p4Nominal;
0027     double pResolution{0.0}, eResolution{0.0}, phiResolution{0.0}, etaResolution{0.0};
0028   };
0029 
0030   /// Typedef for FourMomentum smearing functions/functors
0031   typedef std::function<FourMomentum(const FourMomentum&)> P4SmearFn;
0032 
0033   /// Typedef for FourMomentum efficiency functions/functors
0034   typedef std::function<double(const FourMomentum&)> P4EffFn;
0035 
0036 
0037   /// Take a FourMomentum and return 0
0038   inline double P4_EFF_ZERO(const FourMomentum& ) { return 0; }
0039 
0040   /// Take a FourMomentum and return 1
0041   inline double P4_EFF_ONE(const FourMomentum& ) { return 1; }
0042 
0043   /// Take a FourMomentum and return a constant number
0044   struct P4_EFF_CONST {
0045     P4_EFF_CONST(double x) : _x(x) {}
0046     double operator () (const FourMomentum& )  const { return _x; }
0047     double _x;
0048   };
0049 
0050 
0051   /// Take a FourMomentum and return it unmodified
0052   inline FourMomentum P4_SMEAR_IDENTITY(const FourMomentum& p) { return p; }
0053   /// Alias for P4_SMEAR_IDENTITY
0054   inline FourMomentum P4_SMEAR_PERFECT(const FourMomentum& p) { return p; }
0055 
0056   /// Smear a FourMomentum's energy using a Gaussian of absolute width @a resolution
0057   /// @todo Also make jet versions that update/smear constituents?
0058   inline FourMomentum P4_SMEAR_E_GAUSS(const FourMomentum& p, double resolution) {
0059     const double mass = p.mass2() > 0 ? p.mass() : 0; //< numerical carefulness...
0060     const double smeared_E = max(randnorm(p.E(), resolution), mass); //< can't let the energy go below the mass!
0061     return FourMomentum::mkEtaPhiME(p.eta(), p.phi(), mass, smeared_E);
0062   }
0063 
0064   /// Smear a FourMomentum's transverse momentum using a Gaussian of absolute width @a resolution
0065   inline FourMomentum P4_SMEAR_PT_GAUSS(const FourMomentum& p, double resolution) {
0066     const double smeared_pt = max(randnorm(p.pT(), resolution), 0.);
0067     const double mass = p.mass2() > 0 ? p.mass() : 0; //< numerical carefulness...
0068     return FourMomentum::mkEtaPhiMPt(p.eta(), p.phi(), mass, smeared_pt);
0069   }
0070 
0071   /// Smear a FourMomentum's mass using a Gaussian of absolute width @a resolution
0072   inline FourMomentum P4_SMEAR_MASS_GAUSS(const FourMomentum& p, double resolution) {
0073     const double smeared_mass = max(randnorm(p.mass(), resolution), 0.);
0074     return FourMomentum::mkEtaPhiMPt(p.eta(), p.phi(), smeared_mass, p.pT());
0075   }
0076 
0077   /// @}
0078 
0079 
0080 
0081   /// @defgroup smearing_mom Generic 3-momentum filtering, efficiency and smearing utils
0082   /// @{
0083 
0084   /// Take a Vector3 and return 0
0085   inline double P3_EFF_ZERO(const Vector3&) { return 0; }
0086 
0087   /// Take a Vector3 and return 1
0088   inline double P3_EFF_ONE(const Vector3&) { return 1; }
0089 
0090   /// Take a Vector3 and return a constant number
0091   struct P3_EFF_CONST {
0092     P3_EFF_CONST(double x) : _x(x) {}
0093     double operator () (const Vector3& )  const { return _x; }
0094     double _x;
0095   };
0096 
0097 
0098   /// Take a Vector3 and return it unmodified
0099   inline Vector3 P3_SMEAR_IDENTITY(const Vector3& p) { return p; }
0100   /// Alias for P3_SMEAR_IDENTITY
0101   inline Vector3 P3_SMEAR_PERFECT(const Vector3& p) { return p; }
0102 
0103   /// Smear a Vector3's length using a Gaussian of absolute width @a resolution
0104   inline Vector3 P3_SMEAR_LEN_GAUSS(const Vector3& p, double resolution) {
0105     const double smeared_mod = max(randnorm(p.mod(), resolution), 0.); //< can't let the energy go below the mass!
0106     return smeared_mod * p.unit();
0107   }
0108 
0109   /// @}
0110 
0111 
0112 
0113   /// @defgroup smearing_met Generic missing-ET smearing functions
0114   /// @{
0115 
0116   /// @brief Struct for holding MET-smearing parameters
0117   ///
0118   /// Contains a nominal 3-momentum (maybe shifted in energy or angle)
0119   /// and absolute resolutions in momentum, energy, phi, and eta, with
0120   /// which to Gaussian-smear the nominal.
0121   struct METSmearParams {
0122     METSmearParams(const Vector3& vmetnom, double pres=0.0, double phires=0.0)
0123       : vmetNominal(vmetnom), pResolution(pres), phiResolution(phires) {}
0124     Vector3 vmetNominal;
0125     double pResolution{0.0}, phiResolution{0.0};
0126   };
0127 
0128   /// Typedef for MET smearing-parameter functions/functors (given a MET vector and scalar sum(ET))
0129   ///
0130   /// Returns a nominal MET 3-vector (maybe shifted in energy or angle)
0131   /// and a resolution (in GeV) with which to Gaussian-smear its momentum.
0132   ///
0133   /// @todo Allow MET calculation to access the whole Event?
0134   typedef function<METSmearParams(const Vector3&, double)> METSmearParamsFn;
0135 
0136   /// Typedef for MET smearing functions/functors (given a MET vector and scalar sum(ET))
0137   ///
0138   /// @todo Allow MET calculation to access the whole Event?
0139   typedef function<Vector3(const Vector3&, double)> METSmearFn;
0140 
0141 
0142   /// @brief Smear a nominal vector magnitude by Gaussian with the given absolute resolutions
0143   ///
0144   /// @note For momentum resolutions comparable to or larger than the
0145   /// value they are smearing, a modulus of the resulting vaue is
0146   /// taken, i.e. "reflecting" negative tails back up to positive
0147   /// rather than truncating at zero (or -- horrors -- accidentally
0148   /// flipping the vector direction!) This is not obviously _better_
0149   /// than truncating at zero, and ideally we'd avoid this with some
0150   /// physical positive-definite sampling... but until then let's try
0151   /// to make sure the assuming-Gaussian resolution functions don't
0152   /// have to work in very asymmetric regimes where a single sigma
0153   /// isn't enough.
0154   ///
0155   /// @todo Improve on "reflect in zero" sampling behaviour where res >~ mu.
0156   inline Vector3 MET_SMEAR_NORM(const METSmearParams& msps) {
0157     const Vector3& vmet = msps.vmetNominal;
0158     // MET magnitude smear
0159     // const double metsmear = max(randnorm(vmet.mod(), resolution), 0.); //< make peak at 0
0160     const double metsmear = fabs(randnorm(vmet.mod(), msps.pResolution)); //< "reflect" at 0
0161     // MET phi-angle smearing matrix
0162     const Matrix3 phismear = Matrix3::mkZRotation(randnorm(0.0, msps.phiResolution));
0163     // Apply smearings
0164     return metsmear * phismear * vmet.unit();
0165   }
0166 
0167 
0168   /// @brief Identity resolution is 0 (perfect delta function, no offset)
0169   ///
0170   /// @note This simple factorization doesn't allow for expression of
0171   /// offsets or angular smearing... revisit if needed
0172   inline METSmearParams MET_SMEARPARAMS_IDENTITY(const Vector3& met, double) {
0173     return METSmearParams(met, 0.0, 0.0);
0174   }
0175 
0176   /// @brief Identity MET smearing just returns the input
0177   inline Vector3 MET_SMEAR_IDENTITY(const Vector3& met, double) {
0178     return met;
0179   }
0180 
0181   /// @}
0182 
0183   /// @}
0184 
0185 }
0186 
0187 #endif