Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:31:15

0001 // -*- C++ -*-
0002 #ifndef RIVET_SmearedMET_HH
0003 #define RIVET_SmearedMET_HH
0004 
0005 #include "Rivet/Projection.hh"
0006 #include "Rivet/Projections/METFinder.hh"
0007 #include "Rivet/Projections/MissingMomentum.hh"
0008 #include "Rivet/Tools/SmearingFunctions.hh"
0009 #include <functional>
0010 
0011 namespace Rivet {
0012 
0013 
0014   /// Wrapper projection for smearing missing (transverse) energy/momentum with detector resolutions
0015   class SmearedMET : public METFinder {
0016   public:
0017 
0018     /// @name Constructors etc.
0019     /// @{
0020 
0021     /// @brief Constructor from a MissingMomentum projection and a smearing-params function
0022     ///
0023     /// Smearing-params function maps a 3-vector MET and scalar SET to a new METSmearParams struct for sampling
0024     template<typename SMEARPARAMSFN, typename std::enable_if_t<is_same_v<invoke_result_t<SMEARPARAMSFN, Vector3, double>, METSmearParams>, int> = 0>
0025     SmearedMET(const MissingMomentum& mm, const SMEARPARAMSFN& metSmearParamsFn)
0026       : _metSmearParamsFn(metSmearParamsFn), _metSmearFn(nullptr)
0027         // _metSmearFn([&](const Vector3& met, double set) -> Vector3 {
0028         //   const METSmearParams msps = metSmearParamsFn(met, set);
0029         //   return MET_SMEAR_NORM(msps);
0030         // })
0031     {
0032       setName("SmearedMET");
0033       declare(mm, "TruthMET");
0034     }
0035 
0036     /// @brief Constructor from a Cut (on the particles used to determine missing momentum) and a smearing-params function
0037     ///
0038     /// Smearing-params function maps a 3-vector MET and scalar SET to a new METSmearParams struct for sampling
0039     template<typename SMEARPARAMSFN, typename std::enable_if_t<is_same_v<invoke_result_t<SMEARPARAMSFN, Vector3, double>, METSmearParams>, int> = 0>
0040     SmearedMET(const SMEARPARAMSFN& metSmearParamsFn, const Cut& cut=Cuts::OPEN)
0041       : SmearedMET(MissingMomentum(cut), metSmearParamsFn)
0042     {  }
0043 
0044     /// @brief Constructor from a MissingMomentum projection and a smearing function
0045     ///
0046     /// Smearing function maps a 3-vector MET and scalar SET to a new MET 3-vector: f(V3, double) -> V3
0047     template<typename SMEARFN, typename std::enable_if_t<is_same_v<invoke_result_t<SMEARFN, Vector3, double>, Vector3>, int> = 0>
0048     SmearedMET(const MissingMomentum& mm, const SMEARFN& metSmearFn)
0049        : _metSmearParamsFn(nullptr), _metSmearFn(metSmearFn)
0050     {
0051       setName("SmearedMET");
0052       declare(mm, "TruthMET");
0053     }
0054 
0055     /// @brief Constructor from a Cut (on the particles used to determine missing momentum) and a smearing function
0056     ///
0057     /// Smearing function maps a 3-vector MET and scalar SET to a new MET 3-vector: f(V3, double) -> V3
0058     template<typename SMEARFN, typename std::enable_if_t<is_same_v<invoke_result_t<SMEARFN, Vector3, double>, Vector3>, int> = 0>
0059     SmearedMET(const SMEARFN& metSmearFn, const Cut& cut=Cuts::OPEN)
0060      : SmearedMET(MissingMomentum(cut), metSmearFn)
0061     {  }
0062 
0063     /// @brief Constructor from a MissingMomentum projection and a pair of smearing-params and smearing functions
0064     ///
0065     /// Smearing-params function maps a 3-vector MET and scalar SET to a new METSmearParams struct for sampling
0066     ///
0067     /// Smearing function maps a 3-vector MET and scalar SET to a new MET 3-vector: f(V3, double) -> V3
0068     template <typename SMEARPARAMSFN, typename SMEARFN,
0069               typename std::enable_if_t<is_same_v<invoke_result_t<SMEARFN, Vector3, double>, Vector3> &&
0070                                         is_same_v<invoke_result_t<SMEARPARAMSFN, Vector3, double>, METSmearParams>, int> = 0>
0071     SmearedMET(const MissingMomentum& mm, const SMEARPARAMSFN& metSmearParamsFn, const SMEARFN& metSmearFn)
0072       : _metSmearParamsFn(metSmearParamsFn), _metSmearFn(metSmearFn)
0073     {
0074       setName("SmearedMET");
0075       declare(mm, "TruthMET");
0076     }
0077 
0078     /// @brief Constructor from a Cut (on the particles used to determine missing momentum) and a pair of smearing (params) functions
0079     ///
0080     /// Smearing-params function maps a 3-vector MET and scalar SET to a new METSmearParams struct for sampling
0081     ///
0082     /// Smearing function maps a 3-vector MET and scalar SET to a new MET 3-vector: f(V3, double) -> V3
0083     template <typename SMEARPARAMSFN, typename SMEARFN,
0084               typename std::enable_if_t<is_same_v<invoke_result_t<SMEARFN, Vector3, double>, Vector3> &&
0085                                         is_same_v<invoke_result_t<SMEARPARAMSFN, Vector3, double>, METSmearParams>, int> = 0>
0086     SmearedMET(const SMEARPARAMSFN& metSmearParamsFn, const SMEARFN& metSmearFn, const Cut& cut=Cuts::OPEN)
0087       : SmearedMET(MissingMomentum(cut), metSmearParamsFn, metSmearFn)
0088     {  }
0089 
0090 
0091     /// Clone on the heap.
0092     RIVET_DEFAULT_PROJ_CLONE(SmearedMET);
0093 
0094     /// @}
0095 
0096     /// Import to avoid warnings about overload-hiding
0097     using Projection::operator =;
0098 
0099 
0100     /// Compare to another SmearedMET
0101     CmpState compare(const Projection& p) const {
0102       // const SmearedMET& other = dynamic_cast<const SmearedMET&>(p);
0103       // if (get_address(_metSmearParamsFn) == 0) return cmp((size_t)this, (size_t)&p);
0104       // if (get_address(_metSmearFn) == 0) return cmp((size_t)this, (size_t)&p);
0105       // MSG_TRACE("Smear hashes (params) = " << get_address(_metSmearParamsFn) << "," << get_address(other._metSmearParamsFn));
0106       // MSG_TRACE("Smear hashes (smear) = " << get_address(_metSmearFn) << "," << get_address(other._metSmearFn));
0107       // return mkPCmp(other, "TruthMET") ||
0108       //   cmp(get_address(_metSmearParamsFn), get_address(other._metSmearParamsFn));
0109       //   cmp(get_address(_metSmearFn), get_address(other._metSmearFn));
0110       return CmpState::UNDEF;
0111     }
0112 
0113 
0114     /// Perform the MET finding & smearing calculation
0115     void project(const Event& e) {
0116       const METFinder& mm = apply<MissingMomentum>(e, "TruthMET");
0117       _set = mm.scalarEt();
0118       _vet = mm.vectorEt();
0119       if (_metSmearFn) {
0120         _vet = _metSmearFn(_vet, mm.scalarEt()); //< custom smearing
0121       } else if (_metSmearParamsFn) {
0122         const METSmearParams msps = _metSmearParamsFn(_vet, mm.scalarEt()); //< custom smear params
0123         _vet = MET_SMEAR_NORM(msps); //< normal-distribution smearing from custom params
0124       } else {
0125         throw SmearError("Attempt to smear MET with neither smearing function nor smearing-params function set");
0126       }
0127     }
0128 
0129 
0130     /// @name Transverse-momentum functions
0131     ///
0132     /// @note This may be what you want, even if the paper calls it "missing Et"!
0133     /// @{
0134 
0135     /// The vector-summed visible transverse momentum in the event, as a 3-vector with z=0
0136     const Vector3& vectorPt() const { return vectorEt(); }
0137     /// The scalar-summed visible transverse momentum in the event
0138     double scalarPt() const { return scalarEt(); }
0139 
0140     /// @}
0141 
0142 
0143     /// @name Transverse-energy functions
0144     ///
0145     /// @warning Despite the common names "MET" and "SET", what's often meant is the pT functions above!
0146     /// @{
0147 
0148     /// The vector-summed visible transverse energy in the event, as a 3-vector with z=0
0149     ///
0150     /// @note Reverse this vector with operator- to get the missing ET vector.
0151     const Vector3& vectorEt() const { return _vet; }
0152 
0153     /// The scalar-summed visible transverse energy in the event, as a 3-vector with z=0
0154     double scalarEt() const { return _set; }
0155 
0156     /// Obtain an approximation to the MET resolution for this event
0157     double missingEtResolution() const {
0158       if (!_metSmearParamsFn)
0159         throw UserError("Trying to compute MET significance without a registered significance function");
0160       METSmearParams msps = _metSmearParamsFn(vectorEt(), scalarEt());
0161       //return max(msps.eResolution, msps.pResolution);
0162       return msps.pResolution;
0163     }
0164 
0165     /// Obtain an approximation to the MET significant (value/resolution) for this event
0166     double missingEtSignf() const {
0167       return missingEt() / missingEtResolution();
0168     }
0169 
0170     /// @}
0171 
0172 
0173     /// Reset the projection. Smearing functions will be unchanged.
0174     void reset() {  }
0175 
0176 
0177   protected:
0178 
0179     Vector3 _vet;
0180     double _set;
0181 
0182     /// Stored smearing-params function
0183     METSmearParamsFn _metSmearParamsFn;
0184 
0185     /// Stored smearing function
0186     METSmearFn _metSmearFn;
0187 
0188   };
0189 
0190 
0191 }
0192 
0193 #endif