Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:54

0001 //
0002 //
0003 
0004 #ifndef DataFormats_PatCandidates_MET_h
0005 #define DataFormats_PatCandidates_MET_h
0006 
0007 /**
0008   \class    pat::MET MET.h "DataFormats/PatCandidates/interface/MET.h"
0009   \brief    Analysis-level MET class
0010 
0011    pat::MET implements an analysis-level missing energy class as a 4-vector
0012    within the 'pat' namespace.
0013 
0014    Please post comments and questions to the Physics Tools hypernews:
0015    https://hypernews.cern.ch/HyperNews/CMS/get/physTools.html
0016 
0017   \author   Steven Lowette, Giovanni Petrucciani, Frederic Ronga, Slava Krutelyov
0018 */
0019 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0020 #include <atomic>
0021 #endif
0022 
0023 #include "DataFormats/METReco/interface/CaloMET.h"
0024 #include "DataFormats/METReco/interface/PFMET.h"
0025 #include "DataFormats/METReco/interface/GenMET.h"
0026 #include "DataFormats/PatCandidates/interface/PATObject.h"
0027 #include <cmath>
0028 
0029 // Define typedefs for convenience
0030 namespace pat {
0031   class MET;
0032   typedef std::vector<MET> METCollection;
0033   typedef edm::Ref<METCollection> METRef;
0034   typedef edm::RefVector<METCollection> METRefVector;
0035 }  // namespace pat
0036 
0037 // Class definition
0038 namespace pat {
0039 
0040   class MET : public PATObject<reco::MET> {
0041   public:
0042     /// default constructor
0043     MET();
0044     /// constructor from reco::MET
0045     MET(const reco::MET& aMET);
0046     /// constructor from a RefToBase to reco::MET (to be superseded by Ptr counterpart)
0047     MET(const edm::RefToBase<reco::MET>& aMETRef);
0048     /// constructor from a Ptr to a reco::MET
0049     MET(const edm::Ptr<reco::MET>& aMETRef);
0050     /// copy constructor
0051     MET(MET const&);
0052     /// constructor for corrected METs (keeping specific informations from src MET)
0053     MET(const reco::MET& corMET, const MET& srcMET);
0054     /// destructor
0055     ~MET() override;
0056 
0057     MET& operator=(MET const&);
0058 
0059     /// required reimplementation of the Candidate's clone method
0060     MET* clone() const override { return new MET(*this); }
0061 
0062     // ---- methods for generated MET link ----
0063     /// return the associated GenMET
0064     const reco::GenMET* genMET() const;
0065     /// set the associated GenMET
0066     void setGenMET(const reco::GenMET& gm);
0067 
0068     // ----- MET significance functions ----
0069     // set the MET Significance
0070     void setMETSignificance(const double& metSig);
0071     // get the MET significance
0072     double metSignificance() const;
0073     // set the MET sumPtUnclustered for MET Significance
0074     void setMETSumPtUnclustered(const double& sumPtUnclustered);
0075     // get the MET sumPtUnclustered
0076     double metSumPtUnclustered() const;
0077 
0078     // ---- methods for uncorrected MET ----
0079     // Methods not yet defined
0080     //float uncorrectedPt() const;
0081     //float uncorrectedPhi() const;
0082     //float uncorrectedSumEt() const;
0083 
0084     // ---- methods to know what the pat::MET was constructed from ----
0085     /// True if this pat::MET was made from a reco::CaloMET
0086     bool isCaloMET() const { return !caloMET_.empty(); }
0087     /// True if this pat::MET was made from a reco::pfMET
0088     bool isPFMET() const { return !pfMET_.empty(); }
0089     /// True if this pat::MET was NOT made from a reco::CaloMET nor a reco::pfMET
0090     bool isRecoMET() const { return (caloMET_.empty() && pfMET_.empty()); }
0091 
0092     // ---- methods for CaloMET specific stuff ----
0093     /// Returns the maximum energy deposited in ECAL towers
0094     double maxEtInEmTowers() const { return caloSpecific().MaxEtInEmTowers; }
0095     /// Returns the maximum energy deposited in HCAL towers
0096     double maxEtInHadTowers() const { return caloSpecific().MaxEtInHadTowers; }
0097     /// Returns the event hadronic energy fraction
0098     double etFractionHadronic() const { return caloSpecific().EtFractionHadronic; }
0099     /// Returns the event electromagnetic energy fraction
0100     double emEtFraction() const { return caloSpecific().EtFractionEm; }
0101     /// Returns the event hadronic energy in HB
0102     double hadEtInHB() const { return caloSpecific().HadEtInHB; }
0103     /// Returns the event hadronic energy in HO
0104     double hadEtInHO() const { return caloSpecific().HadEtInHO; }
0105     /// Returns the event hadronic energy in HE
0106     double hadEtInHE() const { return caloSpecific().HadEtInHE; }
0107     /// Returns the event hadronic energy in HF
0108     double hadEtInHF() const { return caloSpecific().HadEtInHF; }
0109     /// Returns the event electromagnetic energy in EB
0110     double emEtInEB() const { return caloSpecific().EmEtInEB; }
0111     /// Returns the event electromagnetic energy in EE
0112     double emEtInEE() const { return caloSpecific().EmEtInEE; }
0113     /// Returns the event electromagnetic energy extracted from HF
0114     double emEtInHF() const { return caloSpecific().EmEtInHF; }
0115     /// Returns the event MET Significance
0116     double caloMetSignificance() const { return caloSpecific().METSignificance; }
0117     /// Returns the event SET in HF+
0118     double CaloSETInpHF() const { return caloSpecific().CaloSETInpHF; }
0119     /// Returns the event SET in HF-
0120     double CaloSETInmHF() const { return caloSpecific().CaloSETInmHF; }
0121     /// Returns the event MET in HF+
0122     double CaloMETInpHF() const { return caloSpecific().CaloMETInpHF; }
0123     /// Returns the event MET in HF-
0124     double CaloMETInmHF() const { return caloSpecific().CaloMETInmHF; }
0125     /// Returns the event MET-phi in HF+
0126     double CaloMETPhiInpHF() const { return caloSpecific().CaloMETPhiInpHF; }
0127     /// Returns the event MET-phi in HF-
0128     double CaloMETPhiInmHF() const { return caloSpecific().CaloMETPhiInmHF; }
0129     /// accessor for the CaloMET-specific structure
0130     const SpecificCaloMETData& caloSpecific() const {
0131       if (!isCaloMET())
0132         throw cms::Exception("pat::MET") << "This pat::MET has not been made from a reco::CaloMET\n";
0133       return caloMET_[0];
0134     }
0135 
0136     // ---- methods for PFMET specific stuff ----
0137     double NeutralEMFraction() const { return pfSpecific().NeutralEMFraction; }
0138     double NeutralHadEtFraction() const { return pfSpecific().NeutralHadFraction; }
0139     double ChargedEMEtFraction() const { return pfSpecific().ChargedEMFraction; }
0140     double ChargedHadEtFraction() const { return pfSpecific().ChargedHadFraction; }
0141     double MuonEtFraction() const { return pfSpecific().MuonFraction; }
0142     double Type6EtFraction() const { return pfSpecific().Type6Fraction; }
0143     double Type7EtFraction() const { return pfSpecific().Type7Fraction; }
0144     /// accessor for the pfMET-specific structure
0145     const SpecificPFMETData& pfSpecific() const {
0146       if (!isPFMET())
0147         throw cms::Exception("pat::MET") << "This pat::MET has not been made from a reco::PFMET\n";
0148       return pfMET_[0];
0149     }
0150 
0151     // ---- members for MET corrections ----
0152     enum METUncertainty {
0153       JetResUp = 0,
0154       JetResDown = 1,
0155       JetEnUp = 2,
0156       JetEnDown = 3,
0157       MuonEnUp = 4,
0158       MuonEnDown = 5,
0159       ElectronEnUp = 6,
0160       ElectronEnDown = 7,
0161       TauEnUp = 8,
0162       TauEnDown = 9,
0163       UnclusteredEnUp = 10,
0164       UnclusteredEnDown = 11,
0165       PhotonEnUp = 12,
0166       PhotonEnDown = 13,
0167       NoShift = 14,
0168       METUncertaintySize = 15,
0169       JetResUpSmear = 16,
0170       JetResDownSmear = 17,
0171       METFullUncertaintySize = 18
0172     };
0173     enum METCorrectionLevel {
0174       Raw = 0,
0175       Type1 = 1,
0176       Type01 = 2,
0177       TypeXY = 3,
0178       Type1XY = 4,
0179       Type01XY = 5,
0180       Type1Smear = 6,
0181       Type01Smear = 7,
0182       Type1SmearXY = 8,
0183       Type01SmearXY = 9,
0184       RawCalo = 10,
0185       RawChs = 11,
0186       RawTrk = 12,
0187       RawDeepResponseTune = 13,
0188       RawDeepResolutionTune = 14,
0189       METCorrectionLevelSize = 15
0190     };
0191     enum METCorrectionType {
0192       None = 0,
0193       T1 = 1,
0194       T0 = 2,
0195       TXY = 3,
0196       TXYForRaw = 4,
0197       TXYForT01 = 5,
0198       TXYForT1Smear = 6,
0199       TXYForT01Smear = 7,
0200       Smear = 8,
0201       Calo = 9,
0202       Chs = 10,
0203       Trk = 11,
0204       DeepResponseTune = 12,
0205       DeepResolutionTune = 13,
0206       METCorrectionTypeSize = 14
0207     };
0208 
0209     struct Vector2 {
0210       double px, py;
0211       double pt() const { return hypotf(px, py); }
0212       double phi() const { return std::atan2(py, px); }
0213     };
0214 
0215     Vector2 shiftedP2(METUncertainty shift, METCorrectionLevel level = Type1) const;
0216     Vector shiftedP3(METUncertainty shift, METCorrectionLevel level = Type1) const;
0217     LorentzVector shiftedP4(METUncertainty shift, METCorrectionLevel level = Type1) const;
0218     double shiftedPx(METUncertainty shift, METCorrectionLevel level = Type1) const {
0219       return shiftedP2(shift, level).px;
0220     };
0221     double shiftedPy(METUncertainty shift, METCorrectionLevel level = Type1) const {
0222       return shiftedP2(shift, level).py;
0223     };
0224     double shiftedPt(METUncertainty shift, METCorrectionLevel level = Type1) const {
0225       return shiftedP2(shift, level).pt();
0226     };
0227     double shiftedPhi(METUncertainty shift, METCorrectionLevel level = Type1) const {
0228       return shiftedP2(shift, level).phi();
0229     };
0230     double shiftedSumEt(METUncertainty shift, METCorrectionLevel level = Type1) const;
0231 
0232     Vector2 corP2(METCorrectionLevel level = Type1) const;
0233     Vector corP3(METCorrectionLevel level = Type1) const;
0234     LorentzVector corP4(METCorrectionLevel level = Type1) const;
0235     double corPx(METCorrectionLevel level = Type1) const { return corP2(level).px; };
0236     double corPy(METCorrectionLevel level = Type1) const { return corP2(level).py; };
0237     double corPt(METCorrectionLevel level = Type1) const { return corP2(level).pt(); };
0238     double corPhi(METCorrectionLevel level = Type1) const { return corP2(level).phi(); };
0239     double corSumEt(METCorrectionLevel level = Type1) const;
0240 
0241     Vector2 uncorP2() const;
0242     Vector uncorP3() const;
0243     LorentzVector uncorP4() const;
0244     double uncorPx() const { return uncorP2().px; };
0245     double uncorPy() const { return uncorP2().py; };
0246     double uncorPt() const { return uncorP2().pt(); };
0247     double uncorPhi() const { return uncorP2().phi(); };
0248     double uncorSumEt() const;
0249 
0250     void setUncShift(double px, double py, double sumEt, METUncertainty shift, bool isSmeared = false);
0251     void setCorShift(double px, double py, double sumEt, METCorrectionType level);
0252 
0253     // specific method to fill and retrieve the caloMET quickly from miniAODs,
0254     //should be used by JetMET experts only for the beginning
0255     //of the runII, will be discarded later once we are sure
0256     //everything is fine
0257     Vector2 caloMETP2() const;
0258     double caloMETPt() const;
0259     double caloMETPhi() const;
0260     double caloMETSumEt() const;
0261 
0262     //Functions for backward compatibility with 74X samples.
0263     // allow access to 74X samples, transparent and not used in 75
0264     Vector2 shiftedP2_74x(METUncertainty shift, METCorrectionLevel level) const;
0265     Vector shiftedP3_74x(METUncertainty shift, METCorrectionLevel level) const;
0266     LorentzVector shiftedP4_74x(METUncertainty shift, METCorrectionLevel level) const;
0267     double shiftedSumEt_74x(METUncertainty shift, METCorrectionLevel level) const;
0268 
0269     class UnpackedMETUncertainty {
0270       // defined as C++ class so that I can change the packing without having to touch the code elsewhere
0271       // the compiler should anyway inline everything whenever possible
0272     public:
0273       UnpackedMETUncertainty() : dpx_(0), dpy_(0), dsumEt_(0) {}
0274       UnpackedMETUncertainty(float dpx, float dpy, float dsumEt) : dpx_(dpx), dpy_(dpy), dsumEt_(dsumEt) {}
0275       double dpx() const { return dpx_; }
0276       double dpy() const { return dpy_; }
0277       double dsumEt() const { return dsumEt_; }
0278       void set(float dpx, float dpy, float dsumEt) {
0279         dpx_ = dpx;
0280         dpy_ = dpy;
0281         dsumEt_ = dsumEt;
0282       }
0283       void add(float dpx, float dpy, float dsumEt) {
0284         dpx_ += dpx;
0285         dpy_ += dpy;
0286         dsumEt_ += dsumEt;
0287       }
0288 
0289     private:
0290       float dpx_, dpy_, dsumEt_;
0291     };
0292 
0293     /// this below should be private but Reflex doesn't like it
0294     class PackedMETUncertainty {
0295       // defined as C++ class so that I can change the packing without having to touch the code elsewhere
0296       // the compiler should anyway inline everything whenever possible
0297     public:
0298       PackedMETUncertainty() { pack(0, 0, 0); }
0299       PackedMETUncertainty(float dpx, float dpy, float dsumEt) { pack(dpx, dpy, dsumEt); }
0300       void set(float dpx, float dpy, float dsumEt) { pack(dpx, dpy, dsumEt); }
0301       UnpackedMETUncertainty unpack() const;
0302 
0303       float unpackDSumEt() const;
0304       float unpackDpx() const;
0305       float unpackDpy() const;
0306 
0307     protected:
0308       void pack(float dpx, float dpy, float dsumEt);
0309       uint16_t packedDpx_, packedDpy_, packedDSumEt_;
0310     };
0311 
0312   private:
0313     // ---- GenMET holder ----
0314     std::vector<reco::GenMET> genMET_;
0315     // ---- holder for CaloMET specific info ---
0316     std::vector<SpecificCaloMETData> caloMET_;
0317     // ---- holder for pfMET specific info ---
0318     std::vector<SpecificPFMETData> pfMET_;
0319 
0320     // MET significance
0321     double metSig_;
0322     // MET sumPtUnclustered for MET Significance
0323     double sumPtUnclustered_;
0324 
0325     UnpackedMETUncertainty findMETTotalShift(MET::METCorrectionLevel cor, MET::METUncertainty shift) const;
0326 
0327     std::map<MET::METCorrectionLevel, std::vector<MET::METCorrectionType> > corMap_;
0328     void initCorMap();
0329 
0330   protected:
0331     // ---- non-public correction utilities ----
0332     //kept for 74X backward-compatibility, not initialized and used in 75X
0333     std::vector<PackedMETUncertainty> uncertaintiesRaw_, uncertaintiesType1_, uncertaintiesType1p2_;
0334 
0335     std::vector<PackedMETUncertainty> uncertainties_;
0336     std::vector<PackedMETUncertainty> corrections_;
0337 
0338     PackedMETUncertainty caloPackedMet_;
0339   };
0340 
0341 }  // namespace pat
0342 
0343 #endif