From 60e013e49bea323af3703ae2941f3b93dbb92fb6 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 30 Nov 2020 16:29:29 +0100 Subject: [PATCH 1/8] final energy regression and ID for UL re-miniAOD --- .../lowPtElectronProducer_cff.py | 8 ++- .../lowPtElectronSelector_cfi.py | 6 +- .../plugins/LowPtGsfElectronFinalizer.cc | 65 +++++++++++++++++++ .../python/lowPtGsfElectronID_cff.py | 10 +++ .../python/lowPtGsfElectronSequence_cff.py | 2 +- ... => lowPtGsfElectronsPreRegression_cfi.py} | 8 +-- .../python/lowPtGsfElectrons_cff.py | 55 ++++++++++++++++ 7 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronFinalizer.cc rename RecoEgamma/EgammaElectronProducers/python/{lowPtGsfElectrons_cfi.py => lowPtGsfElectronsPreRegression_cfi.py} (89%) create mode 100644 RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py index 4a95b97d76edd..239ac2ce4a64a 100644 --- a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py +++ b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py @@ -26,8 +26,6 @@ ID = cms.InputTag("lowPtGsfElectronID"), ), - # Embedding of RECO/AOD items - # Embedding of RECO/AOD items embedTrack = True, embedGsfElectronCore = True, @@ -71,10 +69,16 @@ # Schedule rekeying of seed BDT ValueMaps by reco::GsfElectron for run2_miniAOD_UL and bParking from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL +from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel from Configuration.Eras.Modifier_bParking_cff import bParking + from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import rekeyLowPtGsfElectronSeedValueMaps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons + _makePatLowPtElectronsTask = makePatLowPtElectronsTask.copy() _makePatLowPtElectronsTask.add(rekeyLowPtGsfElectronSeedValueMaps) _makePatLowPtElectronsTask.add(lowPtGsfElectronID) (bParking | run2_miniAOD_UL).toReplaceWith(makePatLowPtElectronsTask,_makePatLowPtElectronsTask) +( (bParking & run2_miniAOD_UL) | (~bParking & run2_miniAOD_devel) ).toModify( + makePatLowPtElectronsTask, func = lambda t: t.add(lowPtGsfElectrons)) diff --git a/PhysicsTools/PatAlgos/python/selectionLayer1/lowPtElectronSelector_cfi.py b/PhysicsTools/PatAlgos/python/selectionLayer1/lowPtElectronSelector_cfi.py index 7ea6b50afd8b8..f040fd6147284 100644 --- a/PhysicsTools/PatAlgos/python/selectionLayer1/lowPtElectronSelector_cfi.py +++ b/PhysicsTools/PatAlgos/python/selectionLayer1/lowPtElectronSelector_cfi.py @@ -9,9 +9,13 @@ cut = cms.string("pt>1. && electronID('ID')>1.5"), ) +# Modifier for run2_miniAOD_devel +from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel +run2_miniAOD_devel.toModify(selectedPatLowPtElectrons,cut = "pt>1. && electronID('ID')>-0.25") + # Modifier for bParking (fully open selection) from Configuration.Eras.Modifier_bParking_cff import bParking -bParking.toModify(selectedPatLowPtElectrons,cut = "") +bParking.toModify(selectedPatLowPtElectrons,cut = "pt>1.") # Modifiers for legacy AOD from Configuration.Eras.Modifier_run2_miniAOD_80XLegacy_cff import run2_miniAOD_80XLegacy diff --git a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronFinalizer.cc b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronFinalizer.cc new file mode 100644 index 0000000000000..701e0f0a77d81 --- /dev/null +++ b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronFinalizer.cc @@ -0,0 +1,65 @@ +#include "CommonTools/CandAlgos/interface/ModifyObjectValueBase.h" +#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +class LowPtGsfElectronFinalizer : public edm::stream::EDProducer<> { +public: + explicit LowPtGsfElectronFinalizer(const edm::ParameterSet&); + + void produce(edm::Event&, const edm::EventSetup&) override; + + static void fillDescriptions(edm::ConfigurationDescriptions&); + +private: + const edm::EDGetTokenT<reco::GsfElectronCollection> previousGsfElectrons_; + std::unique_ptr<ModifyObjectValueBase> regression_; + + const edm::EDPutTokenT<reco::GsfElectronCollection> putToken_; +}; + +using edm::InputTag; +using reco::GsfElectronCollection; + +LowPtGsfElectronFinalizer::LowPtGsfElectronFinalizer(const edm::ParameterSet& cfg) + : previousGsfElectrons_{consumes<GsfElectronCollection>(cfg.getParameter<InputTag>("previousGsfElectronsTag"))}, + putToken_{produces<GsfElectronCollection>()} { + auto const& iconf = cfg.getParameterSet("regressionConfig"); + auto const& mname = iconf.getParameter<std::string>("modifierName"); + auto cc = consumesCollector(); + regression_.reset(ModifyObjectValueFactory::get()->create(mname, iconf, cc)); +} + +void LowPtGsfElectronFinalizer::produce(edm::Event& event, const edm::EventSetup& setup) { + // Setup regression for event + regression_->setEvent(event); + regression_->setEventContent(setup); + + // Create new modified electron collection + reco::GsfElectronCollection outputElectrons; + for (auto const& electron : event.get(previousGsfElectrons_)) { + outputElectrons.emplace_back(electron); + auto& newElectron = outputElectrons.back(); + regression_->modifyObject(newElectron); + } + + // Emplace modified electrons to event + event.emplace(putToken_, std::move(outputElectrons)); +} + +void LowPtGsfElectronFinalizer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add<edm::InputTag>("previousGsfElectronsTag", {}); + edm::ParameterSetDescription psd; + psd.setUnknown(); + desc.add<edm::ParameterSetDescription>("regressionConfig", psd); + descriptions.addWithDefaultLabel(desc); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(LowPtGsfElectronFinalizer); diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronID_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronID_cff.py index 15cb46811b4eb..91a9aafe31b01 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronID_cff.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronID_cff.py @@ -11,6 +11,8 @@ ) from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL +from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel +from Configuration.Eras.Modifier_bParking_cff import bParking run2_miniAOD_UL.toModify( lowPtGsfElectronID, rho = "fixedGridRhoFastjetAll", @@ -18,3 +20,11 @@ ModelThresholds = [-99.], Version = "V1", ) +run2_miniAOD_devel.toModify( + lowPtGsfElectronID, + ModelWeights = ["RecoEgamma/ElectronIdentification/data/LowPtElectrons/LowPtElectrons_ID_2020Nov28.root"], +) +(bParking & run2_miniAOD_UL).toModify( + lowPtGsfElectronID, + ModelWeights = ["RecoEgamma/ElectronIdentification/data/LowPtElectrons/LowPtElectrons_ID_2021May17.root"], +) diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py index 342eaf1a609e7..9f323046b8e52 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py @@ -63,7 +63,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronCores_cff import * # Low pT electrons -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import * +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons # Low pT Electron value maps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import lowPtGsfElectronSeedValueMaps diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronsPreRegression_cfi.py similarity index 89% rename from RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py rename to RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronsPreRegression_cfi.py index 8e0cfcd1bee30..e6d2faa55c3da 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronsPreRegression_cfi.py @@ -5,7 +5,7 @@ from RecoEgamma.EgammaIsolationAlgos.electronTrackIsolations_cfi import trkIsol03CfgV1,trkIsol04CfgV1 from RecoEgamma.EgammaIsolationAlgos.electronTrackIsolations_cfi import trkIsol03CfgV2,trkIsol04CfgV2 -lowPtGsfElectrons = cms.EDProducer( +lowPtGsfElectronsPreRegression = cms.EDProducer( "LowPtGsfElectronProducer", # input collections @@ -63,8 +63,8 @@ ) from Configuration.Eras.Modifier_fastSim_cff import fastSim -fastSim.toModify(lowPtGsfElectrons,ctfTracksTag = cms.InputTag("generalTracksBeforeMixing")) +fastSim.toModify(lowPtGsfElectronsPreRegression,ctfTracksTag = cms.InputTag("generalTracksBeforeMixing")) from Configuration.Eras.Modifier_pp_on_AA_2018_cff import pp_on_AA_2018 -pp_on_AA_2018.toModify(lowPtGsfElectrons.preselection, minSCEtBarrel = 15.0) -pp_on_AA_2018.toModify(lowPtGsfElectrons.preselection, minSCEtEndcaps = 15.0) +pp_on_AA_2018.toModify(lowPtGsfElectronsPreRegression.preselection, minSCEtBarrel = 15.0) +pp_on_AA_2018.toModify(lowPtGsfElectronsPreRegression.preselection, minSCEtEndcaps = 15.0) diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py new file mode 100644 index 0000000000000..ac32ecc504f42 --- /dev/null +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py @@ -0,0 +1,55 @@ +import FWCore.ParameterSet.Config as cms +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronsPreRegression_cfi import lowPtGsfElectronsPreRegression + +lowPtGsfElectrons = lowPtGsfElectronsPreRegression.clone() + +################################################################################ +# LowPtGsfElectronProducer above is run by default in RECO +# LowPtGsfElectronFinalizer below is scheduled for run2_miniAOD_UL + +from RecoEgamma.EgammaTools.regressionModifier_cfi import regressionModifier106XUL +_lowPtRegressionModifier = regressionModifier106XUL.clone( + modifierName = 'EGRegressionModifierV3', + rhoTag = 'fixedGridRhoFastjetAll', + eleRegs = dict( + ecalOnlyMean = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", + ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", + eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", + eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", + ), + ecalOnlySigma = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", + ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", + eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", + eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", + ), + epComb = dict( + ecalTrkRegressionConfig = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", + ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", + eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", + eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", + ), + ecalTrkRegressionUncertConfig = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", + ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", + eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", + eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", + ), + ) + ), +) + +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronFinalizer_cfi import lowPtGsfElectronFinalizer +_lowPtGsfElectrons = lowPtGsfElectronFinalizer.clone( + previousGsfElectronsTag = "lowPtGsfElectrons::@skipCurrentProcess", + regressionConfig = _lowPtRegressionModifier, +) + +from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL +run2_miniAOD_UL.toReplaceWith(lowPtGsfElectrons,_lowPtGsfElectrons) From 6c930923954a193fe5faa7c7ecffd8fd8b51c1f4 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Tue, 4 May 2021 18:09:56 +0200 Subject: [PATCH 2/8] add nanoAOD table for low pT electrons --- .../EgammaCandidates/interface/GsfElectron.h | 5 +- .../EgammaCandidates/src/GsfElectron.cc | 27 ++- .../NanoAOD/python/lowPtElectrons_cff.py | 205 +++++++++++++++++ PhysicsTools/NanoAOD/python/nanoDQM_cff.py | 1 + PhysicsTools/NanoAOD/python/nanoDQM_cfi.py | 47 ++++ PhysicsTools/NanoAOD/python/nano_cff.py | 7 +- .../lowPtElectronProducer_cff.py | 2 +- .../slimming/slimmedLowPtElectrons_cfi.py | 6 + .../LowPtGsfElectronIDHeavyObjectCache.h | 3 +- .../plugins/LowPtGsfElectronIDProducer.cc | 88 +++++--- .../python/lowPtGsfElectronSequence_cff.py | 2 +- .../python/lowPtGsfElectrons_cff.py | 4 +- .../python/lowPtGsfElectrons_cfi.py | 55 +++++ .../src/LowPtGsfElectronFeatures.cc | 9 +- .../src/LowPtGsfElectronIDHeavyObjectCache.cc | 44 ++-- RecoEgamma/EgammaTools/BuildFile.xml | 4 + .../EgammaTools/interface/LowPtConversion.h | 68 ++++++ .../plugins/EGRegressionModifierV3.cc | 4 +- .../plugins/LowPtElectronsModifier.cc | 82 +++++++ .../python/lowPtElectronModifier_cfi.py | 9 + RecoEgamma/EgammaTools/src/LowPtConversion.cc | 212 ++++++++++++++++++ 21 files changed, 801 insertions(+), 83 deletions(-) create mode 100644 PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py create mode 100644 RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py create mode 100644 RecoEgamma/EgammaTools/interface/LowPtConversion.h create mode 100644 RecoEgamma/EgammaTools/plugins/LowPtElectronsModifier.cc create mode 100644 RecoEgamma/EgammaTools/python/lowPtElectronModifier_cfi.py create mode 100644 RecoEgamma/EgammaTools/src/LowPtConversion.cc diff --git a/DataFormats/EgammaCandidates/interface/GsfElectron.h b/DataFormats/EgammaCandidates/interface/GsfElectron.h index 9ede5d64d8409..396b0249ee802 100644 --- a/DataFormats/EgammaCandidates/interface/GsfElectron.h +++ b/DataFormats/EgammaCandidates/interface/GsfElectron.h @@ -836,6 +836,7 @@ class GsfElectron : public RecoCandidate // setters void setCorrectedEcalEnergyError( float newEnergyError ) ; void setCorrectedEcalEnergy( float newEnergy ) ; + void setCorrectedEcalEnergy(float newEnergy, bool rescaleDependentValues); void setTrackMomentumError( float trackMomentumError ) ; void setP4( P4Kind kind, const LorentzVector & p4, float p4Error, bool setCandidate ) ; using RecoCandidate::setP4 ; @@ -861,9 +862,9 @@ class GsfElectron : public RecoCandidate //bool isMomentumCorrected() const { return corrections_.isMomentumCorrected ; } float caloEnergy() const { return correctedEcalEnergy() ; } bool isEnergyScaleCorrected() const { return isEcalEnergyCorrected() ; } - void correctEcalEnergy( float newEnergy, float newEnergyError ) + void correctEcalEnergy(float newEnergy, float newEnergyError, bool rescaleDependentValues = true) { - setCorrectedEcalEnergy(newEnergy) ; + setCorrectedEcalEnergy(newEnergy,rescaleDependentValues) ; setEcalEnergyError(newEnergyError) ; } void correctMomentum( const LorentzVector & p4, float trackMomentumError, float p4Error ) diff --git a/DataFormats/EgammaCandidates/src/GsfElectron.cc b/DataFormats/EgammaCandidates/src/GsfElectron.cc index 2bb17a115565e..300b2c4b5fb2a 100644 --- a/DataFormats/EgammaCandidates/src/GsfElectron.cc +++ b/DataFormats/EgammaCandidates/src/GsfElectron.cc @@ -179,18 +179,21 @@ bool GsfElectron::ecalDriven() const void GsfElectron::setCorrectedEcalEnergyError( float energyError ) { corrections_.correctedEcalEnergyError = energyError ; } -void GsfElectron::setCorrectedEcalEnergy( float newEnergy ) - { - math::XYZTLorentzVectorD momentum = p4() ; - momentum *= newEnergy/momentum.e() ; - setP4(momentum) ; - showerShape_.hcalDepth1OverEcal *= corrections_.correctedEcalEnergy/newEnergy ; - showerShape_.hcalDepth2OverEcal *= corrections_.correctedEcalEnergy/newEnergy ; - trackClusterMatching_.eSuperClusterOverP *= newEnergy/corrections_.correctedEcalEnergy ; - corrections_.correctedEcalEnergyError *= newEnergy/corrections_.correctedEcalEnergy ; - corrections_.correctedEcalEnergy = newEnergy ; - corrections_.isEcalEnergyCorrected = true ; - } +void GsfElectron::setCorrectedEcalEnergy(float newEnergy) { setCorrectedEcalEnergy(newEnergy, true); } + +void GsfElectron::setCorrectedEcalEnergy(float newEnergy, bool rescaleDependentValues) { + math::XYZTLorentzVectorD momentum = p4(); + momentum *= newEnergy / momentum.e(); + setP4(momentum); + if (corrections_.correctedEcalEnergy > 0. && rescaleDependentValues) { + showerShape_.hcalDepth1OverEcal *= corrections_.correctedEcalEnergy / newEnergy; + showerShape_.hcalDepth2OverEcal *= corrections_.correctedEcalEnergy / newEnergy; + trackClusterMatching_.eSuperClusterOverP *= newEnergy / corrections_.correctedEcalEnergy; + corrections_.correctedEcalEnergyError *= newEnergy / corrections_.correctedEcalEnergy; + } + corrections_.correctedEcalEnergy = newEnergy; + corrections_.isEcalEnergyCorrected = true; +} void GsfElectron::setTrackMomentumError( float trackErr ) { corrections_.trackMomentumError = trackErr ; } diff --git a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py new file mode 100644 index 0000000000000..9caa8f29e315a --- /dev/null +++ b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py @@ -0,0 +1,205 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.nano_eras_cff import * +from PhysicsTools.NanoAOD.common_cff import * + +################################################################################ +# Modules +################################################################################ + +from RecoEgamma.EgammaTools.lowPtElectronModifier_cfi import lowPtElectronModifier +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtRegressionModifier +modifiedLowPtElectrons = cms.EDProducer( + "ModifiedElectronProducer", + src = cms.InputTag("slimmedLowPtElectrons"), + modifierConfig = cms.PSet( + modifications = cms.VPSet(lowPtElectronModifier,lowPtRegressionModifier) + ) +) + +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID +lowPtPATElectronID = lowPtGsfElectronID.clone( + usePAT = True, + electrons = "modifiedLowPtElectrons", + unbiased = "", + ModelWeights = [ + 'RecoEgamma/ElectronIdentification/data/LowPtElectrons/LowPtElectrons_ID_2020Nov28.root', + ], + Version = cms.string('V1'), + rho = "fixedGridRhoFastjetAll", +) + +isoForLowPtEle = cms.EDProducer( + "EleIsoValueMapProducer", + src = cms.InputTag("modifiedLowPtElectrons"), + relative = cms.bool(False), + rho_MiniIso = cms.InputTag("fixedGridRhoFastjetAll"), + rho_PFIso = cms.InputTag("fixedGridRhoFastjetAll"), + EAFile_MiniIso = cms.FileInPath("RecoEgamma/ElectronIdentification/data/Fall17/effAreaElectrons_cone03_pfNeuHadronsAndPhotons_94X.txt"), + EAFile_PFIso = cms.FileInPath("RecoEgamma/ElectronIdentification/data/Fall17/effAreaElectrons_cone03_pfNeuHadronsAndPhotons_94X.txt"), +) + +updatedLowPtElectronsWithUserData = cms.EDProducer( + "PATElectronUserDataEmbedder", + src = cms.InputTag("modifiedLowPtElectrons"), + userFloats = cms.PSet( + ID = cms.InputTag("lowPtPATElectronID"), + miniIsoChg = cms.InputTag("isoForLowPtEle:miniIsoChg"), + miniIsoAll = cms.InputTag("isoForLowPtEle:miniIsoAll"), + ), + userIntFromBools = cms.PSet(), + userInts = cms.PSet(), + userCands = cms.PSet(), +) + +finalLowPtElectrons = cms.EDFilter( + "PATElectronRefSelector", + src = cms.InputTag("updatedLowPtElectronsWithUserData"), + cut = cms.string("pt > 1. && userFloat('ID') > -0.25"), +) + +################################################################################ +# electronTable +################################################################################ + +lowPtElectronTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src = cms.InputTag("finalLowPtElectrons"), + cut = cms.string(""), + name= cms.string("LowPtElectron"), + doc = cms.string("slimmedLowPtElectrons after basic selection (" + finalLowPtElectrons.cut.value()+")"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the electrons + variables = cms.PSet( + # Basic variables + CandVars, + # BDT scores and WPs + embeddedID = Var("electronID('ID')",float,doc="ID, BDT (raw) score"), + ID = Var("userFloat('ID')",float,doc="New ID, BDT (raw) score"), + unbiased = Var("electronID('unbiased')",float,doc="ElectronSeed, pT- and dxy- agnostic BDT (raw) score"), + ptbiased = Var("electronID('ptbiased')",float,doc="ElectronSeed, pT- and dxy- dependent BDT (raw) score"), + # Isolation + miniPFRelIso_chg = Var("userFloat('miniIsoChg')/pt",float, + doc="mini PF relative isolation, charged component"), + miniPFRelIso_all = Var("userFloat('miniIsoAll')/pt",float, + doc="mini PF relative isolation, total (with scaled rho*EA PU corrections)"), + # Conversions + convVeto = Var("passConversionVeto()",bool,doc="pass conversion veto"), + convWP = Var("userInt('convOpen')*1 + userInt('convLoose')*2 + userInt('convTight')*4", + int,doc="conversion flag bit map: 1=Veto, 2=Loose, 3=Tight"), + convVtxRadius = Var("userFloat('convVtxRadius')",float,doc="conversion vertex radius (cm)",precision=7), + # Tracking + lostHits = Var("gsfTrack.hitPattern.numberOfLostHits('MISSING_INNER_HITS')","uint8",doc="number of missing inner hits"), + # Cluster-related + energyErr = Var("p4Error('P4_COMBINATION')",float,doc="energy error of the cluster-track combination",precision=6), + deltaEtaSC = Var("superCluster().eta()-eta()",float,doc="delta eta (SC,ele) with sign",precision=10), + r9 = Var("full5x5_r9()",float,doc="R9 of the SC, calculated with full 5x5 region",precision=10), + sieie = Var("full5x5_sigmaIetaIeta()",float,doc="sigma_IetaIeta of the SC, calculated with full 5x5 region",precision=10), + eInvMinusPInv = Var("(1-eSuperClusterOverP())/ecalEnergy()",float,doc="1/E_SC - 1/p_trk",precision=10), + scEtOverPt = Var("(superCluster().energy()/(pt*cosh(superCluster().eta())))-1",float,doc="(SC energy)/pt-1",precision=8), + hoe = Var("hadronicOverEm()",float,doc="H over E",precision=8), + # Displacement + dxy = Var("dB('PV2D')",float,doc="dxy (with sign) wrt first PV, in cm",precision=10), + dxyErr = Var("edB('PV2D')",float,doc="dxy uncertainty, in cm",precision=6), + dz = Var("dB('PVDZ')",float,doc="dz (with sign) wrt first PV, in cm",precision=10), + dzErr = Var("abs(edB('PVDZ'))",float,doc="dz uncertainty, in cm",precision=6), + ip3d = Var("abs(dB('PV3D'))",float,doc="3D impact parameter wrt first PV, in cm",precision=10), + sip3d = Var("abs(dB('PV3D')/edB('PV3D'))",float,doc="3D impact parameter significance wrt first PV, in cm",precision=10), + # Cross-referencing + #jetIdx + #photonIdx + ), +) + +################################################################################ +# electronTable (MC) +################################################################################ + +from PhysicsTools.NanoAOD.particlelevel_cff import particleLevel +particleLevelForMatchingLowPt = particleLevel.clone( + lepMinPt = cms.double(1.), + phoMinPt = cms.double(1), +) + +tautaggerForMatchingLowPt = cms.EDProducer( + "GenJetTauTaggerProducer", + src = cms.InputTag('particleLevelForMatchingLowPt:leptons') +) + +matchingLowPtElecPhoton = cms.EDProducer( + "GenJetGenPartMerger", + srcJet =cms.InputTag("particleLevelForMatchingLowPt:leptons"), + srcPart=cms.InputTag("particleLevelForMatchingLowPt:photons"), + hasTauAnc=cms.InputTag("tautaggerForMatchingLowPt"), +) + +lowPtElectronsMCMatchForTableAlt = cms.EDProducer( + "GenJetMatcherDRPtByDR", # cut on deltaR, deltaPt/Pt; pick best by deltaR + src = lowPtElectronTable.src, # final reco collection + matched = cms.InputTag("matchingLowPtElecPhoton:merged"), # final mc-truth particle collection + mcPdgId = cms.vint32(11,22), # one or more PDG ID (11 = el, 22 = pho); absolute values (see below) + checkCharge = cms.bool(False), # True = require RECO and MC objects to have the same charge + mcStatus = cms.vint32(), + maxDeltaR = cms.double(0.3), # Minimum deltaR for the match + maxDPtRel = cms.double(0.5), # Minimum deltaPt/Pt for the match + resolveAmbiguities = cms.bool(True), # Forbid two RECO objects to match to the same GEN object + resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first +) + +lowPtElectronsMCMatchForTable = cms.EDProducer( + "MCMatcher", # cut on deltaR, deltaPt/Pt; pick best by deltaR + src = lowPtElectronTable.src, # final reco collection + matched = cms.InputTag("finalGenParticles"), # final mc-truth particle collection + mcPdgId = cms.vint32(11), # one or more PDG ID (11 = ele); absolute values (see below) + checkCharge = cms.bool(False), # True = require RECO and MC objects to have the same charge + mcStatus = cms.vint32(1), # PYTHIA status code (1 = stable, 2 = shower, 3 = hard scattering) + maxDeltaR = cms.double(0.3), # Minimum deltaR for the match + maxDPtRel = cms.double(0.5), # Minimum deltaPt/Pt for the match + resolveAmbiguities = cms.bool(True), # Forbid two RECO objects to match to the same GEN object + resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first +) + +from PhysicsTools.NanoAOD.electrons_cff import electronMCTable +lowPtElectronMCTable = cms.EDProducer( + "CandMCMatchTableProducer", + src = lowPtElectronTable.src, + mcMapDressedLep = cms.InputTag("lowPtElectronsMCMatchForTableAlt"), + mcMap = cms.InputTag("lowPtElectronsMCMatchForTable"), + mapTauAnc = cms.InputTag("matchingLowPtElecPhoton:hasTauAnc"), + objName = lowPtElectronTable.name, + objType = electronMCTable.objType, + branchName = cms.string("genPart"), + docString = cms.string("MC matching to status==1 electrons or photons"), + genparticles = cms.InputTag("finalGenParticles"), +) + +################################################################################ +# Sequences +################################################################################ + +lowPtElectronSequence = cms.Sequence(modifiedLowPtElectrons + +lowPtPATElectronID + +isoForLowPtEle + +updatedLowPtElectronsWithUserData + +finalLowPtElectrons) +lowPtElectronTables = cms.Sequence(lowPtElectronTable) +lowPtElectronMC = cms.Sequence( + particleLevelForMatchingLowPt + +tautaggerForMatchingLowPt + +matchingLowPtElecPhoton + +lowPtElectronsMCMatchForTable + +lowPtElectronsMCMatchForTableAlt + +lowPtElectronMCTable) + +################################################################################ +# Modifiers +################################################################################ + +_modifiers = ( run2_miniAOD_80XLegacy | + run2_nanoAOD_94XMiniAODv1 | + run2_nanoAOD_94XMiniAODv2 | + run2_nanoAOD_94X2016 | + run2_nanoAOD_102Xv1 | + run2_nanoAOD_106Xv1 ) +(_modifiers).toReplaceWith(lowPtElectronSequence,cms.Sequence()) +(_modifiers).toReplaceWith(lowPtElectronTables,cms.Sequence()) +(_modifiers).toReplaceWith(lowPtElectronMC,cms.Sequence()) diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cff.py b/PhysicsTools/NanoAOD/python/nanoDQM_cff.py index 64f0a42b0cbe1..4211f6f1c35bb 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cff.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cff.py @@ -146,6 +146,7 @@ ## MC nanoDQMMC = nanoDQM.clone() nanoDQMMC.vplots.Electron.sels.Prompt = cms.string("genPartFlav == 1") +nanoDQMMC.vplots.LowPtElectron.sels.Prompt = cms.string("genPartFlav == 1") nanoDQMMC.vplots.Muon.sels.Prompt = cms.string("genPartFlav == 1") nanoDQMMC.vplots.Photon.sels.Prompt = cms.string("genPartFlav == 1") nanoDQMMC.vplots.Tau.sels.Prompt = cms.string("genPartFlav == 5") diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py index e09841d031466..d1ec4b5f9f471 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py @@ -112,6 +112,53 @@ Plot1D('dEsigmaDown', 'dEsigmaDown', 100, -0.1, 0.1, '#Delta E sigmaDown'), ) ), + + LowPtElectron = cms.PSet( + sels = cms.PSet( + Good = cms.string('pt > 1. && ID > 5.') + ), + plots = cms.VPSet( + # + Count1D('_size', 8, -0.5, 7.5, 'slimmedLowPtElectrons after basic selection'), + # CandVars + Plot1D('charge', 'charge', 3, -1.5, 1.5, 'electric charge'), + Plot1D('eta', 'eta', 20, -3., 3., 'eta'), + NoPlot('mass'), + Plot1D('pdgId', 'pdgId', 101, -50.5, 50.5, 'PDG code assigned by the event reconstruction (not by MC truth)'), + Plot1D('phi', 'phi', 20, -3.14159, 3.14159, 'phi'), + Plot1D('pt', 'pt', 40, 0., 20., 'pt (corrected)'), + # BDT scores and WPs + Plot1D('embeddedID', 'embeddedID', 40, -10., 10., 'Embedded ID, BDT (raw) score'), + Plot1D('ID', 'ID', 40, -10., 10., 'ID, BDT (raw) score'), + Plot1D('unbiased', 'unbiased', 40, -10., 10., 'ElectronSeed, pT- and dxy- agnostic BDT (raw) score'), + Plot1D('ptbiased', 'ptbiased', 40, -10., 10., 'ElectronSeed, pT- and dxy- dependent BDT (raw) score'), + # Isolation + Plot1D('miniPFRelIso_chg', 'miniPFRelIso_chg', 20, 0, 2, 'mini PF relative isolation, charged component'), + Plot1D('miniPFRelIso_all', 'miniPFRelIso_all', 20, 0, 2, 'mini PF relative isolation, total (with scaled rho*EA PU corrections)'), + # Conversions + Plot1D('convVeto', 'convVeto', 2, -0.5, 1.5, 'pass conversion veto'), + Plot1D('convWP', 'convWP', 8, -0.5, 7.5, 'conversion flag bit map: 1=Veto, 2=Loose, 3=Tight'), + Plot1D('convVtxRadius', 'convVtxRadius', 40, 0., 20.0, 'conversion vertex radius (cm)'), + # Tracking + Plot1D('lostHits', 'lostHits', 4, -0.5, 3.5, 'number of missing inner hits'), + # Cluster-related + Plot1D('energyErr', 'energyErr', 40, 0., 20., 'energy error of the cluster from regression'), + Plot1D('deltaEtaSC', 'deltaEtaSC', 20, -0.2, 0.2, 'delta eta (SC,ele) with sign'), + Plot1D('r9', 'r9', 20, 0, 1.1, 'R9 of the supercluster, calculated with full 5x5 region'), + Plot1D('sieie', 'sieie', 20, 0, 0.05, 'sigma_IetaIeta of the supercluster, calculated with full 5x5 region'), + Plot1D('eInvMinusPInv', 'eInvMinusPInv', 20, -0.1, 0.1, '1/E_SC - 1/p_trk'), + Plot1D('scEtOverPt', 'scEtOverPt', 20, -0.5, 0.5, '(supercluster transverse energy)/pt - 1'), + Plot1D('hoe', 'hoe', 20, 0, 0.6, 'H over E'), + # Displacement + Plot1D('dxy', 'dxy', 20, -0.1, 0.1, 'dxy (with sign) wrt first PV, in cm'), + Plot1D('dz', 'dz', 20, -0.3, 0.3, 'dz (with sign) wrt first PV, in cm'), + Plot1D('dxyErr', 'dxyErr', 20, 0., 0.2, 'dxy uncertainty, in cm'), + Plot1D('dzErr', 'dzErr', 20, 0., 0.2, 'dz uncertainty, in cm'), + Plot1D('ip3d', 'ip3d', 20, 0., 0.2, '3D impact parameter wrt first PV, in cm'), + Plot1D('sip3d', 'sip3d', 20, 0., 20., '3D impact parameter significance wrt first PV, in cm'), + ), + ), + FatJet = cms.PSet( sels = cms.PSet(), plots = cms.VPSet( diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 529f1d18fcab6..4d902347cc43f 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -7,6 +7,7 @@ from PhysicsTools.NanoAOD.taus_cff import * from PhysicsTools.NanoAOD.boostedTaus_cff import * from PhysicsTools.NanoAOD.electrons_cff import * +from PhysicsTools.NanoAOD.lowPtElectrons_cff import * from PhysicsTools.NanoAOD.photons_cff import * from PhysicsTools.NanoAOD.globals_cff import * from PhysicsTools.NanoAOD.extraflags_cff import * @@ -107,10 +108,10 @@ (run2_miniAOD_80XLegacy | run2_nanoAOD_94X2016 | run2_nanoAOD_94XMiniAODv1 | run2_nanoAOD_94XMiniAODv2 | run2_nanoAOD_102Xv1).toModify(l1bits, storeUnprefireableBit=False) nanoSequenceCommon = cms.Sequence( - nanoMetadata + jetSequence + muonSequence + tauSequence + boostedTauSequence + electronSequence+photonSequence+vertexSequence+ + nanoMetadata + jetSequence + muonSequence + tauSequence + boostedTauSequence + electronSequence + lowPtElectronSequence + photonSequence+vertexSequence+ isoTrackSequence + jetLepSequence + # must be after all the leptons linkedObjects + - jetTables + muonTables + tauTables + boostedTauTables + electronTables + photonTables + globalTables +vertexTables+ metTables+simpleCleanerTable + isoTrackTables + jetTables + muonTables + tauTables + boostedTauTables + electronTables + lowPtElectronTables + photonTables + globalTables +vertexTables+ metTables+simpleCleanerTable + isoTrackTables ) #remove boosted tau from previous eras (run2_miniAOD_80XLegacy | run2_nanoAOD_92X | run2_nanoAOD_94XMiniAODv1 | run2_nanoAOD_94X2016 | run2_nanoAOD_94XMiniAODv2 | run2_nanoAOD_102Xv1 | run2_nanoAOD_106Xv1).toReplaceWith(nanoSequenceCommon, nanoSequenceCommon.copyAndExclude([boostedTauSequence, boostedTauTables])) @@ -123,7 +124,7 @@ ( run2_nanoAOD_106Xv1 & ~run2_nanoAOD_devel).toReplaceWith(nanoSequence, nanoSequence.copyAndExclude([nanoSequenceOnlyData])) -nanoSequenceFS = cms.Sequence(genParticleSequence + genVertexTables + particleLevelSequence + nanoSequenceCommon + jetMC + muonMC + electronMC + photonMC + tauMC + boostedTauMC + metMC + ttbarCatMCProducers + globalTablesMC + btagWeightTable + genWeightsTable + genVertexTable + genParticleTables + particleLevelTables + lheInfoTable + ttbarCategoryTable ) +nanoSequenceFS = cms.Sequence(genParticleSequence + genVertexTables + particleLevelSequence + nanoSequenceCommon + jetMC + muonMC + electronMC + lowPtElectronMC + photonMC + tauMC + boostedTauMC + metMC + ttbarCatMCProducers + globalTablesMC + btagWeightTable + genWeightsTable + genVertexTable + genParticleTables + particleLevelTables + lheInfoTable + ttbarCategoryTable ) (run2_nanoAOD_92X | run2_miniAOD_80XLegacy | run2_nanoAOD_94X2016 | run2_nanoAOD_94X2016 | \ run2_nanoAOD_94XMiniAODv1 | run2_nanoAOD_94XMiniAODv2 | \ diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py index 239ac2ce4a64a..97a8a7f540b6c 100644 --- a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py +++ b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py @@ -74,7 +74,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import rekeyLowPtGsfElectronSeedValueMaps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtGsfElectrons _makePatLowPtElectronsTask = makePatLowPtElectronsTask.copy() _makePatLowPtElectronsTask.add(rekeyLowPtGsfElectronSeedValueMaps) diff --git a/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py b/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py index 684512a4ce0fd..0bcd2fb7a5000 100644 --- a/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py +++ b/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py @@ -43,3 +43,9 @@ ) ) +from RecoEgamma.EgammaTools.lowPtElectronModifier_cfi import lowPtElectronModifier +from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel +from Configuration.Eras.Modifier_bParking_cff import bParking +_slimmedLowPtElectrons = slimmedLowPtElectrons.clone() +_slimmedLowPtElectrons.modifierConfig.modifications += [lowPtElectronModifier] +(~bParking & run2_miniAOD_devel).toReplaceWith(slimmedLowPtElectrons,_slimmedLowPtElectrons) diff --git a/RecoEgamma/EgammaElectronProducers/interface/LowPtGsfElectronIDHeavyObjectCache.h b/RecoEgamma/EgammaElectronProducers/interface/LowPtGsfElectronIDHeavyObjectCache.h index 0356c3de940b3..4592ce7ebfd02 100644 --- a/RecoEgamma/EgammaElectronProducers/interface/LowPtGsfElectronIDHeavyObjectCache.h +++ b/RecoEgamma/EgammaElectronProducers/interface/LowPtGsfElectronIDHeavyObjectCache.h @@ -45,7 +45,8 @@ namespace lowptgsfeleid { float ele_pt_ = -1.; public: std::vector<float> get(); - void set( const reco::GsfElectronRef& ele, double rho ); + inline void set( const reco::GsfElectronRef& ele, double rho ) { set(*ele, rho); } + void set( const reco::GsfElectron& ele, double rho ); }; class HeavyObjectCache { diff --git a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronIDProducer.cc b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronIDProducer.cc index 6390a6e3d9fc3..1a3c5c2e1f478 100644 --- a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronIDProducer.cc +++ b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronIDProducer.cc @@ -35,11 +35,13 @@ class LowPtGsfElectronIDProducer final : public edm::global::EDProducer<> { static void fillDescriptions(edm::ConfigurationDescriptions&); private: - double eval(const std::string& name, const reco::GsfElectronRef&, double rho, float unbiased, float field_z) const; + double eval(const std::string& name, const edm::Ptr<reco::GsfElectron>&, double rho, float unbiased, float field_z) const; - const edm::EDGetTokenT<reco::GsfElectronCollection> electrons_; + const bool usePAT_; + edm::EDGetTokenT<reco::GsfElectronCollection> electrons_; + edm::EDGetTokenT<pat::ElectronCollection> patElectrons_; const edm::EDGetTokenT<double> rho_; - const edm::EDGetTokenT<edm::ValueMap<float> > unbiased_; + edm::EDGetTokenT<edm::ValueMap<float> > unbiased_; const std::vector<std::string> names_; const bool passThrough_; const double minPtThreshold_; @@ -52,15 +54,23 @@ class LowPtGsfElectronIDProducer final : public edm::global::EDProducer<> { //////////////////////////////////////////////////////////////////////////////// // LowPtGsfElectronIDProducer::LowPtGsfElectronIDProducer(const edm::ParameterSet& conf) - : electrons_(consumes<reco::GsfElectronCollection>(conf.getParameter<edm::InputTag>("electrons"))), + : usePAT_(conf.getParameter<bool>("usePAT")), + electrons_(), + patElectrons_(), rho_(consumes<double>(conf.getParameter<edm::InputTag>("rho"))), - unbiased_(consumes<edm::ValueMap<float> >(conf.getParameter<edm::InputTag>("unbiased"))), + unbiased_(), names_(conf.getParameter<std::vector<std::string> >("ModelNames")), passThrough_(conf.getParameter<bool>("PassThrough")), minPtThreshold_(conf.getParameter<double>("MinPtThreshold")), maxPtThreshold_(conf.getParameter<double>("MaxPtThreshold")), thresholds_(conf.getParameter<std::vector<double> >("ModelThresholds")), version_(conf.getParameter<std::string>("Version")) { + if (usePAT_) { + patElectrons_ = consumes<pat::ElectronCollection>(conf.getParameter<edm::InputTag>("electrons")); + } else { + electrons_ = consumes<reco::GsfElectronCollection>(conf.getParameter<edm::InputTag>("electrons")); + unbiased_ = consumes<edm::ValueMap<float> >(conf.getParameter<edm::InputTag>("unbiased")); + } for (auto& weights : conf.getParameter<std::vector<std::string> >("ModelWeights")) { models_.push_back(createGBRForest(edm::FileInPath(weights))); } @@ -97,39 +107,52 @@ void LowPtGsfElectronIDProducer::produce(edm::StreamID, edm::Event& event, const throw cms::Exception("InvalidHandle", os.str()); } - // Retrieve GsfElectrons from Event + // Retrieve pat::Electrons or reco::GsfElectrons from Event + edm::Handle<pat::ElectronCollection> patElectrons; edm::Handle<reco::GsfElectronCollection> electrons; - event.getByToken(electrons_, electrons); - if (!electrons.isValid()) { - std::ostringstream os; - os << "Problem accessing low-pT electrons collection" << std::endl; - throw cms::Exception("InvalidHandle", os.str()); + if (usePAT_) { + event.getByToken(patElectrons_, patElectrons); + } else { + event.getByToken(electrons_, electrons); } // ElectronSeed unbiased BDT edm::Handle<edm::ValueMap<float> > unbiasedH; - event.getByToken(unbiased_, unbiasedH); + if (!unbiased_.isUninitialized()) { + event.getByToken(unbiased_, unbiasedH); + } // Iterate through Electrons, evaluate BDT, and store result std::vector<std::vector<float> > output; + unsigned int nElectrons = usePAT_ ? patElectrons->size() : electrons->size(); for (unsigned int iname = 0; iname < names_.size(); ++iname) { - output.emplace_back(electrons->size(), -999.); + output.emplace_back(nElectrons, -999.); } - for (unsigned int iele = 0; iele < electrons->size(); iele++) { - reco::GsfElectronRef ele(electrons, iele); - if (ele->core().isNull()) { - continue; - } - const auto& gsf = ele->core()->gsfTrack(); // reco::GsfTrackRef - if (gsf.isNull()) { - continue; + if (usePAT_) { + for (unsigned int iele = 0; iele < nElectrons; iele++) { + edm::Ptr<pat::Electron> ele(patElectrons, iele); + if (!ele->isElectronIDAvailable("unbiased")) { + continue; + } + for (unsigned int iname = 0; iname < names_.size(); ++iname) { + output[iname][iele] = eval(names_[iname], ele, *rho, ele->electronID("unbiased"), zfield.z()); + } } - float unbiased = (*unbiasedH)[gsf]; - - //if ( !passThrough_ && ( ele->pt() < minPtThreshold_ ) ) { continue; } - for (unsigned int iname = 0; iname < names_.size(); ++iname) { - output[iname][iele] = eval(names_[iname], ele, *rho, unbiased, zfield.z()); + } else { + for (unsigned int iele = 0; iele < nElectrons; iele++) { + edm::Ptr<reco::GsfElectron> ele(electrons, iele); + if (ele->core().isNull()) { + continue; + } + const auto& gsf = ele->core()->gsfTrack(); // reco::GsfTrackRef + if (gsf.isNull()) { + continue; + } + float unbiased = (*unbiasedH)[gsf]; + for (unsigned int iname = 0; iname < names_.size(); ++iname) { + output[iname][iele] = eval(names_[iname], ele, *rho, unbiased, zfield.z()); + } } } @@ -137,7 +160,11 @@ void LowPtGsfElectronIDProducer::produce(edm::StreamID, edm::Event& event, const for (unsigned int iname = 0; iname < names_.size(); ++iname) { auto ptr = std::make_unique<edm::ValueMap<float> >(edm::ValueMap<float>()); edm::ValueMap<float>::Filler filler(*ptr); - filler.insert(electrons, output[iname].begin(), output[iname].end()); + if (usePAT_) { + filler.insert(patElectrons, output[iname].begin(), output[iname].end()); + } else { + filler.insert(electrons, output[iname].begin(), output[iname].end()); + } filler.fill(); event.put(std::move(ptr), names_[iname]); } @@ -146,14 +173,14 @@ void LowPtGsfElectronIDProducer::produce(edm::StreamID, edm::Event& event, const ////////////////////////////////////////////////////////////////////////////////////////// // double LowPtGsfElectronIDProducer::eval( - const std::string& name, const reco::GsfElectronRef& ele, double rho, float unbiased, float field_z) const { + const std::string& name, const edm::Ptr<reco::GsfElectron>& ele, double rho, float unbiased, float field_z) const { auto iter = std::find(names_.begin(), names_.end(), name); if (iter != names_.end()) { int index = std::distance(names_.begin(), iter); std::vector<float> inputs; if (version_.empty()) { // Original XML model lowptgsfeleid::Features features; - features.set(ele, rho); + features.set(*ele, rho); inputs = features.get(); } else if (version_ == "V0") { inputs = lowptgsfeleid::features_V0(*ele, rho, unbiased); @@ -171,8 +198,9 @@ double LowPtGsfElectronIDProducer::eval( // void LowPtGsfElectronIDProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; + desc.add<bool>("usePAT", false); desc.add<edm::InputTag>("electrons", edm::InputTag("lowPtGsfElectrons")); - desc.add<edm::InputTag>("unbiased", edm::InputTag("lowPtGsfElectronSeedValueMaps:unbiased")); + desc.addOptional<edm::InputTag>("unbiased", edm::InputTag("lowPtGsfElectronSeedValueMaps:unbiased")); desc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoFastjetAllTmp")); desc.add<std::vector<std::string> >("ModelNames", std::vector<std::string>()); desc.add<std::vector<std::string> >("ModelWeights", std::vector<std::string>()); diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py index 9f323046b8e52..85484aab0bfbf 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py @@ -63,7 +63,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronCores_cff import * # Low pT electrons -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtGsfElectrons # Low pT Electron value maps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import lowPtGsfElectronSeedValueMaps diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py index ac32ecc504f42..30a9f5f11af9d 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cff.py @@ -8,7 +8,7 @@ # LowPtGsfElectronFinalizer below is scheduled for run2_miniAOD_UL from RecoEgamma.EgammaTools.regressionModifier_cfi import regressionModifier106XUL -_lowPtRegressionModifier = regressionModifier106XUL.clone( +lowPtRegressionModifier = regressionModifier106XUL.clone( modifierName = 'EGRegressionModifierV3', rhoTag = 'fixedGridRhoFastjetAll', eleRegs = dict( @@ -48,7 +48,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronFinalizer_cfi import lowPtGsfElectronFinalizer _lowPtGsfElectrons = lowPtGsfElectronFinalizer.clone( previousGsfElectronsTag = "lowPtGsfElectrons::@skipCurrentProcess", - regressionConfig = _lowPtRegressionModifier, + regressionConfig = lowPtRegressionModifier, ) from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py new file mode 100644 index 0000000000000..30a9f5f11af9d --- /dev/null +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py @@ -0,0 +1,55 @@ +import FWCore.ParameterSet.Config as cms +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronsPreRegression_cfi import lowPtGsfElectronsPreRegression + +lowPtGsfElectrons = lowPtGsfElectronsPreRegression.clone() + +################################################################################ +# LowPtGsfElectronProducer above is run by default in RECO +# LowPtGsfElectronFinalizer below is scheduled for run2_miniAOD_UL + +from RecoEgamma.EgammaTools.regressionModifier_cfi import regressionModifier106XUL +lowPtRegressionModifier = regressionModifier106XUL.clone( + modifierName = 'EGRegressionModifierV3', + rhoTag = 'fixedGridRhoFastjetAll', + eleRegs = dict( + ecalOnlyMean = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", + ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", + eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", + eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", + ), + ecalOnlySigma = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", + ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", + eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", + eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", + ), + epComb = dict( + ecalTrkRegressionConfig = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", + ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", + eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", + eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", + ), + ecalTrkRegressionUncertConfig = dict( + lowEtHighEtBoundary = 20., + ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", + ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", + eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", + eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", + ), + ) + ), +) + +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronFinalizer_cfi import lowPtGsfElectronFinalizer +_lowPtGsfElectrons = lowPtGsfElectronFinalizer.clone( + previousGsfElectronsTag = "lowPtGsfElectrons::@skipCurrentProcess", + regressionConfig = lowPtRegressionModifier, +) + +from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL +run2_miniAOD_UL.toReplaceWith(lowPtGsfElectrons,_lowPtGsfElectrons) diff --git a/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronFeatures.cc b/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronFeatures.cc index 5ab6abae8129a..8488c7af30947 100644 --- a/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronFeatures.cc +++ b/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronFeatures.cc @@ -3,6 +3,7 @@ #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h" +#include "DataFormats/PatCandidates/interface/Electron.h" #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "TVector3.h" @@ -62,7 +63,7 @@ namespace lowptgsfeleid { // GSF tracks if (ele.core().isNonnull()) { - reco::GsfTrackRef gsf = ele.core()->gsfTrack(); + reco::GsfTrackRef gsf = ele.gsfTrack(); if (gsf.isNonnull()) { gsf_mode_p = gsf->pMode(); eid_gsf_nhits = (float)gsf->found(); @@ -77,7 +78,7 @@ namespace lowptgsfeleid { // Super clusters if (ele.core().isNonnull()) { - reco::SuperClusterRef sc = ele.core()->superCluster(); + reco::SuperClusterRef sc = ele.superCluster(); if (sc.isNonnull()) { eid_sc_E = sc->energy(); eid_sc_eta = sc->eta(); @@ -109,9 +110,9 @@ namespace lowptgsfeleid { // Clusters if (ele.core().isNonnull()) { - reco::GsfTrackRef gsf = ele.core()->gsfTrack(); + reco::GsfTrackRef gsf = ele.gsfTrack(); if (gsf.isNonnull()) { - reco::SuperClusterRef sc = ele.core()->superCluster(); + reco::SuperClusterRef sc = ele.superCluster(); if (sc.isNonnull()) { // Propagate electron track to ECAL surface double mass2 = 0.000511 * 0.000511; diff --git a/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronIDHeavyObjectCache.cc b/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronIDHeavyObjectCache.cc index c15899fb0208d..8fcf71aabcf66 100644 --- a/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronIDHeavyObjectCache.cc +++ b/RecoEgamma/EgammaElectronProducers/src/LowPtGsfElectronIDHeavyObjectCache.cc @@ -44,11 +44,11 @@ namespace lowptgsfeleid { //////////////////////////////////////////////////////////////////////////////// // - void Features::set( const reco::GsfElectronRef& ele, double rho ) { + void Features::set( const reco::GsfElectron& ele, double rho ) { // KF tracks - if ( ele->core().isNonnull() ) { - reco::TrackRef trk = ele->core()->ctfTrack(); //@@ is this what we want?! + if ( ele.core().isNonnull() ) { + reco::TrackRef trk = ele.core()->ctfTrack(); //@@ is this what we want?! if ( trk.isNonnull() ) { trk_p_ = float(trk->p()); trk_nhits_ = float(trk->found()); @@ -57,8 +57,8 @@ namespace lowptgsfeleid { } // GSF tracks - if ( ele->core().isNonnull() ) { - reco::GsfTrackRef gsf = ele->core()->gsfTrack(); + if ( ele.core().isNonnull() ) { + reco::GsfTrackRef gsf = ele.core()->gsfTrack(); if ( gsf.isNonnull() ) { gsf_nhits_ = gsf->found(); gsf_chi2red_ = gsf->normalizedChi2(); @@ -66,8 +66,8 @@ namespace lowptgsfeleid { } // Super clusters - if ( ele->core().isNonnull() ) { - reco::SuperClusterRef sc = ele->core()->superCluster(); + if ( ele.core().isNonnull() ) { + reco::SuperClusterRef sc = ele.core()->superCluster(); if ( sc.isNonnull() ) { sc_E_ = sc->energy(); sc_eta_ = sc->eta(); @@ -77,29 +77,23 @@ namespace lowptgsfeleid { } // Track-cluster matching - if ( ele.isNonnull() ) { - match_seed_dEta_ = ele->deltaEtaSeedClusterTrackAtCalo(); - match_eclu_EoverP_ = (1./ele->ecalEnergy()) - (1./ele->p()); - match_SC_EoverP_ = ele->eSuperClusterOverP(); - match_SC_dEta_ = ele->deltaEtaSuperClusterTrackAtVtx(); - match_SC_dPhi_ = ele->deltaPhiSuperClusterTrackAtVtx(); - } + match_seed_dEta_ = ele.deltaEtaSeedClusterTrackAtCalo(); + match_eclu_EoverP_ = (1./ele.ecalEnergy()) - (1./ele.p()); + match_SC_EoverP_ = ele.eSuperClusterOverP(); + match_SC_dEta_ = ele.deltaEtaSuperClusterTrackAtVtx(); + match_SC_dPhi_ = ele.deltaPhiSuperClusterTrackAtVtx(); // Shower shape vars - if ( ele.isNonnull() ) { - shape_full5x5_sigmaIetaIeta_ = ele->full5x5_sigmaIetaIeta(); - shape_full5x5_sigmaIphiIphi_ = ele->full5x5_sigmaIphiIphi(); - shape_full5x5_HoverE_ = ele->full5x5_hcalOverEcal(); - shape_full5x5_r9_ = ele->full5x5_r9(); - shape_full5x5_circularity_ = 1. - ele->full5x5_e1x5() / ele->full5x5_e5x5(); - } + shape_full5x5_sigmaIetaIeta_ = ele.full5x5_sigmaIetaIeta(); + shape_full5x5_sigmaIphiIphi_ = ele.full5x5_sigmaIphiIphi(); + shape_full5x5_HoverE_ = ele.full5x5_hcalOverEcal(); + shape_full5x5_r9_ = ele.full5x5_r9(); + shape_full5x5_circularity_ = 1. - ele.full5x5_e1x5() / ele.full5x5_e5x5(); // Misc rho_ = rho; - if ( ele.isNonnull() ) { - brem_frac_ = ele->fbrem(); - ele_pt_ = ele->pt(); - } + brem_frac_ = ele.fbrem(); + ele_pt_ = ele.pt(); }; diff --git a/RecoEgamma/EgammaTools/BuildFile.xml b/RecoEgamma/EgammaTools/BuildFile.xml index b68da922f2348..92acfdf688c8a 100644 --- a/RecoEgamma/EgammaTools/BuildFile.xml +++ b/RecoEgamma/EgammaTools/BuildFile.xml @@ -13,6 +13,10 @@ <use name="CondCore/DBOutputService"/> <use name="DataFormats/ParticleFlowReco"/> <use name="CommonTools/Utils"/> +<use name="CommonTools/Statistics"/> +<use name="DataFormats/Common"/> +<use name="DataFormats/PatCandidates"/> +<use name="DataFormats/TrackReco"/> <export> <lib name="1"/> </export> diff --git a/RecoEgamma/EgammaTools/interface/LowPtConversion.h b/RecoEgamma/EgammaTools/interface/LowPtConversion.h new file mode 100644 index 0000000000000..744bce5caff8f --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/LowPtConversion.h @@ -0,0 +1,68 @@ +#ifndef RecoEgamma_EgammaTools_LowPtConversion_h +#define RecoEgamma_EgammaTools_LowPtConversion_h + +#include "CommonTools/Statistics/interface/ChiSquaredProbability.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/EgammaCandidates/interface/Conversion.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/RefToBase.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "DataFormats/TrackReco/interface/Track.h" + +class LowPtConversion { +public: + LowPtConversion() = default; + ~LowPtConversion() = default; + + bool wpOpen() const; // Matched to any conversion (without selections) + bool wpLoose() const; // Nancy's baseline selections for conversions + bool wpTight() const; // Nancy's selection for analysis of conversions + + void addUserVars(pat::Electron& ele) const; // adds minimal set of flags to electron userData + void addExtraUserVars(pat::Electron& ele) const; // adds all variables to electron userData + + bool match(const reco::BeamSpot& beamSpot, const reco::ConversionCollection& conversions, const pat::Electron& ele); + + static float mee(float ipx1, float ipy1, float ipz1, float ipx2, float ipy2, float ipz2); + +private: + // quality + bool valid_ = false; + float chi2prob_ = -1.; + bool quality_high_purity_ = false; + bool quality_high_efficiency_ = false; + + // tracks + uint ntracks_ = 0; + float min_trk_pt_ = -1.; + int ilead_ = -1; + int itrail_ = -1; + + // displacement + float l_xy_ = -1.; + float vtx_radius_ = -1.; + + // invariant mass + float mass_from_conv_ = -1.; + float mass_from_Pin_ = -1.; + float mass_before_fit_ = -1.; + float mass_after_fit_ = -1.; + + // hits before vertex + uint lead_nhits_before_vtx_ = 0; + uint trail_nhits_before_vtx_ = 0; + uint max_nhits_before_vtx_ = 0; + uint sum_nhits_before_vtx_ = 0; + int delta_expected_nhits_inner_ = 0; + + // opening angle + float delta_cot_from_Pin_ = -1.; + + // match? + bool matched_ = false; + edm::RefToBase<reco::Track> matched_lead_; + edm::RefToBase<reco::Track> matched_trail_; +}; + +#endif // RecoEgamma_EgammaTools_LowPtConversion_h diff --git a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV3.cc b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV3.cc index 9fcab37d305e8..31b976611bc4b 100644 --- a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV3.cc +++ b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV3.cc @@ -116,7 +116,7 @@ void EGRegressionModifierV3::modifyObject(reco::GsfElectron& ele) const if( superClus->seed()->seed().det() == DetId::Forward ) return; // do not apply corrections in case of missing info (slimmed MiniAOD electrons) - if(!superClus->clusters().isAvailable()) return; + bool rescaleDependentValues = superClus->clusters().isAvailable(); //check if fbrem is filled as its needed for E/p combination so abort if its set to the default value //this will be the case for <5 (or current cuts) for miniAOD electrons @@ -148,7 +148,7 @@ void EGRegressionModifierV3::modifyObject(reco::GsfElectron& ele) const const float corrEnergy = (rawEnergy + rawESEnergy)*ecalMeanCorr; const float corrEnergyErr = corrEnergy*ecalSigma; - ele.setCorrectedEcalEnergy(corrEnergy); + ele.setCorrectedEcalEnergy(corrEnergy, rescaleDependentValues); ele.setCorrectedEcalEnergyError(corrEnergyErr); std::pair<float,float> combEnergyAndErr = eleRegs_->epComb.combine(ele); diff --git a/RecoEgamma/EgammaTools/plugins/LowPtElectronsModifier.cc b/RecoEgamma/EgammaTools/plugins/LowPtElectronsModifier.cc new file mode 100644 index 0000000000000..22b55a300e21c --- /dev/null +++ b/RecoEgamma/EgammaTools/plugins/LowPtElectronsModifier.cc @@ -0,0 +1,82 @@ +#include "CommonTools/CandAlgos/interface/ModifyObjectValueBase.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "RecoEgamma/EgammaTools/interface/LowPtConversion.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class LowPtElectronModifier : public ModifyObjectValueBase { +public: + LowPtElectronModifier(const edm::ParameterSet& conf, edm::ConsumesCollector&); + ~LowPtElectronModifier() override = default; + + void setEvent(const edm::Event&) final; + void setEventContent(const edm::EventSetup&) final; + + void modifyObject(pat::Electron& ele) const final; + +private: + const edm::EDGetTokenT<reco::ConversionCollection> convT_; + reco::ConversionCollection const* conv_ = nullptr; + const edm::EDGetTokenT<reco::BeamSpot> beamSpotT_; + reco::BeamSpot const* beamSpot_ = nullptr; + const edm::EDGetTokenT<reco::VertexCollection> verticesT_; + reco::VertexCollection const* vertices_ = nullptr; + bool extra_; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +LowPtElectronModifier::LowPtElectronModifier(const edm::ParameterSet& conf, edm::ConsumesCollector& cc) + : ModifyObjectValueBase(conf), + convT_(cc.consumes<reco::ConversionCollection>(conf.getParameter<edm::InputTag>("conversions"))), + conv_(), + beamSpotT_(cc.consumes<reco::BeamSpot>(conf.getParameter<edm::InputTag>("beamSpot"))), + beamSpot_(), + verticesT_(cc.consumes<reco::VertexCollection>(conf.getParameter<edm::InputTag>("vertices"))), + vertices_(), + extra_(conf.getParameter<bool>("addExtraUserVars")) { + ; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LowPtElectronModifier::setEvent(const edm::Event& iEvent) { + conv_ = &iEvent.get(convT_); + beamSpot_ = &iEvent.get(beamSpotT_); + vertices_ = &iEvent.get(verticesT_); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LowPtElectronModifier::setEventContent(const edm::EventSetup& iSetup) {} + +//////////////////////////////////////////////////////////////////////////////// +// +void LowPtElectronModifier::modifyObject(pat::Electron& ele) const { + // Embed Conversion info + LowPtConversion conv; + conv.match(*beamSpot_, *conv_, ele); + conv.addUserVars(ele); + if (extra_) { + conv.addExtraUserVars(ele); + } + // Set impact parameters + auto const& gsfTrack = *ele.gsfTrack(); + if (!vertices_->empty()) { + const reco::Vertex& pv = vertices_->front(); + ele.setDB(gsfTrack.dxy(pv.position()), + gsfTrack.dxyError(pv.position(), pv.covariance()), + pat::Electron::PV2D); // PV2D + ele.setDB(gsfTrack.dz(pv.position()), std::hypot(gsfTrack.dzError(), pv.zError()), + pat::Electron::PVDZ); // PVDZ + } + ele.setDB(gsfTrack.dxy(*beamSpot_), gsfTrack.dxyError(*beamSpot_), + pat::Electron::BS2D); // BS2D +} + +//////////////////////////////////////////////////////////////////////////////// +// +DEFINE_EDM_PLUGIN(ModifyObjectValueFactory, LowPtElectronModifier, "LowPtElectronModifier"); diff --git a/RecoEgamma/EgammaTools/python/lowPtElectronModifier_cfi.py b/RecoEgamma/EgammaTools/python/lowPtElectronModifier_cfi.py new file mode 100644 index 0000000000000..72636d5f00c3a --- /dev/null +++ b/RecoEgamma/EgammaTools/python/lowPtElectronModifier_cfi.py @@ -0,0 +1,9 @@ +import FWCore.ParameterSet.Config as cms + +lowPtElectronModifier = cms.PSet( + modifierName = cms.string('LowPtElectronModifier'), + beamSpot = cms.InputTag('offlineBeamSpot'), + conversions = cms.InputTag('gsfTracksOpenConversions:gsfTracksOpenConversions'), + addExtraUserVars = cms.bool(True), + vertices = cms.InputTag("offlineSlimmedPrimaryVertices"), +) diff --git a/RecoEgamma/EgammaTools/src/LowPtConversion.cc b/RecoEgamma/EgammaTools/src/LowPtConversion.cc new file mode 100644 index 0000000000000..1862490d4a180 --- /dev/null +++ b/RecoEgamma/EgammaTools/src/LowPtConversion.cc @@ -0,0 +1,212 @@ +#include "RecoEgamma/EgammaTools/interface/LowPtConversion.h" + +//////////////////////////////////////////////////////////////////////////////// +// Matched to any conversion (without selections) +// +bool LowPtConversion::wpOpen() const { return matched_; } + +//////////////////////////////////////////////////////////////////////////////// +// Nancy's baseline selections for conversions +// Based on: https://github.com/CMSBParking/BParkingNANO/blob/b2664ed/BParkingNano/plugins/ConversionSelector.cc#L253-L300 +bool LowPtConversion::wpLoose() const { + return (wpOpen() && ntracks_ == 2 && valid_ && quality_high_purity_ && chi2prob_ > 0.0005); +} + +//////////////////////////////////////////////////////////////////////////////// +// Nancy's selection for analysis of conversions +// Based on: slide 20 of https://indico.cern.ch/event/814402/contributions/3401312/ +bool LowPtConversion::wpTight() const { + return (wpLoose() && sum_nhits_before_vtx_ <= 1 && l_xy_ > 0. && mass_from_conv_ > 0. && // sanity check + mass_from_conv_ < 0.05); +} + +//////////////////////////////////////////////////////////////////////////////// +// adds minimal set of flags to electron userData +void LowPtConversion::addUserVars(pat::Electron& ele) const { + ele.addUserInt("convOpen", matched_ ? 1 : 0); + ele.addUserInt("convLoose", wpLoose() ? 1 : 0); + ele.addUserInt("convTight", wpTight() ? 1 : 0); + ele.addUserInt("convLead", matched_lead_.isNonnull() ? 1 : 0); + ele.addUserInt("convTrail", matched_trail_.isNonnull() ? 1 : 0); + if (ele.hasUserInt("convExtra") == false) { + ele.addUserInt("convExtra", 0); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// adds all variables to electron userData +void LowPtConversion::addExtraUserVars(pat::Electron& ele) const { + // Flag that indicates if extra variables are added to electron userData + ele.addUserInt("convExtra", 1, true); // overwrite + + // quality + ele.addUserInt("convValid", valid_ ? 1 : 0); + ele.addUserFloat("convChi2Prob", chi2prob_); + ele.addUserInt("convQualityHighPurity", quality_high_purity_ ? 1 : 0); + ele.addUserInt("convQualityHighEff", quality_high_efficiency_ ? 1 : 0); + + // tracks + ele.addUserInt("convTracksN", ntracks_); + ele.addUserFloat("convMinTrkPt", min_trk_pt_); + ele.addUserInt("convLeadIdx", ilead_); + ele.addUserInt("convTrailIdx", itrail_); + + // displacement + ele.addUserFloat("convLxy", l_xy_); + ele.addUserFloat("convVtxRadius", vtx_radius_); + + // invariant mass + ele.addUserFloat("convMass", mass_from_conv_); + ele.addUserFloat("convMassFromPin", mass_from_Pin_); + ele.addUserFloat("convMassBeforeFit", mass_before_fit_); + ele.addUserFloat("convMassAfterFit", mass_after_fit_); + + // hits before vertex + ele.addUserInt("convLeadNHitsBeforeVtx", lead_nhits_before_vtx_); + ele.addUserInt("convTrailNHitsBeforeVtx", trail_nhits_before_vtx_); + ele.addUserInt("convMaxNHitsBeforeVtx", max_nhits_before_vtx_); + ele.addUserInt("convSumNHitsBeforeVtx", sum_nhits_before_vtx_); + ele.addUserInt("convDeltaExpectedNHitsInner", delta_expected_nhits_inner_); + + // opening angle + ele.addUserFloat("convDeltaCotFromPin", delta_cot_from_Pin_); +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LowPtConversion::match(const reco::BeamSpot& beamSpot, + const reco::ConversionCollection& conversions, + const pat::Electron& ele) { + // Iterate through conversions and calculate quantities (requirement from Nancy) + for (const auto& conv : conversions) { + // Filter + if (conv.tracks().size() != 2) { + continue; + } + + // Quality + valid_ = conv.conversionVertex().isValid(); // (=true) + chi2prob_ = ChiSquaredProbability(conv.conversionVertex().chi2(), conv.conversionVertex().ndof()); // (<0.005) + quality_high_purity_ = conv.quality(reco::Conversion::highPurity); // (=true) + quality_high_efficiency_ = conv.quality(reco::Conversion::highEfficiency); // (none) + + // Tracks + ntracks_ = conv.tracks().size(); // (=2) + min_trk_pt_ = -1.; // (>0.5) + for (const auto& trk : conv.tracks()) { + if (trk.isNonnull() && trk.isAvailable() && (min_trk_pt_ < 0. || trk->pt() < min_trk_pt_)) { + min_trk_pt_ = trk->pt(); + } + } + ilead_ = -1; + itrail_ = -1; + if (conv.tracks().size() == 2) { + const edm::RefToBase<reco::Track>& trk1 = conv.tracks().front(); + const edm::RefToBase<reco::Track>& trk2 = conv.tracks().back(); + if (trk1.isNonnull() && trk1.isAvailable() && trk2.isNonnull() && trk2.isAvailable()) { + if (trk1->pt() > trk2->pt()) { + ilead_ = 0; + itrail_ = 1; + } else { + ilead_ = 1; + itrail_ = 0; + } + } + } + + // Transverse displacement (with respect to beamspot) and vertex radius + math::XYZVectorF p_refitted = conv.refittedPairMomentum(); + float dx = conv.conversionVertex().x() - beamSpot.x0(); + float dy = conv.conversionVertex().y() - beamSpot.y0(); + l_xy_ = (p_refitted.x() * dx + p_refitted.y() * dy) / p_refitted.rho(); + vtx_radius_ = sqrt(conv.conversionVertex().position().perp2()); // (1.5<r<4.) + + // invariant mass from track pair from conversion + mass_from_conv_ = conv.pairInvariantMass(); + + // Invariant mass from Pin before fit to common vertex + if (conv.tracksPin().size() >= 2 && ilead_ > -1 && itrail_ > -1) { + math::XYZVectorF lead_Pin = conv.tracksPin().at(ilead_); + math::XYZVectorF trail_Pin = conv.tracksPin().at(itrail_); + mass_from_Pin_ = mee(lead_Pin.x(), lead_Pin.y(), lead_Pin.z(), trail_Pin.x(), trail_Pin.y(), trail_Pin.z()); + // Opening angle + delta_cot_from_Pin_ = 1. / tan(trail_Pin.theta()) - 1. / tan(lead_Pin.theta()); + } + + // Invariant mass before fit to common vertex + if (conv.tracks().size() >= 2 && ilead_ > -1 && itrail_ > -1) { + auto lead_before_vtx_fit = conv.tracks().at(ilead_)->momentum(); + auto trail_before_vtx_fit = conv.tracks().at(itrail_)->momentum(); + mass_before_fit_ = mee(lead_before_vtx_fit.x(), + lead_before_vtx_fit.y(), + lead_before_vtx_fit.z(), + trail_before_vtx_fit.x(), + trail_before_vtx_fit.y(), + trail_before_vtx_fit.z()); + } + + // Invariant mass after the fit to common vertex + if (conv.conversionVertex().refittedTracks().size() >= 2 && ilead_ > -1 && itrail_ > -1) { + auto const& lead_after_vtx_fit = conv.conversionVertex().refittedTracks().at(ilead_); + auto const& trail_after_vtx_fit = conv.conversionVertex().refittedTracks().at(itrail_); + mass_after_fit_ = mee(lead_after_vtx_fit.px(), + lead_after_vtx_fit.py(), + lead_after_vtx_fit.pz(), + trail_after_vtx_fit.px(), + trail_after_vtx_fit.py(), + trail_after_vtx_fit.pz()); + // Difference in expeted hits + delta_expected_nhits_inner_ = + lead_after_vtx_fit.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) - + trail_after_vtx_fit.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS); + } + + // Hits prior to vertex + if (ilead_ > -1 && itrail_ > -1) { + auto const& nHits = conv.nHitsBeforeVtx(); + bool enoughTracks = nHits.size() > 1; + lead_nhits_before_vtx_ = enoughTracks ? nHits.at(ilead_) : 0; + trail_nhits_before_vtx_ = enoughTracks ? nHits.at(itrail_) : 0; + max_nhits_before_vtx_ = enoughTracks ? std::max(nHits[0], nHits[1]) : 0; + sum_nhits_before_vtx_ = enoughTracks ? nHits[0] + nHits[1] : 0; + } + + // Attempt to match conversion track to electron + for (uint itrk = 0; itrk < conv.tracks().size(); ++itrk) { + const edm::RefToBase<reco::Track> trk = conv.tracks()[itrk]; + if (trk.isNull()) { + continue; + } + reco::GsfTrackRef ref = ele.core()->gsfTrack(); + reco::GsfTrackRef gsf = ele.gsfTrack(); + if (gsf.isNull()) { + continue; + } + if (ref.id() == trk.id() && ref.key() == trk.key()) { + matched_ = true; + if (static_cast<int>(itrk) == ilead_) { + matched_lead_ = trk; + } + if (static_cast<int>(itrk) == itrail_) { + matched_trail_ = trk; + } + } + } // track loop + } // conversions loop + + return matched_; +} + +//////////////////////////////////////////////////////////////////////////////// +// +float LowPtConversion::mee(float px1, float py1, float pz1, float px2, float py2, float pz2) { + const float m = 0.000511; + const float px = px1 + px2; + const float py = py1 + py2; + const float pz = pz1 + pz2; + const float p1 = px1 * px1 + py1 * py1 + pz1 * pz1; + const float p2 = px2 * px2 + py2 * py2 + pz2 * pz2; + const float e = sqrt(p1 + m * m) + sqrt(p2 + m * m); + const float mass = (e * e - px * px - py * py - pz * pz); + return mass > 0. ? sqrt(mass) : -1.; +} From f6b05b9eb2adc79d611feadd02af1405bc3743aa Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 12:06:57 +0200 Subject: [PATCH 3/8] lowPtElectrons: cfi --> cff, consistent with #33589 --- .../lowPtElectronProducer_cff.py | 2 +- .../python/lowPtGsfElectronSequence_cff.py | 2 +- .../python/lowPtGsfElectrons_cfi.py | 55 ------------------- 3 files changed, 2 insertions(+), 57 deletions(-) delete mode 100644 RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py index 97a8a7f540b6c..239ac2ce4a64a 100644 --- a/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py +++ b/PhysicsTools/PatAlgos/python/producersLayer1/lowPtElectronProducer_cff.py @@ -74,7 +74,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import rekeyLowPtGsfElectronSeedValueMaps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtGsfElectrons +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons _makePatLowPtElectronsTask = makePatLowPtElectronsTask.copy() _makePatLowPtElectronsTask.add(rekeyLowPtGsfElectronSeedValueMaps) diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py index 85484aab0bfbf..9f323046b8e52 100644 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py +++ b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectronSequence_cff.py @@ -63,7 +63,7 @@ from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronCores_cff import * # Low pT electrons -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtGsfElectrons +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtGsfElectrons # Low pT Electron value maps from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronSeedValueMaps_cff import lowPtGsfElectronSeedValueMaps diff --git a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py b/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py deleted file mode 100644 index 30a9f5f11af9d..0000000000000 --- a/RecoEgamma/EgammaElectronProducers/python/lowPtGsfElectrons_cfi.py +++ /dev/null @@ -1,55 +0,0 @@ -import FWCore.ParameterSet.Config as cms -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronsPreRegression_cfi import lowPtGsfElectronsPreRegression - -lowPtGsfElectrons = lowPtGsfElectronsPreRegression.clone() - -################################################################################ -# LowPtGsfElectronProducer above is run by default in RECO -# LowPtGsfElectronFinalizer below is scheduled for run2_miniAOD_UL - -from RecoEgamma.EgammaTools.regressionModifier_cfi import regressionModifier106XUL -lowPtRegressionModifier = regressionModifier106XUL.clone( - modifierName = 'EGRegressionModifierV3', - rhoTag = 'fixedGridRhoFastjetAll', - eleRegs = dict( - ecalOnlyMean = dict( - lowEtHighEtBoundary = 20., - ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", - ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_mean", - eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", - eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_mean", - ), - ecalOnlySigma = dict( - lowEtHighEtBoundary = 20., - ebLowEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", - ebHighEtForestName = "lowPtElectron_eb_ecalOnly_05To50_sigma", - eeLowEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", - eeHighEtForestName = "lowPtElectron_ee_ecalOnly_05To50_sigma", - ), - epComb = dict( - ecalTrkRegressionConfig = dict( - lowEtHighEtBoundary = 20., - ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", - ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_mean", - eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", - eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_mean", - ), - ecalTrkRegressionUncertConfig = dict( - lowEtHighEtBoundary = 20., - ebLowEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", - ebHighEtForestName = "lowPtElectron_eb_ecalTrk_05To50_sigma", - eeLowEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", - eeHighEtForestName = "lowPtElectron_ee_ecalTrk_05To50_sigma", - ), - ) - ), -) - -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronFinalizer_cfi import lowPtGsfElectronFinalizer -_lowPtGsfElectrons = lowPtGsfElectronFinalizer.clone( - previousGsfElectronsTag = "lowPtGsfElectrons::@skipCurrentProcess", - regressionConfig = lowPtRegressionModifier, -) - -from Configuration.ProcessModifiers.run2_miniAOD_UL_cff import run2_miniAOD_UL -run2_miniAOD_UL.toReplaceWith(lowPtGsfElectrons,_lowPtGsfElectrons) From adc59ec63fbba2220851fad40348ead0434d4145 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 12:38:31 +0200 Subject: [PATCH 4/8] lowPtElectrons: cfi-->cff --- PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py index 9caa8f29e315a..e53c5e072e8a3 100644 --- a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py +++ b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py @@ -7,7 +7,7 @@ ################################################################################ from RecoEgamma.EgammaTools.lowPtElectronModifier_cfi import lowPtElectronModifier -from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cfi import lowPtRegressionModifier +from RecoEgamma.EgammaElectronProducers.lowPtGsfElectrons_cff import lowPtRegressionModifier modifiedLowPtElectrons = cms.EDProducer( "ModifiedElectronProducer", src = cms.InputTag("slimmedLowPtElectrons"), From f74c46f6d6d5f46be156b7589efa49ca25b134f0 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 18:14:34 +0200 Subject: [PATCH 5/8] add low-pT ele tables to nano for (run2_nanoAOD_106Xv2 | run2_nanoAOD_devel) --- PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py index e53c5e072e8a3..8749a02b5879c 100644 --- a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py +++ b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py @@ -194,12 +194,7 @@ # Modifiers ################################################################################ -_modifiers = ( run2_miniAOD_80XLegacy | - run2_nanoAOD_94XMiniAODv1 | - run2_nanoAOD_94XMiniAODv2 | - run2_nanoAOD_94X2016 | - run2_nanoAOD_102Xv1 | - run2_nanoAOD_106Xv1 ) -(_modifiers).toReplaceWith(lowPtElectronSequence,cms.Sequence()) -(_modifiers).toReplaceWith(lowPtElectronTables,cms.Sequence()) -(_modifiers).toReplaceWith(lowPtElectronMC,cms.Sequence()) +_modifiers = ~(run2_nanoAOD_106Xv2 | run2_nanoAOD_devel) +_modifiers.toReplaceWith(lowPtElectronSequence,cms.Sequence()) +_modifiers.toReplaceWith(lowPtElectronTables,cms.Sequence()) +_modifiers.toReplaceWith(lowPtElectronMC,cms.Sequence()) From 7d724471012dddc4977e9c6b9cbd8bc3df414c9b Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 18:17:26 +0200 Subject: [PATCH 6/8] add LeptonUpdater, computeMiniIso=True; isoForLowPtEle.relative=True; DQM: fix miniPFRelIso_chg/all, remove s/ip3d histos --- .../NanoAOD/python/lowPtElectrons_cff.py | 27 +++++++++++++------ PhysicsTools/NanoAOD/python/nanoDQM_cfi.py | 6 ++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py index 8749a02b5879c..526a615064311 100644 --- a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py +++ b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py @@ -16,10 +16,22 @@ ) ) +import PhysicsTools.PatAlgos.producersLayer1.electronProducer_cfi +updatedLowPtElectrons = cms.EDProducer( + "PATElectronUpdater", + src = cms.InputTag("modifiedLowPtElectrons"), + vertices = cms.InputTag("offlineSlimmedPrimaryVertices"), + computeMiniIso = cms.bool(True), + fixDxySign = cms.bool(False), + pfCandsForMiniIso = cms.InputTag(""), + miniIsoParamsB = cms.vdouble(), + miniIsoParamsE = cms.vdouble(), +) + from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID lowPtPATElectronID = lowPtGsfElectronID.clone( usePAT = True, - electrons = "modifiedLowPtElectrons", + electrons = "updatedLowPtElectrons", unbiased = "", ModelWeights = [ 'RecoEgamma/ElectronIdentification/data/LowPtElectrons/LowPtElectrons_ID_2020Nov28.root', @@ -30,8 +42,8 @@ isoForLowPtEle = cms.EDProducer( "EleIsoValueMapProducer", - src = cms.InputTag("modifiedLowPtElectrons"), - relative = cms.bool(False), + src = cms.InputTag("updatedLowPtElectrons"), + relative = cms.bool(True), rho_MiniIso = cms.InputTag("fixedGridRhoFastjetAll"), rho_PFIso = cms.InputTag("fixedGridRhoFastjetAll"), EAFile_MiniIso = cms.FileInPath("RecoEgamma/ElectronIdentification/data/Fall17/effAreaElectrons_cone03_pfNeuHadronsAndPhotons_94X.txt"), @@ -40,7 +52,7 @@ updatedLowPtElectronsWithUserData = cms.EDProducer( "PATElectronUserDataEmbedder", - src = cms.InputTag("modifiedLowPtElectrons"), + src = cms.InputTag("updatedLowPtElectrons"), userFloats = cms.PSet( ID = cms.InputTag("lowPtPATElectronID"), miniIsoChg = cms.InputTag("isoForLowPtEle:miniIsoChg"), @@ -78,9 +90,9 @@ unbiased = Var("electronID('unbiased')",float,doc="ElectronSeed, pT- and dxy- agnostic BDT (raw) score"), ptbiased = Var("electronID('ptbiased')",float,doc="ElectronSeed, pT- and dxy- dependent BDT (raw) score"), # Isolation - miniPFRelIso_chg = Var("userFloat('miniIsoChg')/pt",float, + miniPFRelIso_chg = Var("userFloat('miniIsoChg')",float, doc="mini PF relative isolation, charged component"), - miniPFRelIso_all = Var("userFloat('miniIsoAll')/pt",float, + miniPFRelIso_all = Var("userFloat('miniIsoAll')",float, doc="mini PF relative isolation, total (with scaled rho*EA PU corrections)"), # Conversions convVeto = Var("passConversionVeto()",bool,doc="pass conversion veto"), @@ -102,8 +114,6 @@ dxyErr = Var("edB('PV2D')",float,doc="dxy uncertainty, in cm",precision=6), dz = Var("dB('PVDZ')",float,doc="dz (with sign) wrt first PV, in cm",precision=10), dzErr = Var("abs(edB('PVDZ'))",float,doc="dz uncertainty, in cm",precision=6), - ip3d = Var("abs(dB('PV3D'))",float,doc="3D impact parameter wrt first PV, in cm",precision=10), - sip3d = Var("abs(dB('PV3D')/edB('PV3D'))",float,doc="3D impact parameter significance wrt first PV, in cm",precision=10), # Cross-referencing #jetIdx #photonIdx @@ -177,6 +187,7 @@ ################################################################################ lowPtElectronSequence = cms.Sequence(modifiedLowPtElectrons + +updatedLowPtElectrons +lowPtPATElectronID +isoForLowPtEle +updatedLowPtElectronsWithUserData diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py index d1ec4b5f9f471..fe65a86e96786 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py @@ -133,8 +133,8 @@ Plot1D('unbiased', 'unbiased', 40, -10., 10., 'ElectronSeed, pT- and dxy- agnostic BDT (raw) score'), Plot1D('ptbiased', 'ptbiased', 40, -10., 10., 'ElectronSeed, pT- and dxy- dependent BDT (raw) score'), # Isolation - Plot1D('miniPFRelIso_chg', 'miniPFRelIso_chg', 20, 0, 2, 'mini PF relative isolation, charged component'), - Plot1D('miniPFRelIso_all', 'miniPFRelIso_all', 20, 0, 2, 'mini PF relative isolation, total (with scaled rho*EA PU corrections)'), + Plot1D('miniPFRelIso_chg', 'miniPFRelIso_chg', 20, 0., 1., 'mini PF relative isolation, charged component'), + Plot1D('miniPFRelIso_all', 'miniPFRelIso_all', 20, 0., 1., 'mini PF relative isolation, total (with scaled rho*EA PU corrections)'), # Conversions Plot1D('convVeto', 'convVeto', 2, -0.5, 1.5, 'pass conversion veto'), Plot1D('convWP', 'convWP', 8, -0.5, 7.5, 'conversion flag bit map: 1=Veto, 2=Loose, 3=Tight'), @@ -154,8 +154,6 @@ Plot1D('dz', 'dz', 20, -0.3, 0.3, 'dz (with sign) wrt first PV, in cm'), Plot1D('dxyErr', 'dxyErr', 20, 0., 0.2, 'dxy uncertainty, in cm'), Plot1D('dzErr', 'dzErr', 20, 0., 0.2, 'dz uncertainty, in cm'), - Plot1D('ip3d', 'ip3d', 20, 0., 0.2, '3D impact parameter wrt first PV, in cm'), - Plot1D('sip3d', 'sip3d', 20, 0., 20., '3D impact parameter significance wrt first PV, in cm'), ), ), From bda1a88ab731d7e90eafa0a549a370163ffc14a6 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 22:05:34 +0200 Subject: [PATCH 7/8] updatedLowPtElectrons: add missing params --- PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py index 526a615064311..4f3f64d5f851e 100644 --- a/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py +++ b/PhysicsTools/NanoAOD/python/lowPtElectrons_cff.py @@ -23,9 +23,9 @@ vertices = cms.InputTag("offlineSlimmedPrimaryVertices"), computeMiniIso = cms.bool(True), fixDxySign = cms.bool(False), - pfCandsForMiniIso = cms.InputTag(""), - miniIsoParamsB = cms.vdouble(), - miniIsoParamsE = cms.vdouble(), + pfCandsForMiniIso = cms.InputTag("packedPFCandidates"), + miniIsoParamsB = PhysicsTools.PatAlgos.producersLayer1.electronProducer_cfi.patElectrons.miniIsoParamsB, + miniIsoParamsE = PhysicsTools.PatAlgos.producersLayer1.electronProducer_cfi.patElectrons.miniIsoParamsE, ) from RecoEgamma.EgammaElectronProducers.lowPtGsfElectronID_cff import lowPtGsfElectronID From ce41e4b7377ef799c4357378bcd62fbde855acc2 Mon Sep 17 00:00:00 2001 From: bainbrid <bainbrid@users.noreply.github.com> Date: Mon, 7 Jun 2021 22:06:16 +0200 Subject: [PATCH 8/8] slava review --- DataFormats/EgammaCandidates/interface/GsfElectron.h | 4 ++-- .../PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/DataFormats/EgammaCandidates/interface/GsfElectron.h b/DataFormats/EgammaCandidates/interface/GsfElectron.h index 396b0249ee802..7c9d7423828ec 100644 --- a/DataFormats/EgammaCandidates/interface/GsfElectron.h +++ b/DataFormats/EgammaCandidates/interface/GsfElectron.h @@ -862,9 +862,9 @@ class GsfElectron : public RecoCandidate //bool isMomentumCorrected() const { return corrections_.isMomentumCorrected ; } float caloEnergy() const { return correctedEcalEnergy() ; } bool isEnergyScaleCorrected() const { return isEcalEnergyCorrected() ; } - void correctEcalEnergy(float newEnergy, float newEnergyError, bool rescaleDependentValues = true) + void correctEcalEnergy(float newEnergy, float newEnergyError, bool corrEovP = true) { - setCorrectedEcalEnergy(newEnergy,rescaleDependentValues) ; + setCorrectedEcalEnergy(newEnergy, corrEovP) ; setEcalEnergyError(newEnergyError) ; } void correctMomentum( const LorentzVector & p4, float trackMomentumError, float p4Error ) diff --git a/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py b/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py index 0bcd2fb7a5000..ece1ecce9e275 100644 --- a/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py +++ b/PhysicsTools/PatAlgos/python/slimming/slimmedLowPtElectrons_cfi.py @@ -46,6 +46,5 @@ from RecoEgamma.EgammaTools.lowPtElectronModifier_cfi import lowPtElectronModifier from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel from Configuration.Eras.Modifier_bParking_cff import bParking -_slimmedLowPtElectrons = slimmedLowPtElectrons.clone() -_slimmedLowPtElectrons.modifierConfig.modifications += [lowPtElectronModifier] -(~bParking & run2_miniAOD_devel).toReplaceWith(slimmedLowPtElectrons,_slimmedLowPtElectrons) +(~bParking & run2_miniAOD_devel).toModify(slimmedLowPtElectrons.modifierConfig.modifications, + func = lambda m: m.append(lowPtElectronModifier))