diff --git a/PhysicsTools/NanoAOD/plugins/JetPFConstituentVarProducer.cc b/PhysicsTools/NanoAOD/plugins/JetPFConstituentVarProducer.cc new file mode 100644 index 0000000000000..88e13cab48f25 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/JetPFConstituentVarProducer.cc @@ -0,0 +1,264 @@ +#include +#include + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" +#include "DataFormats/Candidate/interface/CandidateFwd.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +template +class JetPFConstituentVarProducer : public edm::stream::EDProducer<> { +public: + explicit JetPFConstituentVarProducer(const edm::ParameterSet&); + ~JetPFConstituentVarProducer() override; + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + void PutValueMapInEvent(edm::Event&, const edm::Handle>&, const std::vector&, std::string); + + edm::EDGetTokenT> jet_token_; + edm::EDGetTokenT> puppi_value_map_token_; + + const bool fallback_puppi_weight_; + bool use_puppi_value_map_; +}; + +// +// constructors and destructor +// +template +JetPFConstituentVarProducer::JetPFConstituentVarProducer(const edm::ParameterSet& iConfig) + : jet_token_(consumes>(iConfig.getParameter("jets"))), + fallback_puppi_weight_(iConfig.getParameter("fallback_puppi_weight")), + use_puppi_value_map_(false) { + // + // Puppi Value Map + // + const auto& puppi_value_map_tag = iConfig.getParameter("puppi_value_map"); + if (!puppi_value_map_tag.label().empty()) { + puppi_value_map_token_ = consumes>(puppi_value_map_tag); + use_puppi_value_map_ = true; + } + produces>("leadConstNeHadEF"); + produces>("leadConstChHadEF"); + produces>("leadConstPhotonEF"); + produces>("leadConstElectronEF"); + produces>("leadConstMuonEF"); + produces>("leadConstHFHADEF"); + produces>("leadConstHFEMEF"); + produces>("leadConstNeHadPuppiWeight"); + produces>("leadConstChHadPuppiWeight"); + produces>("leadConstPhotonPuppiWeight"); + produces>("leadConstElectronPuppiWeight"); + produces>("leadConstMuonPuppiWeight"); + produces>("leadConstHFHADPuppiWeight"); + produces>("leadConstHFEMPuppiWeight"); +} + +template +JetPFConstituentVarProducer::~JetPFConstituentVarProducer() {} + +template +void JetPFConstituentVarProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // Input jets + auto jets = iEvent.getHandle(jet_token_); + + // Get puppi value map + edm::Handle> puppi_value_map_; + if (use_puppi_value_map_) { + iEvent.getByToken(puppi_value_map_token_, puppi_value_map_); + } + + std::vector jet_leadConstNeHadEF(jets->size(), 0.f); + std::vector jet_leadConstNeHadPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstChHadEF(jets->size(), 0.f); + std::vector jet_leadConstChHadPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstPhotonEF(jets->size(), 0.f); + std::vector jet_leadConstPhotonPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstElectronEF(jets->size(), 0.f); + std::vector jet_leadConstElectronPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstMuonEF(jets->size(), 0.f); + std::vector jet_leadConstMuonPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstHFHADEF(jets->size(), 0.f); + std::vector jet_leadConstHFHADPuppiWeight(jets->size(), 0.f); + + std::vector jet_leadConstHFEMEF(jets->size(), 0.f); + std::vector jet_leadConstHFEMPuppiWeight(jets->size(), 0.f); + + // Loop over jet + for (std::size_t jet_idx = 0; jet_idx < jets->size(); jet_idx++) { + const auto& jet = (*jets)[jet_idx]; + + float jet_energy_raw = jet.energy(); + if constexpr (std::is_same::value) { + jet_energy_raw = jet.correctedJet(0).energy(); + } + + reco::CandidatePtr leadConstNeHad; + reco::CandidatePtr leadConstChHad; + reco::CandidatePtr leadConstPhoton; + reco::CandidatePtr leadConstElectron; + reco::CandidatePtr leadConstMuon; + reco::CandidatePtr leadConstHFHAD; + reco::CandidatePtr leadConstHFEM; + + float leadConstNeHadPuppiWeight = 1.f; + float leadConstChHadPuppiWeight = 1.f; + float leadConstPhotonPuppiWeight = 1.f; + float leadConstElectronPuppiWeight = 1.f; + float leadConstMuonPuppiWeight = 1.f; + float leadConstHFHADPuppiWeight = 1.f; + float leadConstHFEMPuppiWeight = 1.f; + + // + // Loop over jet constituents + // + for (const reco::CandidatePtr& dau : jet.daughterPtrVector()) { + float puppiw = 1.f; + + // + // Get Puppi weight from ValueMap, if provided. + // + if (use_puppi_value_map_) { + puppiw = (*puppi_value_map_)[dau]; + } else if (!fallback_puppi_weight_) { + throw edm::Exception(edm::errors::InvalidReference, "PUPPI value map missing") + << "use fallback_puppi_weight option to use " << puppiw << " for cand as default"; + } + + // + // Find the highest energy constituents for each PF type + // + if (abs(dau->pdgId()) == 130) { + if (leadConstNeHad.isNull() || + (puppiw * dau->energy() > leadConstNeHadPuppiWeight * leadConstNeHad->energy())) { + leadConstNeHad = dau; + leadConstNeHadPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 211) { + if (leadConstChHad.isNull() || + (puppiw * dau->energy() > leadConstChHadPuppiWeight * leadConstChHad->energy())) { + leadConstChHad = dau; + leadConstChHadPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 22) { + if (leadConstPhoton.isNull() || + (puppiw * dau->energy() > leadConstPhotonPuppiWeight * leadConstPhoton->energy())) { + leadConstPhoton = dau; + leadConstPhotonPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 11) { + if (leadConstElectron.isNull() || + (puppiw * dau->energy() > leadConstElectronPuppiWeight * leadConstElectron->energy())) { + leadConstElectron = dau; + leadConstElectronPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 13) { + if (leadConstMuon.isNull() || (puppiw * dau->energy() > leadConstMuonPuppiWeight * leadConstMuon->energy())) { + leadConstMuon = dau; + leadConstMuonPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 1) { + if (leadConstHFHAD.isNull() || + (puppiw * dau->energy() > leadConstHFHADPuppiWeight * leadConstHFHAD->energy())) { + leadConstHFHAD = dau; + leadConstHFHADPuppiWeight = puppiw; + } + } else if (abs(dau->pdgId()) == 2) { + if (leadConstHFEM.isNull() || (puppiw * dau->energy() > leadConstHFEMPuppiWeight * leadConstHFEM->energy())) { + leadConstHFEM = dau; + leadConstHFEMPuppiWeight = puppiw; + } + } + } // End of Jet Constituents Loop + + if (leadConstNeHad.isNonnull()) { + jet_leadConstNeHadEF[jet_idx] = (leadConstNeHad->energy() * leadConstNeHadPuppiWeight) / jet_energy_raw; + jet_leadConstNeHadPuppiWeight[jet_idx] = leadConstNeHadPuppiWeight; + } + if (leadConstChHad.isNonnull()) { + jet_leadConstChHadEF[jet_idx] = (leadConstChHad->energy() * leadConstChHadPuppiWeight) / jet_energy_raw; + jet_leadConstChHadPuppiWeight[jet_idx] = leadConstChHadPuppiWeight; + } + if (leadConstPhoton.isNonnull()) { + jet_leadConstPhotonEF[jet_idx] = (leadConstPhoton->energy() * leadConstPhotonPuppiWeight) / jet_energy_raw; + jet_leadConstPhotonPuppiWeight[jet_idx] = leadConstPhotonPuppiWeight; + } + if (leadConstElectron.isNonnull()) { + jet_leadConstElectronEF[jet_idx] = (leadConstElectron->energy() * leadConstElectronPuppiWeight) / jet_energy_raw; + jet_leadConstElectronPuppiWeight[jet_idx] = leadConstElectronPuppiWeight; + } + if (leadConstMuon.isNonnull()) { + jet_leadConstMuonEF[jet_idx] = (leadConstMuon->energy() * leadConstMuonPuppiWeight) / jet_energy_raw; + jet_leadConstMuonPuppiWeight[jet_idx] = leadConstMuonPuppiWeight; + } + if (leadConstHFHAD.isNonnull()) { + jet_leadConstHFHADEF[jet_idx] = (leadConstHFHAD->energy() * leadConstHFHADPuppiWeight) / jet_energy_raw; + jet_leadConstHFHADPuppiWeight[jet_idx] = leadConstHFHADPuppiWeight; + } + if (leadConstHFEM.isNonnull()) { + jet_leadConstHFEMEF[jet_idx] = (leadConstHFEM->energy() * leadConstHFEMPuppiWeight) / jet_energy_raw; + jet_leadConstHFEMPuppiWeight[jet_idx] = leadConstHFEMPuppiWeight; + } + } + + PutValueMapInEvent(iEvent, jets, jet_leadConstNeHadEF, "leadConstNeHadEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstNeHadPuppiWeight, "leadConstNeHadPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstChHadEF, "leadConstChHadEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstChHadPuppiWeight, "leadConstChHadPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstPhotonEF, "leadConstPhotonEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstPhotonPuppiWeight, "leadConstPhotonPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstElectronEF, "leadConstElectronEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstElectronPuppiWeight, "leadConstElectronPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstMuonEF, "leadConstMuonEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstMuonPuppiWeight, "leadConstMuonPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstHFHADEF, "leadConstHFHADEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstHFHADPuppiWeight, "leadConstHFHADPuppiWeight"); + + PutValueMapInEvent(iEvent, jets, jet_leadConstHFEMEF, "leadConstHFEMEF"); + PutValueMapInEvent(iEvent, jets, jet_leadConstHFEMPuppiWeight, "leadConstHFEMPuppiWeight"); +} +template +void JetPFConstituentVarProducer::PutValueMapInEvent(edm::Event& iEvent, + const edm::Handle>& coll, + const std::vector& vec_var, + std::string VMName) { + std::unique_ptr> VM(new edm::ValueMap()); + edm::ValueMap::Filler fillerVM(*VM); + fillerVM.insert(coll, vec_var.begin(), vec_var.end()); + fillerVM.fill(); + iEvent.put(std::move(VM), VMName); +} + +template +void JetPFConstituentVarProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("jets", edm::InputTag("finalJetsPuppi")); + desc.add("puppi_value_map", edm::InputTag("packedpuppi")); + desc.add("fallback_puppi_weight", false); + descriptions.addWithDefaultLabel(desc); +} + +typedef JetPFConstituentVarProducer PatJetPFConstituentVarProducer; +DEFINE_FWK_MODULE(PatJetPFConstituentVarProducer); diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index ccc4ac843427a..46f3d3f53d12b 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -37,7 +37,7 @@ def expandNanoMapping(seqList, mapping, key): 'JME': {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/custom_jme_cff.PrepJMECustomNanoAOD'}, 'JMErePuppi': {'sequence': '@PHYS', - 'customize': '@PHYS+@JME+PhysicsTools/NanoAOD/custom_jme_cff.RecomputePuppiWeightsAndMET'}, + 'customize': '@PHYS+@JME+PhysicsTools/NanoAOD/custom_jme_cff.RecomputePuppiWeightsMETAK8'}, # L1 DPG (standalone with full calo TP info, L1T reemulation customization) 'L1DPG' : {'sequence': 'DPGAnalysis/L1TNanoAOD/l1tNano_cff.l1tNanoSequence', 'customize': ','.join(['PhysicsTools/NanoAOD/l1trig_cff.nanoL1TrigObjCustomizeFull', diff --git a/PhysicsTools/NanoAOD/python/custom_jme_cff.py b/PhysicsTools/NanoAOD/python/custom_jme_cff.py index 8c57d9ff5683b..28aca19965ff3 100644 --- a/PhysicsTools/NanoAOD/python/custom_jme_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_jme_cff.py @@ -37,24 +37,6 @@ ) bTagDiscriminatorsForAK4 = bTagDiscriminatorsForAK4.foo.value() -from RecoBTag.ONNXRuntime.pfDeepBoostedJet_cff import _pfDeepBoostedJetTagsAll -from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetJetTagsAll - -btagHbb = ['pfBoostedDoubleSecondaryVertexAK8BJetTags'] -btagDDX = [ - 'pfDeepDoubleBvLJetTags:probHbb', - 'pfDeepDoubleCvLJetTags:probHcc', - 'pfDeepDoubleCvBJetTags:probHcc', - 'pfMassIndependentDeepDoubleBvLJetTags:probHbb', - 'pfMassIndependentDeepDoubleCvLJetTags:probHcc', - 'pfMassIndependentDeepDoubleCvBJetTags:probHcc' -] -btagDDXV2 = [ - 'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb', - 'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc', - 'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc' -] - # # By default, these collections are saved in NanoAODs: # - ak4gen (GenJet in NanoAOD), slimmedGenJets in MiniAOD @@ -207,9 +189,9 @@ btagUParTAK4UDG = Var("?pt>15? bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:probu')+bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:probd')+bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:probg'):-1",float,precision=10,doc="UnifiedParTAK4 u+d+g raw score"), btagUParTAK4QvG = Var("?pt>15 && bDiscriminator('pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:QvsG')>0?bDiscriminator('pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:QvsG'):-1",float,precision=10,doc="UnifiedParTAK4 q (uds) vs. g"), btagUParTAK4TauVJet = Var("?pt>15 && bDiscriminator('pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:TauVsJet')>0?bDiscriminator('pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:TauVsJet'):-1",float,precision=10,doc="UnifiedParTAK4 tau vs. jet"), - UParTAK4RegPtRawCorr = Var("?pt>15 && bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptcorr')>0?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptcorr'):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware visible pT regression (no neutrinos), correction relative to raw jet pT"), - UParTAK4RegPtRawCorrNeutrino = Var("?pt>15 && bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptnu')>0?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptnu'):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware pT regression neutrino correction, relative to visible. To apply full regression, multiply raw jet pT by both UParTAK4RegPtRawCorr and UParTAK4RegPtRawCorrNeutrino."), - UParTAK4RegPtRawRes = Var("?pt>15 && 0.5*(bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreshigh')-bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreslow')) > 0?0.5*(bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreshigh')-bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreslow')):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware jet pT resolution estimator, (q84 - q16)/2"), + UParTAK4RegPtRawCorr = Var("?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptcorr')>0?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptcorr'):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware visible pT regression (no neutrinos), correction relative to raw jet pT"), + UParTAK4RegPtRawCorrNeutrino = Var("?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptnu')>0?bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptnu'):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware pT regression neutrino correction, relative to visible. To apply full regression, multiply raw jet pT by both UParTAK4RegPtRawCorr and UParTAK4RegPtRawCorrNeutrino."), + UParTAK4RegPtRawRes = Var("?0.5*(bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreshigh')-bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreslow')) > 0?0.5*(bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreshigh')-bDiscriminator('pfUnifiedParticleTransformerAK4JetTags:ptreslow')):-1",float,precision=10,doc="UnifiedParTAK4 universal flavor-aware jet pT resolution estimator, (q84 - q16)/2"), ) PARTICLENETAK4VARS = cms.PSet( particleNetAK4_B = Var("?(pt>=15)?bDiscriminator('pfParticleNetAK4DiscriminatorsJetTags:BvsAll'):-1",float,doc="ParticleNetAK4 tagger b vs all (udsg, c) discriminator",precision=10), @@ -661,6 +643,49 @@ def ReclusterAK4PuppiJets(proc, recoJA, runOnMC): proc.jetPuppiTable.variables.elMultiplicity = PFJETVARS.elMultiplicity proc.jetPuppiTable.variables.phoMultiplicity = PFJETVARS.phoMultiplicity + # + # + # + + from PhysicsTools.NanoAOD.patJetPFConstituentVarProducer_cfi import patJetPFConstituentVarProducer + jetPFConstituentVarName = "jetPFConstituentVar{}".format(jetName) + setattr(proc, jetPFConstituentVarName, patJetPFConstituentVarProducer.clone( + jets = "updatedJetsPuppi", + puppi_value_map = 'packedpuppi', + fallback_puppi_weight = False, + ) + ) + proc.jetPuppiTask.add(getattr(proc, jetPFConstituentVarName)) + proc.updatedJetsPuppiWithUserData.userFloats.leadConstNeHadEF = cms.InputTag(jetPFConstituentVarName+':leadConstNeHadEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstChHadEF = cms.InputTag(jetPFConstituentVarName+':leadConstChHadEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstPhotonEF = cms.InputTag(jetPFConstituentVarName+':leadConstPhotonEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstElectronEF = cms.InputTag(jetPFConstituentVarName+':leadConstElectronEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstMuonEF = cms.InputTag(jetPFConstituentVarName+':leadConstMuonEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstHFHADEF = cms.InputTag(jetPFConstituentVarName+':leadConstHFHADEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstHFEMEF = cms.InputTag(jetPFConstituentVarName+':leadConstHFEMEF') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstNeHadPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstNeHadPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstChHadPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstChHadPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstPhotonPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstPhotonPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstElectronPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstElectronPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstMuonPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstMuonPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstHFHADPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstHFHADPuppiWeight') + proc.updatedJetsPuppiWithUserData.userFloats.leadConstHFEMPuppiWeight = cms.InputTag(jetPFConstituentVarName+':leadConstHFEMPuppiWeight') + proc.jetPuppiTable.variables.leadConstNeHadEF = Var("userFloat('leadConstNeHadEF')",float,doc="Leading PF neutral hadron constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstChHadEF = Var("userFloat('leadConstChHadEF')",float,doc="Leading PF charged hadron constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstPhotonEF = Var("userFloat('leadConstPhotonEF')",float,doc="Leading PF photon constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstElectronEF = Var("userFloat('leadConstElectronEF')",float,doc="Leading PF electron constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstMuonEF = Var("userFloat('leadConstMuonEF')",float,doc="Leading PF muon constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstHFHADEF = Var("userFloat('leadConstHFHADEF')",float,doc="Leading PF HF HAD constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstHFEMEF = Var("userFloat('leadConstHFEMEF')",float,doc="Leading PF HF EM constituent energy fraction w.r.t jet raw energy",precision=10) + proc.jetPuppiTable.variables.leadConstNeHadPuppiWeight = Var("userFloat('leadConstNeHadPuppiWeight')",float,doc="Leading PF neutral hadron constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstChHadPuppiWeight = Var("userFloat('leadConstChHadPuppiWeight')",float,doc="Leading PF charged hadron constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstPhotonPuppiWeight = Var("userFloat('leadConstPhotonPuppiWeight')",float,doc="Leading PF photon constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstElectronPuppiWeight = Var("userFloat('leadConstElectronPuppiWeight')",float,doc="Leading PF electron constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstMuonPuppiWeight = Var("userFloat('leadConstMuonPuppiWeight')",float,doc="Leading PF muon constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstHFHADPuppiWeight = Var("userFloat('leadConstHFHADPuppiWeight')",float,doc="Leading PF HF HAD constituent puppi weight",precision=10) + proc.jetPuppiTable.variables.leadConstHFEMPuppiWeight = Var("userFloat('leadConstHFEMPuppiWeight')",float,doc="Leading PF HF EM constituent puppi weight",precision=10) + + # # Add Pileup Jet ID for Puppi jets # @@ -869,6 +894,12 @@ def ReclusterAK4CHSJets(proc, recoJA, runOnMC): for varNames in proc.jetTable.variables.parameterNames_(): if "btagDeepFlav" in varNames or "btagRobustParT" in varNames or "btagUParT" in varNames: delattr(proc.jetTable.variables, varNames) + if "UParTAK4Reg" in varNames: + delattr(proc.jetTable.variables, varNames) + if "svIdx" in varNames or "muonIdx" in varNames: + delattr(proc.jetTable.variables, varNames) + if "nElectrons" in varNames or "nMuons" in varNames or "nSVs" in varNames: + delattr(proc.jetTable.variables, varNames) proc.jetTable.variables.btagPNetB = Var("?pt>15 && bDiscriminator('pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags:BvsAll')>0?bDiscriminator('pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags:BvsAll'):-1",float,precision=10,doc="ParticleNet b vs. udscg") proc.jetTable.variables.btagPNetCvL = Var("?pt>15 && bDiscriminator('pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags:CvsL')>0?bDiscriminator('pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags:CvsL'):-1",float,precision=10,doc="ParticleNet c vs. udsg") @@ -1237,12 +1268,65 @@ def RecomputePuppiMET(proc): ) return proc +#=========================================================================== +# +# Functions to setup recomputation of Puppi weights and recluster PuppiMET +# and AK8 Puppi jets (slimmedJetsAK8) +# +#=========================================================================== def RecomputePuppiWeightsAndMET(proc): """ - Recompute Puppi weights PuppiMET. + Recompute Puppi weights and PuppiMET. """ + proc = RecomputePuppiWeights(proc) proc = RecomputePuppiMET(proc) + + return proc + +def RecomputePuppiWeightsMETAK8(proc): + """ + Recompute Puppi weights and PuppiMET and rebuild slimmedJetsAK8. + """ + runOnMC=True + if hasattr(proc,"NANOEDMAODoutput") or hasattr(proc,"NANOAODoutput"): + runOnMC = False + + proc = RecomputePuppiWeightsAndMET(proc) + + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetJetTagsAll as pfParticleNetJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetMassRegressionOutputs as pfParticleNetMassRegressionOutputs + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetMassCorrelatedJetTagsAll as pfParticleNetMassCorrelatedJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import _pfParticleNetFromMiniAODAK8JetTagsAll as pfParticleNetFromMiniAODAK8JetTagsAll + + btagDiscriminatorsAK8 = cms.PSet(names = cms.vstring( + pfParticleNetMassCorrelatedJetTagsAll+ + pfParticleNetFromMiniAODAK8JetTagsAll+ + pfParticleNetJetTagsAll+ + pfParticleNetMassRegressionOutputs + ) + ) + + btagDiscriminatorsAK8Subjets = cms.PSet(names = cms.vstring( + 'pfDeepFlavourJetTags:probb', + 'pfDeepFlavourJetTags:probbb', + 'pfDeepFlavourJetTags:problepb', + 'pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:BvsAll' + ) + ) + + run3_nanoAOD_pre142X.toModify(btagDiscriminatorsAK8Subjets, + names = cms.vstring('pfDeepCSVJetTags:probb','pfDeepCSVJetTags:probbb') + ) + + from PhysicsTools.PatAlgos.tools.puppiJetMETReclusteringFromMiniAOD_cff import setupPuppiAK4AK8METReclustering + proc = setupPuppiAK4AK8METReclustering(proc, runOnMC=runOnMC, useExistingWeights=False, + reclusterAK4MET=False, # Already setup to recluster AK4 Puppi jets and PuppiMET + reclusterAK8=True, + btagDiscriminatorsAK8=btagDiscriminatorsAK8, + btagDiscriminatorsAK8Subjets=btagDiscriminatorsAK8Subjets + ) + return proc #=========================================================================== diff --git a/PhysicsTools/NanoAOD/python/jetMC_cff.py b/PhysicsTools/NanoAOD/python/jetMC_cff.py index 4e57a5e7c176d..4e7418e04e015 100644 --- a/PhysicsTools/NanoAOD/python/jetMC_cff.py +++ b/PhysicsTools/NanoAOD/python/jetMC_cff.py @@ -112,6 +112,7 @@ nBHadrons = Var("jetFlavourInfo().getbHadrons().size()", "uint8", doc="number of b-hadrons"), nCHadrons = Var("jetFlavourInfo().getcHadrons().size()", "uint8", doc="number of c-hadrons"), hadronFlavour = Var("hadronFlavour()", "uint8", doc="flavour from hadron ghost clustering"), + subGenJetAK8Idx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", "int16", doc="index of matched gen subjet in SubGenJetAK8") ) ) diff --git a/PhysicsTools/NanoAOD/python/jetsAK4_CHS_cff.py b/PhysicsTools/NanoAOD/python/jetsAK4_CHS_cff.py index 48554879c92bf..fb95821213cb8 100644 --- a/PhysicsTools/NanoAOD/python/jetsAK4_CHS_cff.py +++ b/PhysicsTools/NanoAOD/python/jetsAK4_CHS_cff.py @@ -487,6 +487,7 @@ def nanoAOD_refineFastSim_bTagDeepFlav(process): doc = cms.string("Additional low-pt ak4 CHS jets for Type-1 MET re-correction"), variables = cms.PSet( rawPt = Var("pt()*jecFactor('Uncorrected')",float,precision=10), + rawMass = Var("mass()*jecFactor('Uncorrected')",float,precision=10), eta = Var("eta", float,precision=12), phi = Var("phi", float, precision=12), area = Var("jetArea()", float, doc="jet catchment area, for JECs",precision=10), diff --git a/PhysicsTools/NanoAOD/python/jetsAK4_Puppi_cff.py b/PhysicsTools/NanoAOD/python/jetsAK4_Puppi_cff.py index 491695a47eb34..32939811b00e0 100644 --- a/PhysicsTools/NanoAOD/python/jetsAK4_Puppi_cff.py +++ b/PhysicsTools/NanoAOD/python/jetsAK4_Puppi_cff.py @@ -215,6 +215,7 @@ def nanoAOD_addDeepInfoAK4(process,addParticleNet,addRobustParTAK4=False,addUnif doc = cms.string("Additional low-pt ak4 Puppi jets for Type-1 MET re-correction"), variables = cms.PSet( rawPt = Var("pt()*jecFactor('Uncorrected')",float,precision=10), + rawMass = Var("mass()*jecFactor('Uncorrected')",float,precision=10), eta = Var("eta", float,precision=12), phi = Var("phi", float, precision=12), area = Var("jetArea()", float, doc="jet catchment area, for JECs",precision=10), diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py index 4184faf87f947..f88ed7e9085c5 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py @@ -22,6 +22,7 @@ Plot1D('muonSubtrFactor', 'muonSubtrFactor', 20, 0, 1, '1-(muon-subtracted raw pt)/(raw pt)'), Plot1D('phi', 'phi', 20, -3.14159, 3.14159, 'phi'), Plot1D('rawPt', 'rawPt', 20, 5, 25, "pt()*jecFactor('Uncorrected')"), + Plot1D('rawMass', 'rawMass', 20, 5, 25, "mass()*jecFactor('Uncorrected')"), Plot1D('EmEF', 'EmEF', 20, 0., 1., "charged+neutral Electromagnetic Energy Fraction"), ) ), @@ -833,6 +834,7 @@ Plot1D('tau2', 'tau2', 20, 0, 1, 'Nsubjettiness (2 axis)'), Plot1D('tau3', 'tau3', 20, 0, 1, 'Nsubjettiness (3 axis)'), Plot1D('tau4', 'tau4', 20, 0, 1, 'Nsubjettiness (4 axis)'), + NoPlot('subGenJetAK8Idx'), ) ), Tau = cms.PSet( diff --git a/PhysicsTools/NanoAOD/python/nanojmeDQM_cff.py b/PhysicsTools/NanoAOD/python/nanojmeDQM_cff.py index a8b263343e757..2fbafc9a3e38f 100644 --- a/PhysicsTools/NanoAOD/python/nanojmeDQM_cff.py +++ b/PhysicsTools/NanoAOD/python/nanojmeDQM_cff.py @@ -51,6 +51,20 @@ Plot1D('particleNetAK4_QvsG','particleNetAK4_QvsG',20, -1, 1,"ParticleNetAK4 tagger uds vs g discriminator"), Plot1D('particleNetAK4_G','particleNetAK4_G',20, -1, 1, "ParticleNetAK4 tagger g raw score"), Plot1D('particleNetAK4_puIdDisc','particleNetAK4_puIdDisc',20, -1, 1,"ParticleNetAK4 tagger pileup jet discriminator"), + Plot1D('leadConstNeHadEF','leadConstNeHadEF',10, 0, 1,"Leading PF neutral hadron constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstChHadEF','leadConstChHadEF',10, 0, 1,"Leading PF charged hadron constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstPhotonEF','leadConstPhotonEF',10, 0, 1,"Leading PF photon constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstElectronEF','leadConstElectronEF',10, 0, 1,"Leading PF electron constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstMuonEF','leadConstMuonEF',10, 0, 1,"Leading PF muon constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstHFHADEF','leadConstHFHADEF',10, 0, 1,"Leading PF HF HAD constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstHFEMEF','leadConstHFEMEF',10, 0, 1,"Leading PF HF EM constituent energy fraction w.r.t jet raw energy"), + Plot1D('leadConstNeHadPuppiWeight','leadConstNeHadPuppiWeight',10, 0, 1,"Leading PF neutral hadron constituent puppi weight"), + Plot1D('leadConstChHadPuppiWeight','leadConstChHadPuppiWeight',10, 0, 1,"Leading PF charged hadron constituent puppi weight"), + Plot1D('leadConstPhotonPuppiWeight','leadConstPhotonPuppiWeight',10, 0, 1,"Leading PF photon constituent puppi weight"), + Plot1D('leadConstElectronPuppiWeight','leadConstElectronPuppiWeight',10, 0, 1,"Leading PF electron constituent puppi weight"), + Plot1D('leadConstMuonPuppiWeight','leadConstMuonPuppiWeight',10, 0, 1,"Leading PF muon constituent puppi weight"), + Plot1D('leadConstHFHADPuppiWeight','leadConstHFHADPuppiWeight',10, 0, 1,"Leading PF HF HAD constituent puppi weight"), + Plot1D('leadConstHFEMPuppiWeight','leadConstHFEMPuppiWeight',10, 0, 1,"Leading PF HF EM constituent puppi weight"), ]) #============================================ diff --git a/PhysicsTools/PatAlgos/python/slimming/applySubstructure_cff.py b/PhysicsTools/PatAlgos/python/slimming/applySubstructure_cff.py index da4f42a99df8c..de69664d45755 100644 --- a/PhysicsTools/PatAlgos/python/slimming/applySubstructure_cff.py +++ b/PhysicsTools/PatAlgos/python/slimming/applySubstructure_cff.py @@ -7,11 +7,10 @@ def applySubstructure( process, postfix="" ) : task = getPatAlgosToolsTask(process) from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection - + from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJetsDefault - # Configure the RECO jets from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents setattr(process,'ak8PFJetsPuppi'+postfix,ak8PFJetsPuppi.clone()) @@ -19,76 +18,56 @@ def applySubstructure( process, postfix="" ) : setattr(process,'ak8PFJetsPuppiSoftDrop'+postfix, ak8PFJetsPuppiSoftDrop.clone( src = 'ak8PFJetsPuppiConstituents'+postfix+':constituents' )) from RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi import ak8PFJetsPuppiSoftDropMass setattr(process,'ak8PFJetsPuppiSoftDropMass'+postfix, ak8PFJetsPuppiSoftDropMass.clone()) + from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL _run2_miniAOD_ANY = (run2_miniAOD_UL) from Configuration.Eras.Modifier_pA_2016_cff import pA_2016 - if postfix=='': - # Avoid recomputing the PUPPI collections that are present in AOD - _rerun_puppijets_task = task.copy() - _rerun_puppijets_task.add(getattr(process,'ak8PFJetsPuppi'), - getattr(process,'ak8PFJetsPuppiConstituents'), - getattr(process,'ak8PFJetsPuppiSoftDrop'), - getattr(process,'ak8PFJetsPuppiSoftDropMass')) - (_run2_miniAOD_ANY | pA_2016 ).toReplaceWith(task, _rerun_puppijets_task) - (_run2_miniAOD_ANY | pA_2016 ).toModify(getattr(process,'ak8PFJetsPuppiConstituents'+postfix), - cut = cms.string('pt > 170.0 && abs(rapidity()) < 2.4')) - else: - task.add(getattr(process,'ak8PFJetsPuppi'+postfix), - getattr(process,'ak8PFJetsPuppiConstituents'+postfix), - getattr(process,'ak8PFJetsPuppiSoftDrop'+postfix), - getattr(process,'ak8PFJetsPuppiSoftDropMass'+postfix)) + # Avoid recomputing the PUPPI collections that are present in AOD + _rerun_puppijets_task = task.copy() + _rerun_puppijets_task.add(getattr(process,'ak8PFJetsPuppi'+postfix), + getattr(process,'ak8PFJetsPuppiConstituents'+postfix), + getattr(process,'ak8PFJetsPuppiSoftDrop'+postfix), + getattr(process,'ak8PFJetsPuppiSoftDropMass'+postfix)) + (_run2_miniAOD_ANY | pA_2016 ).toReplaceWith(task, _rerun_puppijets_task) from RecoJets.JetProducers.ak8GenJets_cfi import ak8GenJets, ak8GenJetsSoftDrop, ak8GenJetsConstituents addToProcessAndTask('ak8GenJetsNoNuConstituents'+postfix, ak8GenJetsConstituents.clone(src='ak8GenJetsNoNu'), process, task ) addToProcessAndTask('ak8GenJetsNoNuSoftDrop'+postfix,ak8GenJetsSoftDrop.clone(src=cms.InputTag('ak8GenJetsNoNuConstituents'+postfix, 'constituents')),process,task) addToProcessAndTask('slimmedGenJetsAK8SoftDropSubJets'+postfix, - cms.EDProducer("PATGenJetSlimmer", - src = cms.InputTag("ak8GenJetsNoNuSoftDrop"+postfix, "SubJets"), - packedGenParticles = cms.InputTag("packedGenParticles"), - cut = cms.string(""), - cutLoose = cms.string(""), - nLoose = cms.uint32(0), - clearDaughters = cms.bool(False), #False means rekeying - dropSpecific = cms.bool(True), # Save space - ), process, task ) + cms.EDProducer("PATGenJetSlimmer", + src = cms.InputTag("ak8GenJetsNoNuSoftDrop"+postfix, "SubJets"), + packedGenParticles = cms.InputTag("packedGenParticles"), + cut = cms.string(""), + cutLoose = cms.string(""), + nLoose = cms.uint32(0), + clearDaughters = cms.bool(False), #False means rekeying + dropSpecific = cms.bool(True), # Save space + ), process, task ) ## PATify puppi soft drop fat jets addJetCollection( - process, - postfix=postfix, - labelName = 'AK8PFPuppiSoftDrop' + postfix, - jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix), - btagDiscriminators = ['None'], - genJetCollection = cms.InputTag('slimmedGenJetsAK8'), - jetCorrections = ('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'), - getJetMCFlavour = False # jet flavor disabled + process, + labelName = 'AK8PFPuppiSoftDrop'+postfix, + jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix), + btagDiscriminators = ['None'], + genJetCollection = cms.InputTag('slimmedGenJetsAK8'), + jetCorrections = ('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'), + getJetMCFlavour = False # jet flavor disabled ) ## PATify soft drop subjets - from RecoBTag.ONNXRuntime.pfUnifiedParticleTransformerAK4_cff import _pfUnifiedParticleTransformerAK4JetTagsAll as pfUnifiedParticleTransformerAK4JetTagsAll - _btagDiscriminatorsSubjets = cms.PSet( - names=cms.vstring( - 'pfDeepFlavourJetTags:probb', - 'pfDeepFlavourJetTags:probbb', - 'pfDeepFlavourJetTags:problepb', - 'pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:BvsAll' - ) - ) - addJetCollection( - process, - postfix=postfix, - labelName = 'AK8PFPuppiSoftDropSubjets', - jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix,'SubJets'), - algo = 'ak', # needed for subjet flavor clustering - rParam = 0.8, # needed for subjet flavor clustering - btagDiscriminators = _btagDiscriminatorsSubjets.names.value(), - jetCorrections = ('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'), - explicitJTA = True, # needed for subjet b tagging - svClustering = True, # needed for subjet b tagging - genJetCollection = cms.InputTag('slimmedGenJetsAK8SoftDropSubJets'), - fatJets=cms.InputTag('ak8PFJetsPuppi'), # needed for subjet flavor clustering - groomedFatJets=cms.InputTag('ak8PFJetsPuppiSoftDrop') # needed for subjet flavor clustering + process, + labelName = 'AK8PFPuppiSoftDropSubjets'+postfix, + jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix,'SubJets'), + algo = 'ak', # needed for subjet flavor clustering + rParam = 0.8, # needed for subjet flavor clustering + jetCorrections = ('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'), + explicitJTA = True, # needed for subjet b tagging + svClustering = True, # needed for subjet b tagging + genJetCollection = cms.InputTag('slimmedGenJetsAK8SoftDropSubJets'), + fatJets=cms.InputTag('ak8PFJetsPuppi'), # needed for subjet flavor clustering + groomedFatJets=cms.InputTag('ak8PFJetsPuppiSoftDrop') # needed for subjet flavor clustering ) # add groomed ECFs and N-subjettiness to soft dropped pat::Jets for fat jets and subjets @@ -118,15 +97,15 @@ def applySubstructure( process, postfix="" ) : e.toModify(getattr(process,'nb1AK8PuppiSoftDropSubjets'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] ) e.toModify(getattr(process,'nb2AK8PuppiSoftDropSubjets'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] ) - + # Patify AK8 PF PUPPI - addJetCollection(process, postfix=postfix, labelName = 'AK8Puppi', - jetSource = cms.InputTag('ak8PFJetsPuppi'+postfix), - algo= 'AK', rParam = 0.8, - jetCorrections = ('AK8PFPuppi', cms.vstring(['L2Relative', 'L3Absolute']), 'None'), - btagDiscriminators = None, - genJetCollection = cms.InputTag('slimmedGenJetsAK8') - ) + addJetCollection(process, labelName = 'AK8Puppi'+postfix, + jetSource = cms.InputTag('ak8PFJetsPuppi'+postfix), + algo= 'AK', rParam = 0.8, + jetCorrections = ('AK8PFPuppi', cms.vstring(['L2Relative', 'L3Absolute']), 'None'), + btagDiscriminators = None, + genJetCollection = cms.InputTag('slimmedGenJetsAK8') + ) getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src = [] # start with empty list of user floats getattr(process,"selectedPatJetsAK8Puppi"+postfix).cut = cms.string("pt > 100") getattr(process,"selectedPatJetsAK8Puppi"+postfix).cutLoose = cms.string("pt > 30") @@ -148,55 +127,78 @@ def applySubstructure( process, postfix="" ) : getattr(process,"patJetsAK8Puppi"+postfix).addTagInfos = cms.bool(False) - # add PUPPI Njetiness + # add PUPPI Njetiness addToProcessAndTask('NjettinessAK8Puppi'+postfix, Njettiness.clone(), process, task) getattr(process,"NjettinessAK8Puppi"+postfix).src = cms.InputTag("ak8PFJetsPuppi"+postfix) getattr(process,"patJetsAK8Puppi").userData.userFloats.src += ['NjettinessAK8Puppi'+postfix+':tau1','NjettinessAK8Puppi'+postfix+':tau2','NjettinessAK8Puppi'+postfix+':tau3','NjettinessAK8Puppi'+postfix+':tau4'] - - addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropSubjets"+postfix, - cms.EDProducer("PATJetSlimmer", - src = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"), - packedPFCandidates = cms.InputTag("packedPFCandidates"), - dropJetVars = cms.string("1"), - dropDaughters = cms.string("0"), - rekeyDaughters = cms.string("1"), - dropTrackRefs = cms.string("1"), - dropSpecific = cms.string("1"), - dropTagInfos = cms.string("1"), - modifyJets = cms.bool(True), - mixedDaughters = cms.bool(False), - modifierConfig = cms.PSet( modifications = cms.VPSet() ) - ), - process, task) + # slim subjet collection + addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropSubjetsNoDeepTags"+postfix, cms.EDProducer("PATJetSlimmer", + src = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"), + packedPFCandidates = cms.InputTag("packedPFCandidates"), + dropJetVars = cms.string("1"), + dropDaughters = cms.string("0"), + rekeyDaughters = cms.string("1"), + dropTrackRefs = cms.string("1"), + dropSpecific = cms.string("1"), + dropTagInfos = cms.string("1"), + modifyJets = cms.bool(True), + mixedDaughters = cms.bool(False), + modifierConfig = cms.PSet( modifications = cms.VPSet() ) + ), process, task + ) + + # Setup DeepJet and UParT taggers for subjet + from RecoBTag.ONNXRuntime.pfUnifiedParticleTransformerAK4_cff import _pfUnifiedParticleTransformerAK4JetTagsAll as pfUnifiedParticleTransformerAK4JetTagsAll + _btagDiscriminatorsSubjets = cms.PSet( + names=cms.vstring( + 'pfDeepFlavourJetTags:probb', + 'pfDeepFlavourJetTags:probbb', + 'pfDeepFlavourJetTags:problepb', + 'pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:BvsAll' + ) + ) + updateJetCollection( + process, + labelName = 'AK8PFPuppiSoftDropSubjets', + postfix = 'SlimmedDeepFlavour'+postfix, + jetSource = cms.InputTag('slimmedJetsAK8PFPuppiSoftDropSubjetsNoDeepTags'), + # updateJetCollection defaults to MiniAOD inputs but + # here it is made explicit (as in training or MINIAOD redoing) + pfCandidates = cms.InputTag('packedPFCandidates'), + pvSource = cms.InputTag('offlineSlimmedPrimaryVertices'), + svSource = cms.InputTag('slimmedSecondaryVertices'), + muSource = cms.InputTag('slimmedMuons'), + elSource = cms.InputTag('slimmedElectrons'), + jetCorrections = ('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'), + printWarning = False, + btagDiscriminators = _btagDiscriminatorsSubjets.names.value(), + ) - ## Establish references between PATified fat jets and subjets using the BoostedJetMerger - addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix, - cms.EDProducer("BoostedJetMerger", - jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"), - subjetSrc=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjets") - ), - process, task ) - - + addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix, cms.EDProducer("BoostedJetMerger", + jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"+postfix), + subjetSrc=cms.InputTag("selectedUpdatedPatJetsAK8PFPuppiSoftDropSubjetsSlimmedDeepFlavour"+postfix) + ), process, task + ) + addToProcessAndTask("packedPatJetsAK8"+postfix, cms.EDProducer("JetSubstructurePacker", - jetSrc = cms.InputTag("selectedPatJetsAK8Puppi"+postfix), - distMax = cms.double(0.8), - algoTags = cms.VInputTag( - cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix) - ), - algoLabels = cms.vstring( - 'SoftDropPuppi' - ), - fixDaughters = cms.bool(True), - packedPFCandidates = cms.InputTag("packedPFCandidates"+postfix), - ), - process, task) + jetSrc = cms.InputTag("selectedPatJetsAK8Puppi"+postfix), + distMax = cms.double(0.8), + algoTags = cms.VInputTag( + cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix) + ), + algoLabels = cms.vstring( + 'SoftDropPuppi' + ), + fixDaughters = cms.bool(True), + packedPFCandidates = cms.InputTag("packedPFCandidates"), + ), process, task + ) # switch off daughter re-keying since it's done in the JetSubstructurePacker (and can't be done afterwards) process.slimmedJetsAK8.rekeyDaughters = "0" - # Reconfigure the slimmedAK8 jet information to keep + # Reconfigure the slimmedAK8 jet information to keep process.slimmedJetsAK8.dropDaughters = cms.string("pt < 170") process.slimmedJetsAK8.dropSpecific = cms.string("pt < 170") process.slimmedJetsAK8.dropTagInfos = cms.string("pt < 170") diff --git a/PhysicsTools/PatAlgos/python/tools/coreTools.py b/PhysicsTools/PatAlgos/python/tools/coreTools.py index d0ed62b69bc08..1aa4015eb40eb 100644 --- a/PhysicsTools/PatAlgos/python/tools/coreTools.py +++ b/PhysicsTools/PatAlgos/python/tools/coreTools.py @@ -124,10 +124,13 @@ def toolCode(self, process): _removeMCMatchingForPATObject(process, 'tauMatch', 'patTaus', postfix) ## remove mc extra configs for taus tauProducer = getattr(process,'patTaus'+postfix) - tauProducer.addGenJetMatch = False - tauProducer.embedGenJetMatch = False + if hasattr(tauProducer,"addGenJetMatch"): + tauProducer.addGenJetMatch = False + if hasattr(tauProducer,"embedGenJetMatch"): + tauProducer.embedGenJetMatch = False attrsToDelete += [tauProducer.genJetMatch.getModuleLabel()] - tauProducer.genJetMatch = '' + if hasattr(tauProducer,"genJetMatch"): + tauProducer.genJetMatch = '' attrsToDelete += ['tauGenJets'+postfix] attrsToDelete += ['tauGenJetsSelectorAllHadrons'+postfix] #Boosted Taus @@ -137,10 +140,13 @@ def toolCode(self, process): _removeMCMatchingForPATObject(process, 'tauMatchBoosted', 'patTausBoosted', postfix) ## remove mc extra configs for taus tauProducer = getattr(process,'patTausBoosted'+postfix) - tauProducer.addGenJetMatch = False - tauProducer.embedGenJetMatch = False + if hasattr(tauProducer,"addGenJetMatch"): + tauProducer.addGenJetMatch = False + if hasattr(tauProducer,"embedGenJetMatch"): + tauProducer.embedGenJetMatch = False attrsToDelete += [tauProducer.genJetMatch.getModuleLabel()] - tauProducer.genJetMatch = '' + if hasattr(tauProducer,"genJetMatch"): + tauProducer.genJetMatch = '' attrsToDelete += ['tauGenJetsBoosted'+postfix] attrsToDelete += ['tauGenJetsSelectorAllHadronsBoosted'+postfix] else : @@ -154,20 +160,30 @@ def toolCode(self, process): for pfix in jetPostfixes: ## remove mc extra configs for jets jetProducer = getattr(process, jetCollectionString()+pfix) - jetProducer.addGenPartonMatch = False - jetProducer.embedGenPartonMatch = False + if hasattr(jetProducer,"addGenPartonMatch"): + jetProducer.addGenPartonMatch = False + if hasattr(jetProducer,"embedGenPartonMatch"): + jetProducer.embedGenPartonMatch = False #attrsToDelete += [jetProducer.genPartonMatch.getModuleLabel()] #MM needed for potential jet backuping - jetProducer.genPartonMatch = '' - jetProducer.addGenJetMatch = False + if hasattr(jetProducer,"genPartonMatch"): + jetProducer.genPartonMatch = '' + if hasattr(jetProducer,"addGenJetMatch"): + jetProducer.addGenJetMatch = False #attrsToDelete += [jetProducer.genJetMatch.getModuleLabel()] #MM needed for potential jet backuping - jetProducer.genJetMatch = '' - jetProducer.getJetMCFlavour = False - jetProducer.useLegacyJetMCFlavour = False - jetProducer.addJetFlavourInfo = False + if hasattr(jetProducer,"genJetMatch"): + jetProducer.genJetMatch = '' + if hasattr(jetProducer,"getJetMCFlavour"): + jetProducer.getJetMCFlavour = False + if hasattr(jetProducer,"useLegacyJetMCFlavour"): + jetProducer.useLegacyJetMCFlavour = False + if hasattr(jetProducer,"addJetFlavourInfo"): + jetProducer.addJetFlavourInfo = False #attrsToDelete += [jetProducer.JetPartonMapSource.getModuleLabel()] #MM needed for potential jet backuping - jetProducer.JetPartonMapSource = '' + if hasattr(jetProducer,"JetPartonMapSource"): + jetProducer.JetPartonMapSource = '' #attrsToDelete += [jetProducer.JetFlavourInfoSource.getModuleLabel()] #MM needed for potential jet backuping - jetProducer.JetFlavourInfoSource = '' + if hasattr(jetProducer,"JetFlavourInfoSource"): + jetProducer.JetFlavourInfoSource = '' attrsToDelete += ['slimmedGenJets'+pfix] ## adjust output for outMod in outputModules: @@ -176,7 +192,6 @@ def toolCode(self, process): getattr(process,outMod).outputCommands.append("drop recoGenJets_*_*_*") else: raise KeyError("process has no OutModule named " + outMod) - if ( names[obj] == 'JetsAK8' or names[obj] == 'All' ): print("removing MC dependencies for AK8 jets") attrsToDelete += ['slimmedGenJetsAK8' + postfix] @@ -206,9 +221,12 @@ def _removeMCMatchingForPATObject(process, matcherName, producerName, postfix="" objectMatcher = getattr(process, matcherName+postfix) if hasattr(process, producerName+postfix): objectProducer = getattr(process, producerName+postfix) - objectProducer.addGenMatch = False - objectProducer.embedGenMatch = False + if hasattr(objectProducer,"addGenMatch"): + objectProducer.addGenMatch = False + if hasattr(objectProducer,"addGenMatch"): + objectProducer.addGenMatch = False attr = objectProducer.genParticleMatch.getModuleLabel() - objectProducer.genParticleMatch = '' + if hasattr(objectProducer,"genParticleMatch"): + objectProducer.genParticleMatch = '' if hasattr(process,attr): delattr(process,attr) diff --git a/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringFromMiniAOD_cff.py b/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringFromMiniAOD_cff.py new file mode 100644 index 0000000000000..5772dafc56560 --- /dev/null +++ b/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringFromMiniAOD_cff.py @@ -0,0 +1,80 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.PatAlgos.tools.puppiJetMETReclusteringTools import puppiAK4METReclusterFromMiniAOD +from PhysicsTools.PatAlgos.tools.puppiJetMETReclusteringTools import puppiAK8ReclusterFromMiniAOD + +def setupPuppiAK4AK8METReclustering(process, runOnMC, useExistingWeights=False, reclusterAK4MET=True, reclusterAK8=True, btagDiscriminatorsAK4=None, btagDiscriminatorsAK8=None, btagDiscriminatorsAK8Subjets=None): + + if reclusterAK4MET: + process = puppiAK4METReclusterFromMiniAOD(process, runOnMC, + useExistingWeights=useExistingWeights, + btagDiscriminatorsAK4=btagDiscriminatorsAK4 + ) + + if reclusterAK8: + process = puppiAK8ReclusterFromMiniAOD(process, runOnMC, + useExistingWeights=useExistingWeights, + btagDiscriminatorsAK8=btagDiscriminatorsAK8, + btagDiscriminatorsAK8Subjets=btagDiscriminatorsAK8Subjets + ) + + return process + +def puppiJetMETReclusterFromMiniAOD(process, runOnMC, useExistingWeights=False, reclusterAK4MET=True, reclusterAK8=True): + + # AK4 taggers + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll as pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfParticleNetFromMiniAODAK4PuppiForwardJetTagsAll as pfParticleNetFromMiniAODAK4PuppiForwardJetTagsAll + from RecoBTag.ONNXRuntime.pfUnifiedParticleTransformerAK4_cff import _pfUnifiedParticleTransformerAK4JetTagsAll as pfUnifiedParticleTransformerAK4JetTagsAll + + btagDiscriminatorsAK4 = cms.PSet( + names=cms.vstring( + 'pfDeepFlavourJetTags:probb', + 'pfDeepFlavourJetTags:probbb', + 'pfDeepFlavourJetTags:problepb', + 'pfDeepFlavourJetTags:probc', + 'pfDeepFlavourJetTags:probuds', + 'pfDeepFlavourJetTags:probg') + + pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll + + pfParticleNetFromMiniAODAK4PuppiForwardJetTagsAll + + pfUnifiedParticleTransformerAK4JetTagsAll + ) + + # AK8 taggers + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetJetTagsAll as pfParticleNetJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetMassRegressionOutputs as pfParticleNetMassRegressionOutputs + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetMassCorrelatedJetTagsAll as pfParticleNetMassCorrelatedJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import _pfParticleNetFromMiniAODAK8JetTagsAll as pfParticleNetFromMiniAODAK8JetTagsAll + btagDiscriminatorsAK8 = cms.PSet(names = cms.vstring( + pfParticleNetMassCorrelatedJetTagsAll+ + pfParticleNetFromMiniAODAK8JetTagsAll+ + pfParticleNetJetTagsAll+ + pfParticleNetMassRegressionOutputs + ) + ) + + # AK8 Subjets taggers + btagDiscriminatorsAK8Subjets = cms.PSet(names = cms.vstring( + 'pfDeepFlavourJetTags:probb', + 'pfDeepFlavourJetTags:probbb', + 'pfDeepFlavourJetTags:problepb', + 'pfUnifiedParticleTransformerAK4DiscriminatorsJetTags:BvsAll' + ) + ) + process = setupPuppiAK4AK8METReclustering(process, runOnMC, + useExistingWeights=useExistingWeights, + reclusterAK4MET=reclusterAK4MET, reclusterAK8=reclusterAK8, + btagDiscriminatorsAK4=btagDiscriminatorsAK4, + btagDiscriminatorsAK8=btagDiscriminatorsAK8, + btagDiscriminatorsAK8Subjets=btagDiscriminatorsAK8Subjets + ) + + return process + +def puppiJetMETReclusterFromMiniAOD_MC(process): + process = puppiJetMETReclusterFromMiniAOD(process, runOnMC=True) + return process + +def puppiJetMETReclusterFromMiniAOD_Data(process): + process = puppiJetMETReclusterFromMiniAOD(process, runOnMC=False) + return process + diff --git a/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringTools.py b/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringTools.py new file mode 100644 index 0000000000000..311b706453647 --- /dev/null +++ b/PhysicsTools/PatAlgos/python/tools/puppiJetMETReclusteringTools.py @@ -0,0 +1,476 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.PatAlgos.tools.coreTools import runOnData +from PhysicsTools.PatAlgos.tools.jetTools import supportedJetAlgos, addJetCollection, updateJetCollection +from PhysicsTools.PatAlgos.tools.jetTools import setupPuppiForPackedPF +from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask, addToProcessAndTask + +def puppiAK4METReclusterFromMiniAOD(process, runOnMC, useExistingWeights, btagDiscriminatorsAK4=None): + + task = getPatAlgosToolsTask(process) + + pfLabel = "packedPFCandidates" + pvLabel = "offlineSlimmedPrimaryVertices" + svLabel = "slimmedSecondaryVertices" + muLabel = "slimmedMuons" + elLabel = "slimmedElectrons" + gpLabel = "prunedGenParticles" + + genJetsCollection = "slimmedGenJets" + + ######################### + # + # Setup puppi weights + # Two instances of PuppiProducer: + # 1) puppi (for jet reclustering) + # 2) puppiNoLep (for MET reclustering) + # + ######################## + puppiLabel, puppiNoLepLabel = setupPuppiForPackedPF(process, useExistingWeights) + + ######################### + # + # AK4 Puppi jets + # + ######################## + # + # Recluster jets + # + process.load("RecoJets.JetProducers.ak4PFJets_cfi") + task.add(process.ak4PFJetsPuppi) + process.ak4PFJetsPuppi.src = pfLabel + process.ak4PFJetsPuppi.srcWeights = puppiLabel + + from RecoJets.JetAssociationProducers.j2tParametersVX_cfi import j2tParametersVX + process.ak4PFJetsPuppiTracksAssociatorAtVertex = cms.EDProducer("JetTracksAssociatorAtVertex", + j2tParametersVX, + jets = cms.InputTag("ak4PFJetsPuppi") + ) + task.add(process.ak4PFJetsPuppiTracksAssociatorAtVertex) + process.patJetPuppiCharge = cms.EDProducer("JetChargeProducer", + src = cms.InputTag("ak4PFJetsPuppiTracksAssociatorAtVertex"), + var = cms.string("Pt"), + exp = cms.double(1.0) + ) + + # + # PATify jets + # + addJetCollection( + process, + postfix = "", + labelName = "Puppi", + jetSource = cms.InputTag("ak4PFJetsPuppi"), + algo = "ak", + rParam = 0.4, + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + genJetCollection = cms.InputTag(genJetsCollection), + genParticles = cms.InputTag(gpLabel), + jetCorrections = ('AK4PFPuppi', cms.vstring(["L2Relative", "L3Absolute"]), ''), + getJetMCFlavour = runOnMC + ) + process.patJetsPuppi.jetChargeSource = cms.InputTag("patJetPuppiCharge") + process.selectedPatJetsPuppi.cut = cms.string("pt > 10") + if hasattr(process,"patJetFlavourAssociationPuppi"): + process.patJetFlavourAssociationPuppi.weights = cms.InputTag(puppiLabel) + + #============================================= + # + # Update the selectedPatJet collection. + # This is where we setup + # - JEC + # - b-tagging discriminators + # + #============================================= + # update slimmedJetsPuppi to include taggers + from PhysicsTools.PatAlgos.slimming.slimmedJets_cfi import slimmedJets + addToProcessAndTask('slimmedJetsPuppiNoDeepTags', slimmedJets.clone( + src = "selectedPatJetsPuppi", + packedPFCandidates = pfLabel, + dropDaughters = "0", + rekeyDaughters = "0", + ), + process, task + ) + + updateJetCollection( + process, + jetSource = cms.InputTag("slimmedJetsPuppiNoDeepTags"), + # updateJetCollection defaults to MiniAOD inputs but + # here it is made explicit (as in training or MINIAOD redoing) + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + jetCorrections = ("AK4PFPuppi", cms.vstring(["L2Relative", "L3Absolute"]), "None"), + btagDiscriminators = btagDiscriminatorsAK4.names.value() if btagDiscriminatorsAK4 is not None else ['None'], + postfix = 'SlimmedDeepFlavour', + printWarning = False + ) + + addToProcessAndTask("slimmedJetsPuppi", process.selectedUpdatedPatJetsSlimmedDeepFlavour.clone(), process, task) + del process.selectedUpdatedPatJetsSlimmedDeepFlavour + + ######################## + # + # Recluster PuppiMET + # + ######################## + from PhysicsTools.PatUtils.tools.runMETCorrectionsAndUncertainties import runMetCorAndUncFromMiniAOD + runMetCorAndUncFromMiniAOD(process, + isData=not(runOnMC), + jetCollUnskimmed="slimmedJetsPuppi", + metType="Puppi", + postfix="Puppi", + jetFlavor="AK4PFPuppi", + puppiProducerLabel=puppiLabel, + puppiProducerForMETLabel=puppiNoLepLabel, + recoMetFromPFCs=True + ) + + ######################## + # + # Modify JECs when processing real Data + # Disable any MC-only features. + # + ######################## + if not(runOnMC): + runOnData(process, names=["Jets","METs"], outputModules = []) + + return process + + +def puppiAK8ReclusterFromMiniAOD(process, runOnMC, useExistingWeights, btagDiscriminatorsAK8=None, btagDiscriminatorsAK8Subjets=None): + + task = getPatAlgosToolsTask(process) + + pfLabel = "packedPFCandidates" + pvLabel = "offlineSlimmedPrimaryVertices" + svLabel = "slimmedSecondaryVertices" + muLabel = "slimmedMuons" + elLabel = "slimmedElectrons" + gpLabel = "prunedGenParticles" + + genJetsAK8Collection = "slimmedGenJetsAK8" + genSubJetsForAK8Collection = "slimmedGenJetsAK8SoftDropSubJets" + + ######################### + # + # Setup puppi weights + # Two instances of PuppiProducer: + # 1) puppi (for jet reclustering) + # 2) puppiNoLep (for MET reclustering) + # + ######################## + puppiLabel, puppiNoLepLabel = setupPuppiForPackedPF(process, useExistingWeights) + + ######################## + # + # AK8 Puppi jets + # + ######################## + # + # Recluster jets and do soft-drop grooming + # + process.load("RecoJets.JetProducers.ak8PFJets_cfi") + task.add(process.ak8PFJetsPuppi) + task.add(process.ak8PFJetsPuppiSoftDrop) + + # AK8 jet constituents for softdrop + process.ak8PFJetsPuppi.src = pfLabel + process.ak8PFJetsPuppi.srcWeights = puppiLabel + + # AK8 jet constituents for softdrop + from CommonTools.RecoAlgos.miniAODJetConstituentSelector_cfi import miniAODJetConstituentSelector + addToProcessAndTask("ak8PFJetsPuppiConstituents", miniAODJetConstituentSelector.clone( + src = cms.InputTag("ak8PFJetsPuppi"), + cut = cms.string("pt > 100.0 && abs(rapidity()) < 2.4") + ), + process, task + ) + + # Soft-drop grooming + process.ak8PFJetsPuppiSoftDrop.src = "ak8PFJetsPuppiConstituents:constituents" + process.ak8PFJetsPuppiSoftDrop.srcWeights = puppiLabel + + # Soft-drop mass + process.load("RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi") + task.add(process.ak8PFJetsPuppiSoftDropMass) + process.ak8PFJetsPuppiSoftDropMass.src = "ak8PFJetsPuppi" + process.ak8PFJetsPuppiSoftDropMass.matched = "ak8PFJetsPuppiSoftDrop" + #============================================= + # + # PATify + # + #============================================= + # + # AK8 jets + # + addJetCollection( + process, + labelName = "AK8Puppi", + jetSource = cms.InputTag("ak8PFJetsPuppi"), + algo = "ak", + rParam = 0.8, + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + genJetCollection = cms.InputTag(genJetsAK8Collection), + genParticles = cms.InputTag(gpLabel), + jetCorrections = ("AK8PFPuppi", cms.vstring(["L2Relative", "L3Absolute"]), "None"), + getJetMCFlavour = runOnMC, + ) + if hasattr(process,"patJetFlavourAssociationAK8Puppi"): + process.patJetFlavourAssociationAK8Puppi.weights = cms.InputTag(puppiLabel) + + process.patJetsAK8Puppi.userData.userFloats.src = [] # start with empty list of user floats + process.patJetsAK8Puppi.userData.userFloats.src += ["ak8PFJetsPuppiSoftDropMass"] + process.patJetsAK8Puppi.addTagInfos = cms.bool(False) + + process.selectedPatJetsAK8Puppi.cut = cms.string("pt > 100") + process.selectedPatJetsAK8Puppi.cutLoose = cms.string("pt > 30") + process.selectedPatJetsAK8Puppi.nLoose = cms.uint32(3) + + # + # Add AK8 Njetiness + # + from RecoJets.JetProducers.nJettinessAdder_cfi import Njettiness + addToProcessAndTask("NjettinessAK8Puppi", Njettiness.clone( + src = "ak8PFJetsPuppi", + srcWeights = puppiLabel + ), + process, task + ) + process.patJetsAK8Puppi.userData.userFloats.src += [ + "NjettinessAK8Puppi:tau1", + "NjettinessAK8Puppi:tau2", + "NjettinessAK8Puppi:tau3", + "NjettinessAK8Puppi:tau4" + ] + + # + # AK8 soft-drop jets + # + addJetCollection( + process, + labelName = "AK8PFPuppiSoftDrop", + jetSource = cms.InputTag("ak8PFJetsPuppiSoftDrop"), + btagDiscriminators = ["None"], + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + genJetCollection = cms.InputTag(genJetsAK8Collection), + genParticles = cms.InputTag(gpLabel), + jetCorrections = ("AK8PFPuppi", cms.vstring(["L2Relative", "L3Absolute"]), "None"), + getJetMCFlavour = False # jet flavor disabled regardless if running on MC or data + ) + + # + # Soft-drop subjets + # + addJetCollection( + process, + labelName = "AK8PFPuppiSoftDropSubjets", + jetSource = cms.InputTag("ak8PFJetsPuppiSoftDrop", "SubJets"), + algo = "ak", # needed for subjet flavor clustering + rParam = 0.8, # needed for subjet flavor clustering + explicitJTA = True, # needed for subjet b tagging + svClustering = True, # needed for subjet b tagging + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + genJetCollection = cms.InputTag(genSubJetsForAK8Collection), + genParticles = cms.InputTag(gpLabel), + fatJets = cms.InputTag("ak8PFJetsPuppi"), # needed for subjet flavor clustering + groomedFatJets = cms.InputTag("ak8PFJetsPuppiSoftDrop"), # needed for subjet flavor clustering + jetCorrections = ("AK4PFPuppi", cms.vstring(["L2Relative", "L3Absolute"]), "None"), + ) + if hasattr(process,"patJetFlavourAssociationAK8PFPuppiSoftDropSubjets"): + process.patJetFlavourAssociationAK8PFPuppiSoftDropSubjets.weights = cms.InputTag(puppiLabel) + + #============================================= + # + # + # + #============================================= + # + # add groomed ECFs and N-subjettiness to soft dropped pat::Jets for fat jets and subjets + # + process.load('RecoJets.JetProducers.ECF_cff') + + addToProcessAndTask('nb1AK8PuppiSoftDrop', process.ecfNbeta1.clone( + src = cms.InputTag("ak8PFJetsPuppiSoftDrop"), + srcWeights = puppiLabel, + cuts = cms.vstring('', '', 'pt > 250') + ), + process, task + ) + process.patJetsAK8PFPuppiSoftDrop.userData.userFloats.src += [ + 'nb1AK8PuppiSoftDrop:ecfN2', + 'nb1AK8PuppiSoftDrop:ecfN3', + ] + + addToProcessAndTask('nb2AK8PuppiSoftDrop', process.ecfNbeta2.clone( + src = cms.InputTag("ak8PFJetsPuppiSoftDrop"), + srcWeights = puppiLabel, + cuts = cms.vstring('', '', 'pt > 250') + ), + process, task + ) + process.patJetsAK8PFPuppiSoftDrop.userData.userFloats.src += [ + 'nb2AK8PuppiSoftDrop:ecfN2', + 'nb2AK8PuppiSoftDrop:ecfN3', + ] + + # + # add groomed ECFs and N-subjettiness to soft drop subjets + # + addToProcessAndTask("nb1AK8PuppiSoftDropSubjets", process.ecfNbeta1.clone( + src = cms.InputTag("ak8PFJetsPuppiSoftDrop", "SubJets"), + srcWeights = puppiLabel, + ), + process, task + ) + + process.patJetsAK8PFPuppiSoftDropSubjets.userData.userFloats.src += [ + 'nb1AK8PuppiSoftDropSubjets:ecfN2', + 'nb1AK8PuppiSoftDropSubjets:ecfN3' + ] + + addToProcessAndTask("nb2AK8PuppiSoftDropSubjets", process.ecfNbeta2.clone( + src = cms.InputTag("ak8PFJetsPuppiSoftDrop", "SubJets"), + srcWeights = puppiLabel, + ), + process, task + ) + + process.patJetsAK8PFPuppiSoftDropSubjets.userData.userFloats.src += [ + 'nb2AK8PuppiSoftDropSubjets:ecfN2', + 'nb2AK8PuppiSoftDropSubjets:ecfN3' + ] + + addToProcessAndTask("NjettinessAK8Subjets", Njettiness.clone( + src = cms.InputTag("ak8PFJetsPuppiSoftDrop", "SubJets"), + srcWeights = puppiLabel + ), + process, task + ) + process.patJetsAK8PFPuppiSoftDropSubjets.userData.userFloats.src += [ + "NjettinessAK8Subjets:tau1", + "NjettinessAK8Subjets:tau2", + "NjettinessAK8Subjets:tau3", + "NjettinessAK8Subjets:tau4", + ] + + addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropSubjetsNoDeepTags", cms.EDProducer("PATJetSlimmer", + src = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"), + packedPFCandidates = cms.InputTag(pfLabel), + dropJetVars = cms.string("1"), + dropDaughters = cms.string("0"), + rekeyDaughters = cms.string("0"), + dropTrackRefs = cms.string("1"), + dropSpecific = cms.string("1"), + dropTagInfos = cms.string("1"), + modifyJets = cms.bool(True), + mixedDaughters = cms.bool(False), + modifierConfig = cms.PSet( modifications = cms.VPSet() ) + ), + process, task + ) + + updateJetCollection( + process, + labelName = "AK8PFPuppiSoftDropSubjets", + postfix = 'SlimmedDeepFlavour', + jetSource = cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjetsNoDeepTags"), + # updateJetCollection defaults to MiniAOD inputs but + # here it is made explicit (as in training or MINIAOD redoing) + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + jetCorrections = ("AK4PFPuppi", cms.vstring(["L2Relative", "L3Absolute"]), "None"), + printWarning = False, + btagDiscriminators = btagDiscriminatorsAK8Subjets.names.value() if btagDiscriminatorsAK8Subjets is not None else ['None'], + ) + + ## Establish references between PATified fat jets and subjets using the BoostedJetMerger + addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropPacked", cms.EDProducer("BoostedJetMerger", + jetSrc = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"), + subjetSrc = cms.InputTag("selectedUpdatedPatJetsAK8PFPuppiSoftDropSubjetsSlimmedDeepFlavour") + ), + process, task + ) + + addToProcessAndTask("packedPatJetsAK8", cms.EDProducer("JetSubstructurePacker", + jetSrc = cms.InputTag("selectedPatJetsAK8Puppi"), + distMax = cms.double(0.8), + algoTags = cms.VInputTag( + cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked") + ), + algoLabels = cms.vstring( + 'SoftDropPuppi' + ), + fixDaughters = cms.bool(False), + packedPFCandidates = cms.InputTag(pfLabel), + ), + process, task + ) + + #============================================= + # + # Update the selectedPatJet collection. + # This is where we setup + # - JEC + # - b-tagging discriminators + # + #============================================= + from PhysicsTools.PatAlgos.slimming.slimmedJets_cfi import slimmedJetsAK8 + addToProcessAndTask("slimmedJetsAK8NoDeepTags", slimmedJetsAK8.clone(rekeyDaughters = "0"), process, task) + # Reconfigure the slimmedAK8 jet information to keep + process.slimmedJetsAK8NoDeepTags.dropDaughters = cms.string("pt < 170") + process.slimmedJetsAK8NoDeepTags.dropSpecific = cms.string("pt < 170") + process.slimmedJetsAK8NoDeepTags.dropTagInfos = cms.string("pt < 170") + + updateJetCollection( + process, + jetSource = cms.InputTag("slimmedJetsAK8NoDeepTags"), + # updateJetCollection defaults to MiniAOD inputs but + # here it is made explicit (as in training or MINIAOD redoing) + pfCandidates = cms.InputTag(pfLabel), + pvSource = cms.InputTag(pvLabel), + svSource = cms.InputTag(svLabel), + muSource = cms.InputTag(muLabel), + elSource = cms.InputTag(elLabel), + rParam = 0.8, + jetCorrections = ('AK8PFPuppi', cms.vstring(["L2Relative", "L3Absolute"]), 'None'), + btagDiscriminators = btagDiscriminatorsAK8.names.value() if btagDiscriminatorsAK8 is not None else ['None'], + postfix = "SlimmedAK8DeepTags", + printWarning = False + ) + + addToProcessAndTask("slimmedJetsAK8", process.selectedUpdatedPatJetsSlimmedAK8DeepTags.clone(), process, task) + del process.selectedUpdatedPatJetsSlimmedAK8DeepTags + + ######################## + # + # Modify JECs when processing real Data + # Disable any MC-only features. + # + ######################## + if not(runOnMC): + runOnData(process, names=["Jets"], outputModules = []) + + return process +