diff --git a/DataFormats/PatCandidates/interface/Jet.h b/DataFormats/PatCandidates/interface/Jet.h index 448344110938d..ded4c7d9174f7 100644 --- a/DataFormats/PatCandidates/interface/Jet.h +++ b/DataFormats/PatCandidates/interface/Jet.h @@ -177,6 +177,20 @@ namespace pat { void scaleEnergy(double fScale) override { scaleEnergy(fScale, "Unscaled"); } void scaleEnergy(double fScale, const std::string& level); + // Methods to work with a JER correction factor + // + // is the JER correction factor valid, i.e. has it been written using the saveJerFactor method + bool isJerFactorValid() const; + + // load the currently saved JER correction factor and check whether the factor was propely set before loading + float jerFactor() const; + + // save a JER correction factor + void setJerFactor(float jerFactor); + + // reset a saved JER correction factor + void resetJerFactor(); + private: /// index of the set of jec factors with given label; returns -1 if no set /// of jec factors exists with the given label @@ -650,6 +664,10 @@ namespace pat { // ---- id functions ---- reco::JetID jetID_; + // ---- JER correction factor ---- + float jerFactor_; + bool jerFactorValid_; + private: // ---- helper functions ---- diff --git a/DataFormats/PatCandidates/src/Jet.cc b/DataFormats/PatCandidates/src/Jet.cc index 9717faaee9dd7..6413489243916 100644 --- a/DataFormats/PatCandidates/src/Jet.cc +++ b/DataFormats/PatCandidates/src/Jet.cc @@ -10,23 +10,43 @@ using namespace pat; /// default constructor Jet::Jet() - : PATObject(reco::Jet()), embeddedCaloTowers_(false), embeddedPFCandidates_(false), jetCharge_(0.) {} + : PATObject(reco::Jet()), + embeddedCaloTowers_(false), + embeddedPFCandidates_(false), + jetCharge_(0.), + jerFactor_(0.0), + jerFactorValid_(false) {} /// constructor from a reco::Jet Jet::Jet(const reco::Jet& aJet) - : PATObject(aJet), embeddedCaloTowers_(false), embeddedPFCandidates_(false), jetCharge_(0.0) { + : PATObject(aJet), + embeddedCaloTowers_(false), + embeddedPFCandidates_(false), + jetCharge_(0.0), + jerFactor_(0.0), + jerFactorValid_(false) { tryImportSpecific(aJet); } /// constructor from ref to reco::Jet Jet::Jet(const edm::Ptr& aJetRef) - : PATObject(aJetRef), embeddedCaloTowers_(false), embeddedPFCandidates_(false), jetCharge_(0.0) { + : PATObject(aJetRef), + embeddedCaloTowers_(false), + embeddedPFCandidates_(false), + jetCharge_(0.0), + jerFactor_(0.0), + jerFactorValid_(false) { tryImportSpecific(*aJetRef); } /// constructor from ref to reco::Jet Jet::Jet(const edm::RefToBase& aJetRef) - : PATObject(aJetRef), embeddedCaloTowers_(false), embeddedPFCandidates_(false), jetCharge_(0.0) { + : PATObject(aJetRef), + embeddedCaloTowers_(false), + embeddedPFCandidates_(false), + jetCharge_(0.0), + jerFactor_(0.0), + jerFactorValid_(false) { tryImportSpecific(*aJetRef); } @@ -596,3 +616,36 @@ void Jet::addSubjets(pat::JetPtrCollection const& pieces, std::string const& lab subjetCollections_.push_back(pieces); subjetLabels_.push_back(label); } + +// is the JER correction factor valid, i.e. has it been written using the saveJerFactor method +bool Jet::isJerFactorValid() const { return jerFactorValid_; } + +// load the currently saved JER correction factor and check whether the factor was propely set before loading +float Jet::jerFactor() const { + if (isJerFactorValid()) { + return jerFactor_; + } else { + throw cms::Exception( + "Loading JER factor of a pat::Jet, but it was not set properly before. You need to save a JER factor first, " + "see methods in pat::Jet."); + return 0.0; + } +} + +// save a JER correction factor +void Jet::setJerFactor(float jerFactor) { + if (isJerFactorValid()) { + throw cms::Exception( + "Setting a JER factor although the JER factor was already set before." + "Please reset the JER factor before setting a new one, see methods in pat::Jet"); + } else { + jerFactor_ = jerFactor; + jerFactorValid_ = true; + } +} + +// reset a saved JER correction factor +void Jet::resetJerFactor() { + jerFactor_ = 0.0; + jerFactorValid_ = false; +} diff --git a/DataFormats/PatCandidates/src/MET.cc b/DataFormats/PatCandidates/src/MET.cc index a50f2e2c5ba5e..33d7465a3a6f5 100644 --- a/DataFormats/PatCandidates/src/MET.cc +++ b/DataFormats/PatCandidates/src/MET.cc @@ -342,9 +342,9 @@ void MET::setUncShift(double px, double py, double sumEt, METUncertainty shift, //changing reference to only get the uncertainty shift and not the smeared one // which is performed independently shift = (MET::METUncertainty)(METUncertainty::METUncertaintySize + shift + 1); - const PackedMETUncertainty &ref = uncertainties_[METUncertainty::NoShift]; + const PackedMETUncertainty &ref = corrections_[METCorrectionType::Smear]; uncertainties_[shift].set( - px + ref.dpx() - this->px(), py + ref.dpy() - this->py(), sumEt + ref.dsumEt() - this->sumEt()); + px - ref.dpx() - this->px(), py - ref.dpy() - this->py(), sumEt - ref.dsumEt() - this->sumEt()); } else uncertainties_[shift].set(px - this->px(), py - this->py(), sumEt - this->sumEt()); } diff --git a/DataFormats/PatCandidates/src/classes_def_objects.xml b/DataFormats/PatCandidates/src/classes_def_objects.xml index 2b98aef02aab2..d45e82b9fbb20 100644 --- a/DataFormats/PatCandidates/src/classes_def_objects.xml +++ b/DataFormats/PatCandidates/src/classes_def_objects.xml @@ -248,7 +248,8 @@ newObj->setPflowIsolationVariables(pfIsoVar);]]> - + + diff --git a/JetMETCorrections/Type1MET/interface/PFJetMETcorrInputProducerT.h b/JetMETCorrections/Type1MET/interface/PFJetMETcorrInputProducerT.h index 6314ef9d80119..238d376b20496 100644 --- a/JetMETCorrections/Type1MET/interface/PFJetMETcorrInputProducerT.h +++ b/JetMETCorrections/Type1MET/interface/PFJetMETcorrInputProducerT.h @@ -61,6 +61,17 @@ namespace PFJetMETcorrInputProducer_namespace { reco::Candidate::LorentzVector operator()(const T& jet) const { return jet.p4(); } }; + // functor to retrieve JER factors of jets + // for pat::Jet a previously saved JER factor is retrieved + // general template just returns 1 + // specialized template for pat::Jet returns desired JER correction value if available + template + class RetrieveJerT { + public: + RetrieveJerT() {} + float operator()(const T& jet) const { return 1.0; } + }; + } // namespace PFJetMETcorrInputProducer_namespace template @@ -196,6 +207,9 @@ class PFJetMETcorrInputProducerT : public edm::stream::EDProducer<> { corrJetP4 = jetCorrExtractor_(jet, jetCorrLabel_.label(), jetCorrEtaMax_, &rawJetP4); else corrJetP4 = jetCorrExtractor_(jet, jetCorr.product(), jetCorrEtaMax_, &rawJetP4); + // retrieve JER factors in case of pat::Jets (done via specialized template defined for pat::Jets) and apply it + const static PFJetMETcorrInputProducer_namespace::RetrieveJerT retrieveJER{}; + corrJetP4 *= retrieveJER(jet); if (corrJetP4.pt() > type1JetPtThreshold_) { reco::Candidate::LorentzVector rawJetP4offsetCorr = rawJetP4; diff --git a/PhysicsTools/PatUtils/interface/SmearedJetProducerT.h b/PhysicsTools/PatUtils/interface/SmearedJetProducerT.h index 2d2ee29ab70af..cd9e00f6fd2f9 100644 --- a/PhysicsTools/PatUtils/interface/SmearedJetProducerT.h +++ b/PhysicsTools/PatUtils/interface/SmearedJetProducerT.h @@ -26,6 +26,7 @@ #include "DataFormats/JetReco/interface/GenJet.h" #include "DataFormats/JetReco/interface/GenJetCollection.h" #include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/PatCandidates/interface/Jet.h" #include "JetMETCorrections/Modules/interface/JetResolution.h" @@ -93,6 +94,21 @@ namespace pat { }; }; // namespace pat +namespace SmearedJetProducer_namespace { + // template function to apply JER + template + void SmearJet(T& jet, float smearfactor) { + jet.scaleEnergy(smearfactor); + } + // template specialization for pat::Jets to store the JER factor + template <> + inline void SmearJet(pat::Jet& jet, float smearfactor) { + jet.scaleEnergy(smearfactor); + jet.resetJerFactor(); + jet.setJerFactor(smearfactor); + } +} // namespace SmearedJetProducer_namespace + template class SmearedJetProducerT : public edm::stream::EDProducer<> { using JetCollection = std::vector; @@ -288,7 +304,7 @@ class SmearedJetProducerT : public edm::stream::EDProducer<> { } T smearedJet = jet; - smearedJet.scaleEnergy(smearFactor); + SmearedJetProducer_namespace::SmearJet(smearedJet, smearFactor); if (m_debug) { std::cout << "smeared jet (" << smearFactor << "): pt: " << smearedJet.pt() << " eta: " << smearedJet.eta() diff --git a/PhysicsTools/PatUtils/plugins/PATPFJetMETcorrInputProducer.cc b/PhysicsTools/PatUtils/plugins/PATPFJetMETcorrInputProducer.cc index a629a44bbe00a..a2ccce81dc4fd 100644 --- a/PhysicsTools/PatUtils/plugins/PATPFJetMETcorrInputProducer.cc +++ b/PhysicsTools/PatUtils/plugins/PATPFJetMETcorrInputProducer.cc @@ -16,17 +16,41 @@ namespace PFJetMETcorrInputProducer_namespace { bool isPatJet(const pat::Jet& jet) const { return true; } }; + // template specialization for pat::Jet + // remove JER correction if JER factor was saved previously template <> class RawJetExtractorT { public: RawJetExtractorT() {} reco::Candidate::LorentzVector operator()(const pat::Jet& jet) const { + reco::Candidate::LorentzVector uncorrected_jet; if (jet.jecSetsAvailable()) - return jet.correctedP4("Uncorrected"); + uncorrected_jet = jet.correctedP4("Uncorrected"); else - return jet.p4(); + uncorrected_jet = jet.p4(); + // remove JER correction factor from pat::Jets + if (jet.isJerFactorValid()) { + uncorrected_jet *= (1.0 / jet.jerFactor()); + } + return uncorrected_jet; } }; + + // template specialization for pat::Jets + // retrieve JER factor if it was saved previously + // otherwise just return 1 + template <> + class RetrieveJerT { + public: + RetrieveJerT() {} + float operator()(const pat::Jet& jet) const { + if (jet.isJerFactorValid()) { + return jet.jerFactor(); + } else + return 1.0; + } + }; + } // namespace PFJetMETcorrInputProducer_namespace typedef PFJetMETcorrInputProducerT PATPFJetMETcorrInputProducer;