diff --git a/DataFormats/PatCandidates/interface/Jet.h b/DataFormats/PatCandidates/interface/Jet.h index 3604ec8d83c26..44e6977c767bd 100644 --- a/DataFormats/PatCandidates/interface/Jet.h +++ b/DataFormats/PatCandidates/interface/Jet.h @@ -80,6 +80,7 @@ namespace pat { /// function, which should be non accessible to any other user friend class PATJetProducer; friend class PATJetSlimmer; + friend class PATJetUpdater; public: @@ -91,6 +92,10 @@ namespace pat { Jet(const edm::RefToBase & aJetRef); /// constructor from ref to reco::Jet Jet(const edm::Ptr & aJetRef); + /// constructure from ref to pat::Jet + Jet(const edm::RefToBase & aJetRef); + /// constructure from ref to pat::Jet + Jet(const edm::Ptr & aJetRef); /// destructor virtual ~Jet(); /// required reimplementation of the Candidate's clone method diff --git a/DataFormats/PatCandidates/src/Jet.cc b/DataFormats/PatCandidates/src/Jet.cc index ce92a7e6aa435..444f32fb9d465 100644 --- a/DataFormats/PatCandidates/src/Jet.cc +++ b/DataFormats/PatCandidates/src/Jet.cc @@ -47,6 +47,20 @@ Jet::Jet(const edm::RefToBase & aJetRef) : tryImportSpecific(*aJetRef); } +/// constructure from ref to pat::Jet +Jet::Jet(const edm::RefToBase & aJetRef) : + Jet(*aJetRef) +{ + refToOrig_ = edm::Ptr(aJetRef.id(), aJetRef.get(), aJetRef.key()); +} + +/// constructure from ref to pat::Jet +Jet::Jet(const edm::Ptr & aJetRef) : + Jet(*aJetRef) +{ + refToOrig_ = aJetRef; +} + std::ostream& reco::operator<<(std::ostream& out, const pat::Jet& obj) { diff --git a/PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.cc b/PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.cc index 2bdd94d4e385e..c1df1092cba54 100644 --- a/PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.cc +++ b/PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.cc @@ -7,6 +7,7 @@ #include "DataFormats/JetReco/interface/JPTJet.h" #include "DataFormats/JetReco/interface/CaloJet.h" #include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/PatCandidates/interface/Jet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.h" #include "JetMETCorrections/Objects/interface/JetCorrectionsRecord.h" @@ -158,7 +159,13 @@ JetCorrFactorsProducer::evaluate(edm::View::const_iterator& jet, cons } corrector->setJPTrawP4(p4); } - corrector->setJetEta(jet->eta()); corrector->setJetPt(jet->pt()); corrector->setJetE(jet->energy()); + //For PAT jets undo previous jet energy corrections + const Jet* patjet = dynamic_cast( &*jet ); + if( patjet ){ + corrector->setJetEta(patjet->correctedP4(0).eta()); corrector->setJetPt(patjet->correctedP4(0).pt()); corrector->setJetE(patjet->correctedP4(0).energy()); + } else { + corrector->setJetEta(jet->eta()); corrector->setJetPt(jet->pt()); corrector->setJetE(jet->energy()); + } if( emf_ && dynamic_cast(&*jet)){ corrector->setJetEMF(dynamic_cast(&*jet)->emEnergyFraction()); } diff --git a/PhysicsTools/PatAlgos/plugins/PATJetUpdater.cc b/PhysicsTools/PatAlgos/plugins/PATJetUpdater.cc new file mode 100755 index 0000000000000..ffd4e1a40abf6 --- /dev/null +++ b/PhysicsTools/PatAlgos/plugins/PATJetUpdater.cc @@ -0,0 +1,144 @@ +// + + +#include "PhysicsTools/PatAlgos/plugins/PATJetUpdater.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" + +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/Common/interface/Association.h" +#include "DataFormats/Candidate/interface/CandAssociation.h" + +#include "DataFormats/PatCandidates/interface/JetCorrFactors.h" + +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "FWCore/Utilities/interface/transform.h" + +#include +#include +#include + + +using namespace pat; + + +PATJetUpdater::PATJetUpdater(const edm::ParameterSet& iConfig) : + useUserData_(iConfig.exists("userData")) +{ + // initialize configurables + jetsToken_ = consumes >(iConfig.getParameter( "jetSource" )); + addJetCorrFactors_ = iConfig.getParameter( "addJetCorrFactors" ); + jetCorrFactorsTokens_ = edm::vector_transform(iConfig.getParameter >( "jetCorrFactorsSource" ), [this](edm::InputTag const & tag){return mayConsume >(tag);}); + // Check to see if the user wants to add user data + if ( useUserData_ ) { + userDataHelper_ = PATUserDataHelper(iConfig.getParameter("userData"), consumesCollector()); + } + // produces vector of jets + produces >(); +} + + +PATJetUpdater::~PATJetUpdater() { + +} + + +void PATJetUpdater::produce(edm::Event & iEvent, const edm::EventSetup & iSetup) +{ + // Get the vector of jets + edm::Handle > jets; + iEvent.getByToken(jetsToken_, jets); + + // read in the jet correction factors ValueMap + std::vector > jetCorrs; + if (addJetCorrFactors_) { + for ( size_t i = 0; i < jetCorrFactorsTokens_.size(); ++i ) { + edm::Handle > jetCorr; + iEvent.getByToken(jetCorrFactorsTokens_[i], jetCorr); + jetCorrs.push_back( *jetCorr ); + } + } + + // loop over jets + std::auto_ptr< std::vector > patJets ( new std::vector() ); + + bool first=true; // this is introduced to issue warnings only for the first jet + for (edm::View::const_iterator itJet = jets->begin(); itJet != jets->end(); itJet++) { + + // construct the Jet from the ref -> save ref to original object + unsigned int idx = itJet - jets->begin(); + edm::RefToBase jetRef = jets->refAt(idx); + edm::Ptr jetPtr = jets->ptrAt(idx); + Jet ajet(jetPtr); + + if (addJetCorrFactors_) { + unsigned int setindex = ajet.availableJECSets().size(); + // Undo previous jet energy corrections + ajet.setP4(ajet.correctedP4(0)); + // add additional JetCorrs to the jet + for ( unsigned int i=0; i levels = jetCorrs[0][jetRef].correctionLabels(); + if(std::find(levels.begin(), levels.end(), "L2L3Residual")!=levels.end()){ + ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L2L3Residual"), JetCorrFactors::NONE, setindex); + } + else if(std::find(levels.begin(), levels.end(), "L3Absolute")!=levels.end()){ + ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L3Absolute"), JetCorrFactors::NONE, setindex); + } + else{ + ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("Uncorrected"), JetCorrFactors::NONE, setindex); + if(first){ + edm::LogWarning("L3Absolute not found") << "L2L3Residual and L3Absolute are not part of the correction applied jetCorrFactors \n" + << "of module " << jetCorrs[0][jetRef].jecSet() << " jets will remain" + << " uncorrected."; first=false; + } + } + } + + if ( useUserData_ ) { + userDataHelper_.add( ajet, iEvent, iSetup ); + } + + patJets->push_back(ajet); + } + + // sort jets in pt + std::sort(patJets->begin(), patJets->end(), pTComparator_); + + // put genEvt in Event + iEvent.put(patJets); + +} + +// ParameterSet description for module +void PATJetUpdater::fillDescriptions(edm::ConfigurationDescriptions & descriptions) +{ + edm::ParameterSetDescription iDesc; + iDesc.setComment("PAT jet producer module"); + + // input source + iDesc.add("jetSource", edm::InputTag("no default"))->setComment("input collection"); + + // jet energy corrections + iDesc.add("addJetCorrFactors", true); + std::vector emptyVInputTags; + iDesc.add >("jetCorrFactorsSource", emptyVInputTags); + + // Check to see if the user wants to add user data + edm::ParameterSetDescription userDataPSet; + PATUserDataHelper::fillDescription(userDataPSet); + iDesc.addOptional("userData", userDataPSet); + + descriptions.add("PATJetUpdater", iDesc); +} + +#include "FWCore/Framework/interface/MakerMacros.h" + +DEFINE_FWK_MODULE(PATJetUpdater); diff --git a/PhysicsTools/PatAlgos/plugins/PATJetUpdater.h b/PhysicsTools/PatAlgos/plugins/PATJetUpdater.h new file mode 100644 index 0000000000000..449debec1a459 --- /dev/null +++ b/PhysicsTools/PatAlgos/plugins/PATJetUpdater.h @@ -0,0 +1,62 @@ +// +// + +#ifndef PhysicsTools_PatAlgos_PATJetUpdater_h +#define PhysicsTools_PatAlgos_PATJetUpdater_h + +/** + \class pat::PATJetUpdater PATJetUpdater.h "PhysicsTools/PatAlgos/interface/PATJetUpdater.h" + \brief Produces pat::Jet's + + The PATJetUpdater produces analysis-level pat::Jet's starting from + a collection of pat::Jet's and updates information. + + \author Andreas Hinzmann + \version $Id: PATJetUpdater.h,v 1.00 2014/03/11 18:13:54 srappocc Exp $ +*/ + + +#include "FWCore/Framework/interface/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/Common/interface/View.h" + +#include "CommonTools/Utils/interface/PtComparator.h" + +#include "DataFormats/PatCandidates/interface/Jet.h" + +#include "DataFormats/PatCandidates/interface/UserData.h" +#include "PhysicsTools/PatAlgos/interface/PATUserDataHelper.h" + +namespace pat { + + class PATJetUpdater : public edm::EDProducer { + + public: + + explicit PATJetUpdater(const edm::ParameterSet & iConfig); + ~PATJetUpdater(); + + virtual void produce(edm::Event & iEvent, const edm::EventSetup& iSetup) override; + + static void fillDescriptions(edm::ConfigurationDescriptions & descriptions); + + private: + + // configurables + edm::EDGetTokenT > jetsToken_; + bool addJetCorrFactors_; + std::vector > > jetCorrFactorsTokens_; + + GreaterByPt pTComparator_; + + bool useUserData_; + pat::PATUserDataHelper userDataHelper_; + + }; + + +} + +#endif diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cff.py b/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cff.py new file mode 100644 index 0000000000000..16d4fd7e70a40 --- /dev/null +++ b/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cff.py @@ -0,0 +1,15 @@ +import FWCore.ParameterSet.Config as cms + +from PhysicsTools.PatAlgos.recoLayer0.jetCorrections_cff import * +from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cfi import * + +patJetCorrFactorsUpdated = patJetCorrFactors.clone( + src = cms.InputTag("slimmedJets"), + primaryVertices = cms.InputTag("offlineSlimmedPrimaryVertices") + ) + +## for scheduled mode +makePatJetsUpdated = cms.Sequence( + patJetCorrFactorsUpdated * + patJetsUpdated + ) diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cfi.py b/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cfi.py new file mode 100644 index 0000000000000..210227c7161fa --- /dev/null +++ b/PhysicsTools/PatAlgos/python/producersLayer1/jetUpdater_cfi.py @@ -0,0 +1,33 @@ +import FWCore.ParameterSet.Config as cms + +patJetsUpdated = cms.EDProducer("PATJetUpdater", + # input + jetSource = cms.InputTag("slimmedJets"), + # add user data + userData = cms.PSet( + # add custom classes here + userClasses = cms.PSet( + src = cms.VInputTag('') + ), + # add doubles here + userFloats = cms.PSet( + src = cms.VInputTag('') + ), + # add ints here + userInts = cms.PSet( + src = cms.VInputTag('') + ), + # add candidate ptrs here + userCands = cms.PSet( + src = cms.VInputTag('') + ), + # add "inline" functions here + userFunctions = cms.vstring(), + userFunctionLabels = cms.vstring() + ), + # jet energy corrections + addJetCorrFactors = cms.bool(True), + jetCorrFactorsSource = cms.VInputTag(cms.InputTag("patJetCorrFactorsUpdated") ), +) + + diff --git a/PhysicsTools/PatAlgos/test/update_jets_from_MiniAOD.py b/PhysicsTools/PatAlgos/test/update_jets_from_MiniAOD.py new file mode 100644 index 0000000000000..c5f01917256d3 --- /dev/null +++ b/PhysicsTools/PatAlgos/test/update_jets_from_MiniAOD.py @@ -0,0 +1,61 @@ +# This configuration is an example that recalibrates the slimmedJets from MiniAOD +# and adds a new userfloat "oldJetMass" to it + +import FWCore.ParameterSet.Config as cms + +process = cms.Process("PATUPDATE") +process.load("FWCore.MessageLogger.MessageLogger_cfi") + +from PhysicsTools.PatAlgos.patInputFiles_cff import filesRelValTTbarPileUpMINIAODSIM +process.source = cms.Source("PoolSource", + fileNames = filesRelValTTbarPileUpMINIAODSIM +) + +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(100) ) + +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_mc') + +process.load("PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cff") + +# An example where the jet energy correction are updated to the GlobalTag given above +# and a usedfloat containing the previous mass of the jet is added +from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsCHSSoftDropMass +process.oldJetMass = ak8PFJetsCHSSoftDropMass.clone( + src = cms.InputTag("slimmedJets"), + matched = cms.InputTag("slimmedJets") ) +process.patJetsUpdated.userData.userFloats.src += ['oldJetMass'] +process.p = cms.Path( process.oldJetMass + process.makePatJetsUpdated ) + +# An example where the jet correction is undone +process.patJetCorrFactorsUndoJEC = process.patJetCorrFactorsUpdated.clone( + src = cms.InputTag("patJetsUpdated"), + levels = [] ) +process.patJetsUndoJEC = process.patJetsUpdated.clone( + jetSource = cms.InputTag("patJetsUpdated"), + jetCorrFactorsSource = cms.VInputTag(cms.InputTag("patJetCorrFactorsUndoJEC")) + ) +process.patJetsUndoJEC.userData.userFloats.src = [] +process.p += cms.Sequence( process.patJetCorrFactorsUndoJEC + process. patJetsUndoJEC ) + +# An example where the jet correction are reapplied +process.patJetCorrFactorsReapplyJEC = process.patJetCorrFactorsUpdated.clone( + src = cms.InputTag("patJetsUndoJEC"), + levels = ['L1FastJet', + 'L2Relative', + 'L3Absolute'] ) +process.patJetsReapplyJEC = process.patJetsUpdated.clone( + jetSource = cms.InputTag("patJetsUndoJEC"), + jetCorrFactorsSource = cms.VInputTag(cms.InputTag("patJetCorrFactorsReapplyJEC")) + ) +process.patJetsReapplyJEC.userData.userFloats.src = [] +process.p += cms.Sequence( process.patJetCorrFactorsReapplyJEC + process. patJetsReapplyJEC ) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string("patTupleUpdated.root"), + outputCommands = cms.untracked.vstring('keep *') + ) + +process.endpath = cms.EndPath(process.out) +