From 4559f4e3de684a457e3c4c374583f836f1935abb Mon Sep 17 00:00:00 2001 From: Swagata Mukherjee Date: Tue, 31 Jul 2018 23:50:11 +0200 Subject: [PATCH 01/12] Cutbased photonID Fall17 V2 --- ...e03_pfChargedHadrons_90percentBased_V2.txt | 9 + ...e03_pfNeutralHadrons_90percentBased_V2.txt | 9 + ...ons_cone03_pfPhotons_90percentBased_V2.txt | 9 + .../cutBasedPhotonID_Fall17_100X_V2_cff.py | 154 ++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt create mode 100644 RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt create mode 100644 RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt create mode 100644 RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt new file mode 100644 index 0000000000000..1dc879b16581c --- /dev/null +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt @@ -0,0 +1,9 @@ +# The constants are based on 90% contours of isolation. +# |eta| min |eta| max effective area +0.0000 1.0000 0.0404 +1.0000 1.4790 0.0396 +1.4790 2.0000 0.0364 +2.0000 2.2000 0.0353 +2.2000 2.3000 0.0351 +2.3000 2.4000 0.0347 +2.4000 5.0000 0.0337 diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt new file mode 100644 index 0000000000000..970f1f659429d --- /dev/null +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt @@ -0,0 +1,9 @@ +# The constants are based on 90% contours of isolation. +# |eta| min |eta| max effective area +0.0000 1.0000 0.067 +1.0000 1.4790 0.105 +1.4790 2.0000 0.079 +2.0000 2.2000 0.023 +2.2000 2.3000 0.008 +2.3000 2.4000 0.003 +2.4000 5.0000 0.014 diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt new file mode 100644 index 0000000000000..83419bef02fee --- /dev/null +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt @@ -0,0 +1,9 @@ +# The constants are based on 90% contours of isolation. +# |eta| min |eta| max effective area +0.0000 1.0000 0.111 +1.0000 1.4790 0.095 +1.4790 2.0000 0.062 +2.0000 2.2000 0.084 +2.2000 2.3000 0.107 +2.3000 2.4000 0.121 +2.4000 5.0000 0.147 diff --git a/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py new file mode 100644 index 0000000000000..863c12c243f59 --- /dev/null +++ b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py @@ -0,0 +1,154 @@ +from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry + +import FWCore.ParameterSet.Config as cms + +# Common functions and classes for ID definition are imported here: +from RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_tools \ + import ( WorkingPoint_V2, + IsolationCutInputs, + configureVIDCutBasedPhoID_V5 ) + +# The cut values are taken from the twiki: +# https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedPhotonIdentificationRun2 +# (where they may not stay, if a newer version of cuts becomes available for these +# conditions) + +# See also the presentation explaining these working points (this will not change): +# https://indico.cern.ch/event/732974/contributions/3072291/attachments/1685029/2709189/PhotonIDStudy.pdf + + +# +# First, define cut values +# + +# Loose working point Barrel and Endcap +idName = "cutBasedPhotonID-Fall17-100X-V2-loose" +WP_Loose_EB = WorkingPoint_V2( + idName , # idName + 0.0313 , # hOverECut + 0.0108 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 1.272 , # absPFChaHadIsoWithEACut_C1 + 0 , # absPFChaHadIsoWithEACut_C2 + 8.3828 , # absPFNeuHadIsoWithEACut_C1 + 0.01512 , # absPFNeuHadIsoWithEACut_C2 + 0.00002259 , # absPFNeuHadIsoWithEACut_C3 + 4.2891 , # absPFPhoIsoWithEACut_C1 + 0.004017 # absPFPhoIsoWithEACut_C2 + ) +WP_Loose_EE = WorkingPoint_V2( + idName , #idName + 0.0431 , # hOverECut + 0.0281 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 1.4449 , # absPFChaHadIsoWithEACut_C1 + 0.00 , # absPFChaHadIsoWithEACut_C2 + 13.6894 , # absPFNeuHadIsoWithEACut_C1 + 0.0117 , # absPFNeuHadIsoWithEACut_C2 + 0.000023 , # absPFNeuHadIsoWithEACut_C3 + 4.2969 , # absPFPhoIsoWithEACut_C1 + 0.0037 # absPFPhoIsoWithEACut_C2 + ) + +# Medium working point Barrel and Endcap +idName = "cutBasedPhotonID-Fall17-100X-V2-medium" +WP_Medium_EB = WorkingPoint_V2( + idName , # idName + 0.02 , # hOverECut + 0.01 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 0.6127 , # absPFChaHadIsoWithEACut_C1 + 0.00 , # absPFChaHadIsoWithEACut_C2 + 3.6265 , # absPFNeuHadIsoWithEACut_C1 + 0.01512 , # absPFNeuHadIsoWithEACut_C2 + 0.00002259 , # absPFNeuHadIsowithEACut_C3 + 2.3692 , # absPFPhoIsoWithEACut_C1 + 0.004017 # absPFPhoIsoWithEACut_C2 + ) + +WP_Medium_EE = WorkingPoint_V2( + idName , #idName + 0.0248 , # hOverECut + 0.0271 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 0.7981 , # absPFChaHadIsoWithEACut_C1 + 0.00 , # absPFChaHadIsoWithEACut_C2 + 2.3737 , # absPFNeuHadIsoWithEACut_C1 + 0.0117 , # absPFNeuHadIsoWithEACut_C2 + 0.000023 , # absPFNeuHadIsowithEACut_C3 + 3.1760 , # absPFPhoIsoWithEACut_C1 + 0.0037 # absPFPhoIsoWithEACut_C2 + ) + +# Tight working point Barrel and Endcap +idName = "cutBasedPhotonID-Fall17-100X-V2-tight" +WP_Tight_EB = WorkingPoint_V2( + idName , # idName + 0.02 , # hOverECut + 0.01 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 0.0939 , # absPFChaHadIsoWithEACut_C1 + 0.00 , # absPFChaHadIsoWithEACut_C2 + 3.6195 , # absPFNeuHadIsoWithEACut_C1 + 0.01512 , # absPFNeuHadIsoWithEACut_C2 + 0.00002259 , # absPFNeuHadIsowithEACut_C3 + 2.0018 , # absPFPhoIsoWithEACut_C1 + 0.004017 # absPFPhoIsoWithEACut_C2 + ) + +WP_Tight_EE = WorkingPoint_V2( + idName , #idName + 0.0219 , # hOverECut + 0.0268 , # full5x5_SigmaIEtaIEtaCut +# Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 + 0.2629 , # absPFChaHadIsoWithEACut_C1 + 0.00 , # absPFChaHadIsoWithEACut_C2 + 2.1436 , # absPFNeuHadIsoWithEACut_C1 + 0.0117 , # absPFNeuHadIsoWithEACut_C2 + 0.000023 , # absPFNeuHadIsowithEACut_C3 + 3.0133 , # absPFPhoIsoWithEACut_C1 + 0.0037 # absPFPhoIsoWithEACut_C2 + ) + + +# Second, define where to find the precomputed isolations and what effective +# areas to use for pile-up correction +isoInputs = IsolationCutInputs( + # chHadIsolationMapName + 'photonIDValueMapProducer:phoChargedIsolation' , + # chHadIsolationEffAreas + "RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt", + # neuHadIsolationMapName + 'photonIDValueMapProducer:phoNeutralHadronIsolation' , + # neuHadIsolationEffAreas + "RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt" , + # phoIsolationMapName + "photonIDValueMapProducer:phoPhotonIsolation" , + # phoIsolationEffAreas + "RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt" +) + +# +# Finally, set up VID configuration for all cuts +# +cutBasedPhotonID_Fall17_100X_V2_loose = configureVIDCutBasedPhoID_V5 ( WP_Loose_EB, WP_Loose_EE, isoInputs) +cutBasedPhotonID_Fall17_100X_V2_medium = configureVIDCutBasedPhoID_V5 ( WP_Medium_EB, WP_Medium_EE, isoInputs) +cutBasedPhotonID_Fall17_100X_V2_tight = configureVIDCutBasedPhoID_V5 ( WP_Tight_EB, WP_Tight_EE, isoInputs) + +## The MD5 sum numbers below reflect the exact set of cut variables +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, +# 2) run "calculateMD5 +# 3) update the MD5 sum strings below and uncomment the lines again. +# + +central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_loose.idName, + '4578dfcceb0bfd1ba5ac28973c843fd0') +central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_medium.idName, + '28b186c301061395f394a81266c8d7de') +central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_tight.idName, + '6f4f0ed6a8bf2de8dcf0bc3349b0546d') + +cutBasedPhotonID_Fall17_100X_V2_loose.isPOGApproved = cms.untracked.bool(True) +cutBasedPhotonID_Fall17_100X_V2_medium.isPOGApproved = cms.untracked.bool(True) +cutBasedPhotonID_Fall17_100X_V2_tight.isPOGApproved = cms.untracked.bool(True) From 4bba6c70077132253a0959e570ad35759f4677cd Mon Sep 17 00:00:00 2001 From: Swagata Mukherjee Date: Tue, 18 Sep 2018 20:19:18 +0200 Subject: [PATCH 02/12] update phoID v2 cutbased --- ...e03_pfChargedHadrons_90percentBased_V2.txt | 14 ++--- ...e03_pfNeutralHadrons_90percentBased_V2.txt | 14 ++--- ...ons_cone03_pfPhotons_90percentBased_V2.txt | 14 ++--- .../cutBasedPhotonID_Fall17_100X_V2_cff.py | 60 +++++++++---------- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt index 1dc879b16581c..a0835051ec5d8 100644 --- a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfChargedHadrons_90percentBased_V2.txt @@ -1,9 +1,9 @@ # The constants are based on 90% contours of isolation. # |eta| min |eta| max effective area -0.0000 1.0000 0.0404 -1.0000 1.4790 0.0396 -1.4790 2.0000 0.0364 -2.0000 2.2000 0.0353 -2.2000 2.3000 0.0351 -2.3000 2.4000 0.0347 -2.4000 5.0000 0.0337 +0.0000 1.0000 0.0112 +1.0000 1.4790 0.0108 +1.4790 2.0000 0.0106 +2.0000 2.2000 0.01002 +2.2000 2.3000 0.0098 +2.3000 2.4000 0.0089 +2.4000 5.0000 0.0087 diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt index 970f1f659429d..41090422c318a 100644 --- a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfNeutralHadrons_90percentBased_V2.txt @@ -1,9 +1,9 @@ # The constants are based on 90% contours of isolation. # |eta| min |eta| max effective area -0.0000 1.0000 0.067 -1.0000 1.4790 0.105 -1.4790 2.0000 0.079 -2.0000 2.2000 0.023 -2.2000 2.3000 0.008 -2.3000 2.4000 0.003 -2.4000 5.0000 0.014 +0.0000 1.0000 0.0668 +1.0000 1.4790 0.1054 +1.4790 2.0000 0.0786 +2.0000 2.2000 0.0233 +2.2000 2.3000 0.0078 +2.3000 2.4000 0.0028 +2.4000 5.0000 0.0137 diff --git a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt index 83419bef02fee..7269ec2b79cb7 100644 --- a/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt +++ b/RecoEgamma/PhotonIdentification/data/Fall17/effAreaPhotons_cone03_pfPhotons_90percentBased_V2.txt @@ -1,9 +1,9 @@ # The constants are based on 90% contours of isolation. # |eta| min |eta| max effective area -0.0000 1.0000 0.111 -1.0000 1.4790 0.095 -1.4790 2.0000 0.062 -2.0000 2.2000 0.084 -2.2000 2.3000 0.107 -2.3000 2.4000 0.121 -2.4000 5.0000 0.147 +0.0000 1.0000 0.1113 +1.0000 1.4790 0.0953 +1.4790 2.0000 0.0619 +2.0000 2.2000 0.0837 +2.2000 2.3000 0.1070 +2.3000 2.4000 0.1212 +2.4000 5.0000 0.1466 diff --git a/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py index 863c12c243f59..22381750868ff 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py @@ -25,28 +25,28 @@ idName = "cutBasedPhotonID-Fall17-100X-V2-loose" WP_Loose_EB = WorkingPoint_V2( idName , # idName - 0.0313 , # hOverECut - 0.0108 , # full5x5_SigmaIEtaIEtaCut + 0.04596 , # hOverECut + 0.0106 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 1.272 , # absPFChaHadIsoWithEACut_C1 + 1.694 , # absPFChaHadIsoWithEACut_C1 0 , # absPFChaHadIsoWithEACut_C2 - 8.3828 , # absPFNeuHadIsoWithEACut_C1 + 24.032 , # absPFNeuHadIsoWithEACut_C1 0.01512 , # absPFNeuHadIsoWithEACut_C2 0.00002259 , # absPFNeuHadIsoWithEACut_C3 - 4.2891 , # absPFPhoIsoWithEACut_C1 + 2.876 , # absPFPhoIsoWithEACut_C1 0.004017 # absPFPhoIsoWithEACut_C2 ) WP_Loose_EE = WorkingPoint_V2( idName , #idName - 0.0431 , # hOverECut - 0.0281 , # full5x5_SigmaIEtaIEtaCut + 0.0590 , # hOverECut + 0.0272 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 1.4449 , # absPFChaHadIsoWithEACut_C1 + 2.089 , # absPFChaHadIsoWithEACut_C1 0.00 , # absPFChaHadIsoWithEACut_C2 - 13.6894 , # absPFNeuHadIsoWithEACut_C1 + 19.722 , # absPFNeuHadIsoWithEACut_C1 0.0117 , # absPFNeuHadIsoWithEACut_C2 0.000023 , # absPFNeuHadIsoWithEACut_C3 - 4.2969 , # absPFPhoIsoWithEACut_C1 + 4.162 , # absPFPhoIsoWithEACut_C1 0.0037 # absPFPhoIsoWithEACut_C2 ) @@ -54,29 +54,29 @@ idName = "cutBasedPhotonID-Fall17-100X-V2-medium" WP_Medium_EB = WorkingPoint_V2( idName , # idName - 0.02 , # hOverECut - 0.01 , # full5x5_SigmaIEtaIEtaCut + 0.02197 , # hOverECut + 0.01015 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 0.6127 , # absPFChaHadIsoWithEACut_C1 + 1.141 , # absPFChaHadIsoWithEACut_C1 0.00 , # absPFChaHadIsoWithEACut_C2 - 3.6265 , # absPFNeuHadIsoWithEACut_C1 + 1.189 , # absPFNeuHadIsoWithEACut_C1 0.01512 , # absPFNeuHadIsoWithEACut_C2 0.00002259 , # absPFNeuHadIsowithEACut_C3 - 2.3692 , # absPFPhoIsoWithEACut_C1 + 2.08 , # absPFPhoIsoWithEACut_C1 0.004017 # absPFPhoIsoWithEACut_C2 ) WP_Medium_EE = WorkingPoint_V2( idName , #idName - 0.0248 , # hOverECut - 0.0271 , # full5x5_SigmaIEtaIEtaCut + 0.0326 , # hOverECut + 0.0272 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 0.7981 , # absPFChaHadIsoWithEACut_C1 + 1.051 , # absPFChaHadIsoWithEACut_C1 0.00 , # absPFChaHadIsoWithEACut_C2 - 2.3737 , # absPFNeuHadIsoWithEACut_C1 + 2.718 , # absPFNeuHadIsoWithEACut_C1 0.0117 , # absPFNeuHadIsoWithEACut_C2 0.000023 , # absPFNeuHadIsowithEACut_C3 - 3.1760 , # absPFPhoIsoWithEACut_C1 + 3.867 , # absPFPhoIsoWithEACut_C1 0.0037 # absPFPhoIsoWithEACut_C2 ) @@ -84,29 +84,29 @@ idName = "cutBasedPhotonID-Fall17-100X-V2-tight" WP_Tight_EB = WorkingPoint_V2( idName , # idName - 0.02 , # hOverECut - 0.01 , # full5x5_SigmaIEtaIEtaCut + 0.02148 , # hOverECut + 0.00996 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 0.0939 , # absPFChaHadIsoWithEACut_C1 + 0.65 , # absPFChaHadIsoWithEACut_C1 0.00 , # absPFChaHadIsoWithEACut_C2 - 3.6195 , # absPFNeuHadIsoWithEACut_C1 + 0.317 , # absPFNeuHadIsoWithEACut_C1 0.01512 , # absPFNeuHadIsoWithEACut_C2 0.00002259 , # absPFNeuHadIsowithEACut_C3 - 2.0018 , # absPFPhoIsoWithEACut_C1 + 2.044 , # absPFPhoIsoWithEACut_C1 0.004017 # absPFPhoIsoWithEACut_C2 ) WP_Tight_EE = WorkingPoint_V2( idName , #idName - 0.0219 , # hOverECut - 0.0268 , # full5x5_SigmaIEtaIEtaCut + 0.0321 , # hOverECut + 0.0271 , # full5x5_SigmaIEtaIEtaCut # Isolation cuts are generally absIso < C1 + pt*C2, except for NeuHad is < C1 + pt*C2 + pt*pt*C3 - 0.2629 , # absPFChaHadIsoWithEACut_C1 + 0.517 , # absPFChaHadIsoWithEACut_C1 0.00 , # absPFChaHadIsoWithEACut_C2 - 2.1436 , # absPFNeuHadIsoWithEACut_C1 + 2.716 , # absPFNeuHadIsoWithEACut_C1 0.0117 , # absPFNeuHadIsoWithEACut_C2 0.000023 , # absPFNeuHadIsowithEACut_C3 - 3.0133 , # absPFPhoIsoWithEACut_C1 + 3.032 , # absPFPhoIsoWithEACut_C1 0.0037 # absPFPhoIsoWithEACut_C2 ) From cc33f7818c33515aee725f320aa7c6213d1373a0 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 16 Aug 2018 10:01:09 +0200 Subject: [PATCH 03/12] Fall17_94X_v2 MVA Photon ID --- .../PatAlgos/python/slimming/miniAOD_tools.py | 1 + .../mvaPhotonID_Fall17_94X_V2_cff.py | 55 +++++++++++++++++++ .../python/PhotonMVAValueMapProducer_cfi.py | 3 + .../PhotonIdentification/test/runtests.sh | 4 +- .../test/testPhotonMVA_cfg.py | 3 + 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py diff --git a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py index 57dc96463ab7e..d30f7bc6eb314 100644 --- a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py +++ b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py @@ -320,6 +320,7 @@ def miniAOD_customizeCommon(process): photon_ids = ['RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_Fall17_94X_V1_TrueVtx_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1p1_cff', + 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V2_cff', 'RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_Spring16_V2p2_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Spring16_nonTrig_V1_cff'] switchOnVIDPhotonIdProducer(process,DataFormat.AOD, task) diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py new file mode 100644 index 0000000000000..9fce0619529e4 --- /dev/null +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py @@ -0,0 +1,55 @@ +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * +# +# In this file we define the locations of the MVA weights, cuts on the MVA values +# for specific working points, and configure those cuts in VID +# +# +# The following MVA is derived for Fall17 samples for photons. +# See more documentation in these presentations: +# https://indico.cern.ch/event/697079/contributions/2968123/attachments/1632966/2604131/PhotonID_EGM_13.04.2018.pdf +# +mvaTag = "RunIIFall17v2" +mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt" +mvaWeightFiles = [ + path.join(weightFileBaseDir, "Fall17/EB_V2.weights.xml.gz"), + path.join(weightFileBaseDir, "Fall17/EE_V2.weights.xml.gz"), + ] +# Set up the VID working point parameters +wpConfig = [ + # The working point for this MVA that is expected to have about 90% signal + # efficiency in each category for photons with pt>30 GeV (somewhat lower + # for lower pt photons). + {"idName" : "mvaPhoID-RunIIFall17-v2-wp90", + "cuts" : { "EB" : -0.02, + "EE" : -0.26 }}, + # The working point for this MVA that is expected to have about 90% signal + # efficiency in each category for photons with pt>30 GeV (somewhat lower + # for lower pt photons). + {"idName" : "mvaPhoID-RunIIFall17-v2-wp80", + "cuts" : { "EB" : 0.42, + "EE" : 0.14 }}, + ] +# Create the PSet that will be fed to the MVA value map producer and the +# VPset's for VID cuts +configs = configureFullVIDMVAPhoID(mvaTag=mvaTag, + variablesFile=mvaVariablesFile, + weightFiles=mvaWeightFiles, + wpConfig=wpConfig, + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts) +mvaPhoID_RunIIFall17_v2_producer_config = configs["producer_config"] +mvaPhoID_RunIIFall17_v2_wp90 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp90"] +mvaPhoID_RunIIFall17_v2_wp80 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp80"] +# The MD5 sum numbers below reflect the exact set of cut variables +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, +# 2) run "calculateIdMD5 +# 3) update the MD5 sum strings below and uncomment the lines again. +# +central_id_registry.register( mvaPhoID_RunIIFall17_v2_wp90.idName, + '5c06832759b1faf7dd6fc45ed1aef3a2') +central_id_registry.register( mvaPhoID_RunIIFall17_v2_wp80.idName, + '3013ddce7a3ad8b54827c29f5d92282e') +mvaPhoID_RunIIFall17_v2_wp90.isPOGApproved = cms.bool(True) +mvaPhoID_RunIIFall17_v2_wp80.isPOGApproved = cms.bool(True) diff --git a/RecoEgamma/PhotonIdentification/python/PhotonMVAValueMapProducer_cfi.py b/RecoEgamma/PhotonIdentification/python/PhotonMVAValueMapProducer_cfi.py index d9a9d95330a11..6bd60d9f32947 100644 --- a/RecoEgamma/PhotonIdentification/python/PhotonMVAValueMapProducer_cfi.py +++ b/RecoEgamma/PhotonIdentification/python/PhotonMVAValueMapProducer_cfi.py @@ -14,6 +14,9 @@ from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1p1_cff import * mvaConfigsForPhoProducer.append( mvaPhoID_RunIIFall17_v1p1_producer_config ) +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V2_cff import * +mvaConfigsForPhoProducer.append( mvaPhoID_RunIIFall17_v2_producer_config ) + photonMVAValueMapProducer = cms.EDProducer('PhotonMVAValueMapProducer', # The module automatically detects AOD vs miniAOD, so we configure both # diff --git a/RecoEgamma/PhotonIdentification/test/runtests.sh b/RecoEgamma/PhotonIdentification/test/runtests.sh index a7be141b0f28c..fd94875bacee8 100755 --- a/RecoEgamma/PhotonIdentification/test/runtests.sh +++ b/RecoEgamma/PhotonIdentification/test/runtests.sh @@ -7,10 +7,12 @@ ids_to_test=( 'RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_Fall17_94X_V1_TrueVtx_cff' 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Spring16_nonTrig_V1_cff' 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1_cff' + 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1p1_cff' + 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V2_cff' ) for id_set in "${ids_to_test[@]}"; do echo Checking: $id_set cmsRun ${LOCAL_TEST_DIR}/runPhoton_VID.py 1 $id_set || die "Failure using runPhoton_VID.py on AOD $id_set" $? cmsRun ${LOCAL_TEST_DIR}/runPhoton_VID.py 0 $id_set || die "Failure using runPhoton_VID.py on MiniAOD $id_set" $? -done \ No newline at end of file +done diff --git a/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py b/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py index fee6ae3cb7e45..d0d0f7aaa493c 100644 --- a/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py +++ b/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py @@ -38,6 +38,7 @@ 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Spring16_nonTrig_V1_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1p1_cff', + 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V2_cff', ] #add them to the VID producer @@ -62,11 +63,13 @@ "photonMVAValueMapProducer:PhotonMVAEstimatorRun2Spring16NonTrigV1Values", "photonMVAValueMapProducer:PhotonMVAEstimatorRunIIFall17v1Values", "photonMVAValueMapProducer:PhotonMVAEstimatorRunIIFall17v1p1Values", + "photonMVAValueMapProducer:PhotonMVAEstimatorRunIIFall17v2Values", ), phoMVAValMapLabels = cms.untracked.vstring( "Spring16NonTrigV1", "Fall17v1", "Fall17v1p1", + "Fall17v2", ), phoMVACats = cms.untracked.vstring( "photonMVAValueMapProducer:PhotonMVAEstimatorRunIIFall17v1Categories", From b3ea443b1ae3ca19a185617268647f766ab19e60 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 17 Sep 2018 19:51:14 +0200 Subject: [PATCH 04/12] fix worst charged iso variable --- .../python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py index 9fce0619529e4..31f963ffd16b5 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py @@ -9,7 +9,7 @@ # https://indico.cern.ch/event/697079/contributions/2968123/attachments/1632966/2604131/PhotonID_EGM_13.04.2018.pdf # mvaTag = "RunIIFall17v2" -mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt" +mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt" mvaWeightFiles = [ path.join(weightFileBaseDir, "Fall17/EB_V2.weights.xml.gz"), path.join(weightFileBaseDir, "Fall17/EE_V2.weights.xml.gz"), From 7326dcda3621d3426656cba445267507e07e2da5 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 19 Nov 2018 16:05:00 +0100 Subject: [PATCH 05/12] Renamed cut based ID and put in MiniAOD --- .../PatAlgos/python/slimming/miniAOD_tools.py | 1 + ... => cutBasedPhotonID_Fall17_94X_V2_cff.py} | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) rename RecoEgamma/PhotonIdentification/python/Identification/{cutBasedPhotonID_Fall17_100X_V2_cff.py => cutBasedPhotonID_Fall17_94X_V2_cff.py} (86%) diff --git a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py index d30f7bc6eb314..6f36d926805be 100644 --- a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py +++ b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py @@ -318,6 +318,7 @@ def miniAOD_customizeCommon(process): #VID Photon IDs process.patPhotons.addPhotonID = cms.bool(True) photon_ids = ['RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_Fall17_94X_V1_TrueVtx_cff', + 'RecoEgamma.PhotonIdentification.Identification.cutBasedPhotonID_Fall17_94X_V2_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V1p1_cff', 'RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_Fall17_94X_V2_cff', diff --git a/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_94X_V2_cff.py similarity index 86% rename from RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py rename to RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_94X_V2_cff.py index 22381750868ff..2bce2bd0feaa0 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_100X_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/cutBasedPhotonID_Fall17_94X_V2_cff.py @@ -22,7 +22,7 @@ # # Loose working point Barrel and Endcap -idName = "cutBasedPhotonID-Fall17-100X-V2-loose" +idName = "cutBasedPhotonID-Fall17-94X-V2-loose" WP_Loose_EB = WorkingPoint_V2( idName , # idName 0.04596 , # hOverECut @@ -51,7 +51,7 @@ ) # Medium working point Barrel and Endcap -idName = "cutBasedPhotonID-Fall17-100X-V2-medium" +idName = "cutBasedPhotonID-Fall17-94X-V2-medium" WP_Medium_EB = WorkingPoint_V2( idName , # idName 0.02197 , # hOverECut @@ -81,7 +81,7 @@ ) # Tight working point Barrel and Endcap -idName = "cutBasedPhotonID-Fall17-100X-V2-tight" +idName = "cutBasedPhotonID-Fall17-94X-V2-tight" WP_Tight_EB = WorkingPoint_V2( idName , # idName 0.02148 , # hOverECut @@ -131,9 +131,9 @@ # # Finally, set up VID configuration for all cuts # -cutBasedPhotonID_Fall17_100X_V2_loose = configureVIDCutBasedPhoID_V5 ( WP_Loose_EB, WP_Loose_EE, isoInputs) -cutBasedPhotonID_Fall17_100X_V2_medium = configureVIDCutBasedPhoID_V5 ( WP_Medium_EB, WP_Medium_EE, isoInputs) -cutBasedPhotonID_Fall17_100X_V2_tight = configureVIDCutBasedPhoID_V5 ( WP_Tight_EB, WP_Tight_EE, isoInputs) +cutBasedPhotonID_Fall17_94X_V2_loose = configureVIDCutBasedPhoID_V5 ( WP_Loose_EB, WP_Loose_EE, isoInputs) +cutBasedPhotonID_Fall17_94X_V2_medium = configureVIDCutBasedPhoID_V5 ( WP_Medium_EB, WP_Medium_EE, isoInputs) +cutBasedPhotonID_Fall17_94X_V2_tight = configureVIDCutBasedPhoID_V5 ( WP_Tight_EB, WP_Tight_EE, isoInputs) ## The MD5 sum numbers below reflect the exact set of cut variables # and values above. If anything changes, one has to @@ -142,13 +142,13 @@ # 3) update the MD5 sum strings below and uncomment the lines again. # -central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_loose.idName, +central_id_registry.register(cutBasedPhotonID_Fall17_94X_V2_loose.idName, '4578dfcceb0bfd1ba5ac28973c843fd0') -central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_medium.idName, +central_id_registry.register(cutBasedPhotonID_Fall17_94X_V2_medium.idName, '28b186c301061395f394a81266c8d7de') -central_id_registry.register(cutBasedPhotonID_Fall17_100X_V2_tight.idName, +central_id_registry.register(cutBasedPhotonID_Fall17_94X_V2_tight.idName, '6f4f0ed6a8bf2de8dcf0bc3349b0546d') -cutBasedPhotonID_Fall17_100X_V2_loose.isPOGApproved = cms.untracked.bool(True) -cutBasedPhotonID_Fall17_100X_V2_medium.isPOGApproved = cms.untracked.bool(True) -cutBasedPhotonID_Fall17_100X_V2_tight.isPOGApproved = cms.untracked.bool(True) +cutBasedPhotonID_Fall17_94X_V2_loose.isPOGApproved = cms.untracked.bool(True) +cutBasedPhotonID_Fall17_94X_V2_medium.isPOGApproved = cms.untracked.bool(True) +cutBasedPhotonID_Fall17_94X_V2_tight.isPOGApproved = cms.untracked.bool(True) From fde7b8ed6376149de42b15161e3e6837a07e1219 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 26 Nov 2018 18:32:02 +0100 Subject: [PATCH 06/12] Backporting #25293 --- ...PhotonMVAEstimatorRun2VariablesFall17.txt} | 6 ++-- ...tonMVAEstimatorRun2VariablesFall17V1p1.txt | 2 +- ...hotonMVAEstimatorRun2VariablesSpring16.txt | 2 +- .../plugins/PhotonIDValueMapProducer.cc | 36 +++++++++---------- .../mvaPhotonID_Fall17_94X_V1_cff.py | 6 ++-- .../mvaPhotonID_Fall17_94X_V1p1_cff.py | 4 +-- .../mvaPhotonID_Fall17_94X_V2_cff.py | 5 +-- ...vaPhotonID_Spring15_25ns_nonTrig_V0_cff.py | 4 +-- ...vaPhotonID_Spring15_25ns_nonTrig_V2_cff.py | 4 +-- ...PhotonID_Spring15_25ns_nonTrig_V2p1_cff.py | 4 +-- ...vaPhotonID_Spring15_50ns_nonTrig_V0_cff.py | 4 +-- ...vaPhotonID_Spring15_50ns_nonTrig_V1_cff.py | 4 +-- ...vaPhotonID_Spring15_50ns_nonTrig_V2_cff.py | 4 +-- ...PhotonID_Spring15_50ns_nonTrig_V2p1_cff.py | 4 +-- .../mvaPhotonID_Spring16_nonTrig_V1_cff.py | 4 +-- .../Identification/mvaPhotonID_tools.py | 3 ++ 16 files changed, 48 insertions(+), 48 deletions(-) rename RecoEgamma/PhotonIdentification/data/{PhotonMVAEstimatorRun2VariablesFall17V1.txt => PhotonMVAEstimatorRun2VariablesFall17.txt} (92%) diff --git a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1.txt b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt similarity index 92% rename from RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1.txt rename to RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt index fdcb2d112f894..0c26e6c6f6aff 100644 --- a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1.txt +++ b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt @@ -1,5 +1,5 @@ # -# File: PhotonMVAEstimatorRun2VariablesFall17V1.txt +# File: PhotonMVAEstimatorRun2VariablesFall17.txt # # This file is to be read by the MVAVariableManager class. Lists all the # variables which appear in the xml files for the MVA based Photon IDs for Run2. @@ -22,7 +22,7 @@ s4 full5x5_showerShapeVariables.e2x2/full5x5_showerShapeV scEta superCluster.eta None None rho fixedGridRhoAll None None esEffSigmaRR full5x5_showerShapeVariables.effSigmaRR None None -esEnergy/SCRawE superCluster.preshowerEnergy/superCluster.rawEnergy None None +esEnergyOverRawE superCluster.preshowerEnergy/superCluster.rawEnergy None None phoIso03 photonIDValueMapProducer:phoPhotonIsolation None None chgIsoWrtChosenVtx photonIDValueMapProducer:phoChargedIsolation None None -chgIsoWrtWorstVtx photonIDValueMapProducer:phoWorstChargedIsolationWithPVConstraint None None +chgIsoWrtWorstVtx photonIDValueMapProducer:phoWorstChargedIsolationConeVetoPVConstr None None diff --git a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt index 2775f64f054ec..72ad0262e8027 100644 --- a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt +++ b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt @@ -22,7 +22,7 @@ s4 full5x5_showerShapeVariables.e2x2/full5x5_showerShapeV scEta superCluster.eta None None rho fixedGridRhoAll None None esEffSigmaRR full5x5_showerShapeVariables.effSigmaRR None None -esEnergy/SCRawE superCluster.preshowerEnergy/superCluster.rawEnergy None None +esEnergyOverRawE superCluster.preshowerEnergy/superCluster.rawEnergy None None phoIso03 photonIDValueMapProducer:phoPhotonIsolation None None chgIsoWrtChosenVtx photonIDValueMapProducer:phoChargedIsolation None None chgIsoWrtWorstVtx photonIDValueMapProducer:phoWorstChargedIsolation None None diff --git a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring16.txt b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring16.txt index cb731b954d56a..875927f1feb37 100644 --- a/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring16.txt +++ b/RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring16.txt @@ -25,6 +25,6 @@ phiWidth superCluster.phiWidth CITK_isoPhotons egmPhotonIsolation:gamma-DR030- None None CITK_isoPhoCorrMax2p5 egmPhotonIsolation:gamma-DR030- None None CITK_isoChargedHad egmPhotonIsolation:h+-DR030- None None -chgIsoWrtWorstVtx photonIDValueMapProducer:phoWorstChargedIsolationWithConeVeto None None +chgIsoWrtWorstVtx photonIDValueMapProducer:phoWorstChargedIsolationConeVeto None None esEffSigmaRR full5x5_showerShapeVariables.effSigmaRR None None esEnergy/SCRawE superCluster.preshowerEnergy/superCluster.rawEnergy None None diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc index 6383bd5aec92e..4c207c4776889 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc @@ -123,9 +123,9 @@ class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { constexpr static char phoNeutralHadronIsolation_[] = "phoNeutralHadronIsolation"; constexpr static char phoPhotonIsolation_[] = "phoPhotonIsolation"; constexpr static char phoWorstChargedIsolation_[] = "phoWorstChargedIsolation"; - constexpr static char phoWorstChargedIsolationWithConeVeto_[] = "phoWorstChargedIsolationWithConeVeto"; - constexpr static char phoWorstChargedIsolationWithPVConstraint_[] = "phoWorstChargedIsolationWithPVConstraint"; - constexpr static char phoWorstChargedIsolationWithConeVetoWithPVConstraint_[] = "phoWorstChargedIsolationWithConeVetoWithPVConstraint"; + constexpr static char phoWorstChargedIsolationConeVeto_[] = "phoWorstChargedIsolationConeVeto"; + constexpr static char phoWorstChargedIsolationConeVetoPVConstr_[] = "phoWorstChargedIsolationConeVetoPVConstr"; + constexpr static char phoWorstChargedIsolationConeVetoWithPVConstraint_[] = "phoWorstChargedIsolationConeVetoWithPVConstraint"; //PFCluster Isolation constexpr static char phoTrkIsolation_[] = "phoTrkIsolation"; @@ -151,9 +151,9 @@ constexpr char PhotonIDValueMapProducer::phoChargedIsolation_[]; constexpr char PhotonIDValueMapProducer::phoNeutralHadronIsolation_[]; constexpr char PhotonIDValueMapProducer::phoPhotonIsolation_[]; constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationWithConeVeto_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationWithPVConstraint_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationWithConeVetoWithPVConstraint_[]; +constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVeto_[]; +constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVetoPVConstr_[]; +constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVetoWithPVConstraint_[]; //PFCluster Isolation constexpr char PhotonIDValueMapProducer::phoTrkIsolation_[]; @@ -226,9 +226,9 @@ PhotonIDValueMapProducer::PhotonIDValueMapProducer(const edm::ParameterSet& iCon produces >(phoNeutralHadronIsolation_); produces >(phoPhotonIsolation_); produces >(phoWorstChargedIsolation_); - produces >(phoWorstChargedIsolationWithConeVeto_); - produces >(phoWorstChargedIsolationWithPVConstraint_); - produces >(phoWorstChargedIsolationWithConeVetoWithPVConstraint_); + produces >(phoWorstChargedIsolationConeVeto_); + produces >(phoWorstChargedIsolationConeVetoPVConstr_); + produces >(phoWorstChargedIsolationConeVetoWithPVConstraint_); //PFCluster Isolations produces >(phoTrkIsolation_); @@ -333,9 +333,9 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup std::vector phoNeutralHadronIsolation; std::vector phoPhotonIsolation; std::vector phoWorstChargedIsolation; - std::vector phoWorstChargedIsolationWithConeVeto; - std::vector phoWorstChargedIsolationWithPVConstraint; - std::vector phoWorstChargedIsolationWithConeVetoWithPVConstraint; + std::vector phoWorstChargedIsolationConeVeto; + std::vector phoWorstChargedIsolationConeVetoPVConstr; + std::vector phoWorstChargedIsolationConeVetoWithPVConstraint; //PFCluster Isolations std::vector phoTrkIsolation; @@ -489,14 +489,14 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, isAOD, isPVConstraint,pv, coneSizeDR, dxyMax, dzMax, dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationWithConeVeto .push_back( worstChargedIsoWithConeVeto ); + phoWorstChargedIsolationConeVeto .push_back( worstChargedIsoWithConeVeto ); isPVConstraint=true; float worstChargedIsoWithPVConstraint = computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, isAOD, isPVConstraint,pv,coneSizeDR, dxyMax, dzMax, dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationWithPVConstraint .push_back( worstChargedIsoWithPVConstraint ); + phoWorstChargedIsolationConeVetoPVConstr .push_back( worstChargedIsoWithPVConstraint ); // Worst isolation computed with cone vetos and a ptMin cut, as in // Run 2 Hgg code. @@ -507,7 +507,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, isAOD,isPVConstraint, pv, coneSizeDR, dxyMax, dzMax, dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationWithConeVetoWithPVConstraint .push_back( worstChargedIsoWithConeVetoWithPVConstraint ); + phoWorstChargedIsolationConeVetoWithPVConstraint .push_back( worstChargedIsoWithConeVetoWithPVConstraint ); @@ -530,9 +530,9 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup writeValueMap(iEvent, src, phoNeutralHadronIsolation, phoNeutralHadronIsolation_); writeValueMap(iEvent, src, phoPhotonIsolation, phoPhotonIsolation_); writeValueMap(iEvent, src, phoWorstChargedIsolation, phoWorstChargedIsolation_); - writeValueMap(iEvent, src, phoWorstChargedIsolationWithConeVeto, phoWorstChargedIsolationWithConeVeto_); - writeValueMap(iEvent, src, phoWorstChargedIsolationWithPVConstraint, phoWorstChargedIsolationWithPVConstraint_); - writeValueMap(iEvent, src, phoWorstChargedIsolationWithConeVetoWithPVConstraint, phoWorstChargedIsolationWithConeVetoWithPVConstraint_); + writeValueMap(iEvent, src, phoWorstChargedIsolationConeVeto, phoWorstChargedIsolationConeVeto_); + writeValueMap(iEvent, src, phoWorstChargedIsolationConeVetoPVConstr, phoWorstChargedIsolationConeVetoPVConstr_); + writeValueMap(iEvent, src, phoWorstChargedIsolationConeVetoWithPVConstraint, phoWorstChargedIsolationConeVetoWithPVConstraint_); //PFCluster Isolation writeValueMap(iEvent, src, phoTrkIsolation, phoTrkIsolation_); writeValueMap(iEvent, src, phoHcalPFClIsolation, phoHcalPFClIsolation_); diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py index 34d9aa32a985f..266f08c520ccb 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py @@ -8,10 +8,10 @@ # https://indico.cern.ch/event/662751/contributions/2778043/attachments/1562017/2459674/EGamma_WorkShop_21.11.17_Debabrata.pdf mvaTag = "RunIIFall17v1" -mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1.txt" +mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17.txt" mvaWeightFiles = [ - "RecoEgamma/PhotonIdentification/data/Fall17/HggPhoId_92X_barrel_BDT.weights.xml", - "RecoEgamma/PhotonIdentification/data/Fall17/HggPhoId_92X_endcap_BDT.weights.xml" + path.join(weightFileBaseDir, "Fall17/EB_V1.weights.xml.gz"), + path.join(weightFileBaseDir, "Fall17/EE_V1.weights.xml.gz"), ] # Set up the VID working point parameters diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py index 2cd3e5bacf63c..3c063828407a8 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py @@ -10,8 +10,8 @@ mvaTag = "RunIIFall17v1p1" mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt" mvaWeightFiles = [ - "RecoEgamma/PhotonIdentification/data/Fall17/HggPhoId_92X_barrel_BDT.weights.xml", - "RecoEgamma/PhotonIdentification/data/Fall17/HggPhoId_92X_endcap_BDT.weights.xml" + path.join(weightFileBaseDir, "Fall17/EB_V1.weights.xml.gz"), + path.join(weightFileBaseDir, "Fall17/EE_V1.weights.xml.gz"), ] # Set up the VID working point parameters diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py index 31f963ffd16b5..adf420d87a609 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py @@ -34,10 +34,7 @@ configs = configureFullVIDMVAPhoID(mvaTag=mvaTag, variablesFile=mvaVariablesFile, weightFiles=mvaWeightFiles, - wpConfig=wpConfig, - # Category parameters - nCategories = cms.int32(2), - categoryCuts = category_cuts) + wpConfig=wpConfig) mvaPhoID_RunIIFall17_v2_producer_config = configs["producer_config"] mvaPhoID_RunIIFall17_v2_wp90 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp90"] mvaPhoID_RunIIFall17_v2_wp80 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp80"] diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py index 2a958749e9fda..267b3da9530cc 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py @@ -28,8 +28,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V0 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EB_V0.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EE_V0.weights.xml" + path.join(weightFileBaseDir, "Spring15/25ns_EB_V0.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/25ns_EE_V0.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py index c9fa4613035f9..0f2e9b0eeda25 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py @@ -29,8 +29,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V2 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EB_V2.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EE_V2.weights.xml" + path.join(weightFileBaseDir, "Spring15/25ns_EB_V2.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/25ns_EE_V2.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py index 58797eb1b6b86..548c5f4ce0e1b 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py @@ -31,8 +31,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V2p1 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EB_V2.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_25ns_EE_V2.weights.xml" + path.join(weightFileBaseDir, "Spring15/25ns_EB_V2.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/25ns_EE_V2.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py index d80480c63810a..b7c1ce6c72155 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py @@ -28,8 +28,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V0 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EB_V0.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EE_V0.weights.xml" + path.join(weightFileBaseDir, "Spring15/50ns_EB_V0.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/50ns_EE_V0.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py index 27e6859efb177..e63268bb8e121 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py @@ -28,8 +28,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V1 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EB_V1.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EE_V1.weights.xml" + path.join(weightFileBaseDir, "Spring15/50ns_EB_V1.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/50ns_EE_V1.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py index a62f9cc09fcf5..fe27e209e02c2 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py @@ -30,8 +30,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V2 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EB_V2.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EE_V2.weights.xml" + path.join(weightFileBaseDir, "Spring15/50ns_EB_V2.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/50ns_EE_V2.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py index e1b16cee38608..6563250e11a2d 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py @@ -32,8 +32,8 @@ # 1 endcap photons mvaSpring15NonTrigWeightFiles_V2p1 = cms.vstring( - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EB_V2.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring15/photon_general_MVA_Spring15_50ns_EE_V2.weights.xml" + path.join(weightFileBaseDir, "Spring15/50ns_EB_V2.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring15/50ns_EE_V2.weights.xml.gz"), ) # Load some common definitions for MVA machinery diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py index cc2a239e12f58..2f4b29b7d38cf 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py @@ -11,8 +11,8 @@ mvaTag = "Run2Spring16NonTrigV1" mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring16.txt" mvaWeightFiles = [ - "RecoEgamma/PhotonIdentification/data/Spring16/photon_general_MVA_Spring16_EB_V3.weights.xml", - "RecoEgamma/PhotonIdentification/data/Spring16/photon_general_MVA_Spring16_EE_V3.weights.xml" + path.join(weightFileBaseDir, "Spring16/EB_V1.weights.xml.gz"), + path.join(weightFileBaseDir, "Spring16/EE_V1.weights.xml.gz"), ] effAreasPath_pho = "RecoEgamma/PhotonIdentification/data/Spring16/effAreaPhotons_cone03_pfPhotons_90percentBased_3bins.txt" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py index 03d3c36978d8f..fdf395761c9dc 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py @@ -1,5 +1,8 @@ import FWCore.ParameterSet.Config as cms from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry +from os import path + +weightFileBaseDir = "RecoEgamma/PhotonIdentification/data/MVA" # division between barrel and endcap ebeeSplit = 1.479 From e78ff2dec5c2047a4933b6f8a0b165c967002dab Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 18 Jul 2018 21:26:48 +0200 Subject: [PATCH 07/12] Attempt to improve PhotonIDValueMapProducer --- .../plugins/PhotonIDValueMapProducer.cc | 1076 +++++++---------- 1 file changed, 439 insertions(+), 637 deletions(-) diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc index 4c207c4776889..bfdf872f5c473 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc @@ -1,686 +1,488 @@ -#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 "DataFormats/Common/interface/ValueMap.h" #include "DataFormats/Common/interface/View.h" - #include "DataFormats/EgammaCandidates/interface/Photon.h" -#include "DataFormats/PatCandidates/interface/Photon.h" - #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" - #include "DataFormats/PatCandidates/interface/PackedCandidate.h" - +#include "DataFormats/PatCandidates/interface/Photon.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" -#include -#include - -// Introduce these two types for brevity of casting -typedef edm::Ptr recoCandPtr; -typedef edm::Ptr patCandPtr; - -// This template function finds whether theCandidate is in thefootprint +// This template function finds whether theCandidate is in thefootprint // collection. It is templated to be able to handle both reco and pat // photons (from AOD and miniAOD, respectively). template -bool isInFootprint(const T& thefootprint, const U& theCandidate) { - for ( auto itr = thefootprint.begin(); itr != thefootprint.end(); ++itr ) { - if( itr->key() == theCandidate.key() ) return true; - } - return false; +bool isInFootprint(const T& footprint, const U& candidate) +{ + for (auto& it : footprint) { + if (it.key() == candidate.key()) + return true; + } + return false; } class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { - public: - - explicit PhotonIDValueMapProducer(const edm::ParameterSet&); - ~PhotonIDValueMapProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - - private: - - void produce(edm::Event&, const edm::EventSetup&) override; - - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - // This function computes charged hadron isolation - // with respect to multiple PVs and returns the worst - // of the found isolation values. - // The function implements the computation method taken directly - // from Run 1 code of H->gamma gamma, specifically from - // the class CiCPhotonID of the HiggsTo2photons anaysis code. - // Template is introduced to handle reco/pat photons and aod/miniAOD - // PF candidates collections - template - float computeWorstPFChargedIsolation(const T& photon, - const U& pfCandidates, - const edm::Handle vertices, - bool isAOD, bool isPVConstraint,const reco::Vertex& pv, - float dRmax, float dxyMax, float dzMax, - float dRvetoBarrel, float dRvetoEndcap, float ptMin); - - // Some helper functions that are needed to access info in - // AOD vs miniAOD - reco::PFCandidate::ParticleType - candidatePdgId(const edm::Ptr candidate, bool isAOD); - - const reco::Track* getTrackPointer(const edm::Ptr candidate, bool isAOD); - void getImpactParameters(const edm::Ptr& candidate, - bool isAOD, const reco::Vertex& pv, float &dxy, float &dz); - - - - // The object that will compute 5x5 quantities - std::unique_ptr lazyToolnoZS; - - // for AOD case - edm::EDGetTokenT ebReducedRecHitCollection_; - edm::EDGetTokenT eeReducedRecHitCollection_; - edm::EDGetTokenT esReducedRecHitCollection_; - edm::EDGetTokenT vtxToken_; - edm::EDGetTokenT > > particleBasedIsolationToken_; - edm::EDGetTokenT > pfCandidatesToken_; - edm::EDGetToken src_; - - // for miniAOD case - edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT vtxTokenMiniAOD_; - edm::EDGetTokenT > > particleBasedIsolationTokenMiniAOD_; - edm::EDGetTokenT > pfCandidatesTokenMiniAOD_; - edm::EDGetToken srcMiniAOD_; - - // check whether a non-null preshower is there - bool usesES_; - - // Cluster shapes - constexpr static char phoFull5x5SigmaIEtaIEta_[] = "phoFull5x5SigmaIEtaIEta"; - constexpr static char phoFull5x5SigmaIEtaIPhi_[] = "phoFull5x5SigmaIEtaIPhi"; - constexpr static char phoFull5x5E1x3_[] = "phoFull5x5E1x3"; - constexpr static char phoFull5x5E2x2_[] = "phoFull5x5E2x2"; - constexpr static char phoFull5x5E2x5Max_[] = "phoFull5x5E2x5Max"; - constexpr static char phoFull5x5E5x5_[] = "phoFull5x5E5x5"; - constexpr static char phoESEffSigmaRR_[] = "phoESEffSigmaRR"; - // Cluster shape ratios - constexpr static char phoFull5x5E1x3byE5x5_[] = "phoFull5x5E1x3byE5x5"; - constexpr static char phoFull5x5E2x2byE5x5_[] = "phoFull5x5E2x2byE5x5"; - constexpr static char phoFull5x5E2x5byE5x5_[] = "phoFull5x5E2x5byE5x5"; - // Isolations - constexpr static char phoChargedIsolation_[] = "phoChargedIsolation"; - constexpr static char phoNeutralHadronIsolation_[] = "phoNeutralHadronIsolation"; - constexpr static char phoPhotonIsolation_[] = "phoPhotonIsolation"; - constexpr static char phoWorstChargedIsolation_[] = "phoWorstChargedIsolation"; - constexpr static char phoWorstChargedIsolationConeVeto_[] = "phoWorstChargedIsolationConeVeto"; - constexpr static char phoWorstChargedIsolationConeVetoPVConstr_[] = "phoWorstChargedIsolationConeVetoPVConstr"; - constexpr static char phoWorstChargedIsolationConeVetoWithPVConstraint_[] = "phoWorstChargedIsolationConeVetoWithPVConstraint"; - - //PFCluster Isolation - constexpr static char phoTrkIsolation_[] = "phoTrkIsolation"; - constexpr static char phoHcalPFClIsolation_[] = "phoHcalPFClIsolation"; - constexpr static char phoEcalPFClIsolation_[] = "phoEcalPFClIsolation"; - +public: + explicit PhotonIDValueMapProducer(const edm::ParameterSet&); + ~PhotonIDValueMapProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + // This function computes charged hadron isolation with respect to multiple + // PVs and returns the worst of the found isolation values. The function + // implements the computation method taken directly from Run 1 code of + // H->gamma gamma, specifically from the class CiCPhotonID of the + // HiggsTo2photons anaysis code. Template is introduced to handle reco/pat + // photons and aod/miniAOD PF candidates collections + template + float computeWorstPFChargedIsolation( + const T& photon, + const U& pfCands, + const edm::Handle vertices, + const reco::Vertex& pv, + unsigned char options); + + // Some helper functions that are needed to access info in + // AOD vs miniAOD + reco::PFCandidate::ParticleType candidatePdgId(const edm::Ptr candidate); + + const reco::Track* getTrackPointer(const edm::Ptr candidate); + void getImpactParameters( + const edm::Ptr& candidate, const reco::Vertex& pv, float& dxy, float& dz); + + // The object that will compute 5x5 quantities + std::unique_ptr lazyToolnoZS; + + // check whether a non-null preshower is there + const bool usesES_; + + // for AOD case + const edm::EDGetTokenT ebReducedRecHitCollection_; + const edm::EDGetTokenT eeReducedRecHitCollection_; + const edm::EDGetTokenT esReducedRecHitCollection_; + const edm::EDGetTokenT vtxToken_; + const edm::EDGetTokenT>> particleBasedIsolationToken_; + const edm::EDGetTokenT> pfCandsToken_; + const edm::EDGetToken src_; + + // for miniAOD case + const edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; + const edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; + const edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; + const edm::EDGetTokenT vtxTokenMiniAOD_; + const edm::EDGetTokenT>> particleBasedIsolationTokenMiniAOD_; + const edm::EDGetTokenT> pfCandsTokenMiniAOD_; + const edm::EDGetToken srcMiniAOD_; + + bool isAOD_; }; -// Cluster shapes -constexpr char PhotonIDValueMapProducer::phoFull5x5SigmaIEtaIEta_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5SigmaIEtaIPhi_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E1x3_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E2x2_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E2x5Max_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E5x5_[]; -constexpr char PhotonIDValueMapProducer::phoESEffSigmaRR_[]; -// Cluster shape ratios -constexpr char PhotonIDValueMapProducer::phoFull5x5E1x3byE5x5_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E2x2byE5x5_[]; -constexpr char PhotonIDValueMapProducer::phoFull5x5E2x5byE5x5_[]; -// Isolations -constexpr char PhotonIDValueMapProducer::phoChargedIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoNeutralHadronIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoPhotonIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVeto_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVetoPVConstr_[]; -constexpr char PhotonIDValueMapProducer::phoWorstChargedIsolationConeVetoWithPVConstraint_[]; - -//PFCluster Isolation -constexpr char PhotonIDValueMapProducer::phoTrkIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoHcalPFClIsolation_[]; -constexpr char PhotonIDValueMapProducer::phoEcalPFClIsolation_[]; - - -PhotonIDValueMapProducer::PhotonIDValueMapProducer(const edm::ParameterSet& iConfig) { - - // - // Declare consummables, handle both AOD and miniAOD case - // - ebReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollection")); - ebReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollectionMiniAOD")); - - eeReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollection")); - eeReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollectionMiniAOD")); - - if (!iConfig.getParameter("esReducedRecHitCollection").label().empty() || - !iConfig.getParameter("esReducedRecHitCollectionMiniAOD").label().empty()) { - usesES_ = true; - esReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollection")); - esReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollectionMiniAOD")); - - } else { - usesES_ = false; - } - - vtxToken_ = mayConsume(iConfig.getParameter("vertices")); - vtxTokenMiniAOD_ = mayConsume(iConfig.getParameter("verticesMiniAOD")); - - // reco photons are castable into pat photons, so no need to handle reco/pat seprately - src_ = mayConsume >(iConfig.getParameter("src")); - srcMiniAOD_ = mayConsume >(iConfig.getParameter("srcMiniAOD")); - - // The particleBasedIsolation object is relevant only for AOD, RECO format - particleBasedIsolationToken_ = mayConsume > > - (iConfig.getParameter("particleBasedIsolation")); - - // AOD has reco::PFCandidate vector, and miniAOD has pat::PackedCandidate vector. - // Both inherit from reco::Candidate, so we go to the base class. We can cast into - // the full type later if needed. Since the collection names are different, we - // introduce both collections - pfCandidatesToken_ = mayConsume< edm::View >(iConfig.getParameter("pfCandidates")); - pfCandidatesTokenMiniAOD_ = mayConsume< edm::View >(iConfig.getParameter("pfCandidatesMiniAOD")); - - // - // Declare producibles - // - // Cluster shapes - produces >(phoFull5x5SigmaIEtaIEta_); - produces >(phoFull5x5SigmaIEtaIPhi_); - produces >(phoFull5x5E1x3_); - produces >(phoFull5x5E2x2_); - produces >(phoFull5x5E2x5Max_); - produces >(phoFull5x5E5x5_); - produces >(phoESEffSigmaRR_); - // Cluster shape ratios - produces >(phoFull5x5E1x3byE5x5_); - produces >(phoFull5x5E2x2byE5x5_); - produces >(phoFull5x5E2x5byE5x5_); - // Isolations - produces >(phoChargedIsolation_); - produces >(phoNeutralHadronIsolation_); - produces >(phoPhotonIsolation_); - produces >(phoWorstChargedIsolation_); - produces >(phoWorstChargedIsolationConeVeto_); - produces >(phoWorstChargedIsolationConeVetoPVConstr_); - produces >(phoWorstChargedIsolationConeVetoWithPVConstraint_); - - //PFCluster Isolations - produces >(phoTrkIsolation_); - produces >(phoHcalPFClIsolation_); - produces >(phoEcalPFClIsolation_); +constexpr int nVars_ = 19; + +const std::string names[nVars_] = { + // Cluster shapes + "phoFull5x5SigmaIEtaIEta", // 0 + "phoFull5x5SigmaIEtaIPhi", + "phoFull5x5E1x3", + "phoFull5x5E2x2", + "phoFull5x5E2x5Max", + "phoFull5x5E5x5", // 5 + "phoESEffSigmaRR", + // Cluster shape ratios + "phoFull5x5E1x3byE5x5", + "phoFull5x5E2x2byE5x5", + "phoFull5x5E2x5byE5x5", + // Isolations + "phoChargedIsolation", // 10 + "phoNeutralHadronIsolation", + "phoPhotonIsolation", + "phoWorstChargedIsolation", + "phoWorstChargedIsolationConeVeto", + "phoWorstChargedIsolationConeVetoPVConstr", // 15 + // PFCluster Isolation + "phoTrkIsolation", + "phoHcalPFClIsolation", + "phoEcalPFClIsolation" +}; +// options and bitflags +constexpr float coneSizeDR = 0.3; +constexpr float dxyMax = 0.1; +constexpr float dzMax = 0.2; +constexpr float dRvetoBarrel = 0.02; +constexpr float dRvetoEndcap = 0.02; +constexpr float ptMin = 0.1; + +const unsigned char PV_CONSTRAINT = 0x1; +const unsigned char DR_VETO = 0x2; +const unsigned char PT_MIN_THRESH = 0x8; + +PhotonIDValueMapProducer::PhotonIDValueMapProducer(const edm::ParameterSet& cfg) + : usesES_(!cfg.getParameter("esReducedRecHitCollection").label().empty() + || !cfg.getParameter("esReducedRecHitCollectionMiniAOD").label().empty()) + // Declare consummables, handle both AOD and miniAOD case + , ebReducedRecHitCollection_( + mayConsume(cfg.getParameter("ebReducedRecHitCollection"))) + , eeReducedRecHitCollection_( + mayConsume(cfg.getParameter("eeReducedRecHitCollection"))) + , esReducedRecHitCollection_( + mayConsume(cfg.getParameter("esReducedRecHitCollection"))) + , vtxToken_(mayConsume(cfg.getParameter("vertices"))) + // The particleBasedIsolation object is relevant only for AOD, RECO format + , particleBasedIsolationToken_(mayConsume>>( + cfg.getParameter("particleBasedIsolation"))) + // AOD has reco::PFCandidate vector, and miniAOD has pat::PackedCandidate + // vector. Both inherit from reco::Candidate, so we go to the base class. + // We can cast into the full type later if needed. Since the collection + // names are different, we introduce both collections + , pfCandsToken_(mayConsume>(cfg.getParameter("pfCandidates"))) + // reco photons are castable into pat photons, so no need to handle reco/pat seprately + , src_(mayConsume>(cfg.getParameter("src"))) + , ebReducedRecHitCollectionMiniAOD_( + mayConsume(cfg.getParameter("ebReducedRecHitCollectionMiniAOD"))) + , eeReducedRecHitCollectionMiniAOD_( + mayConsume(cfg.getParameter("eeReducedRecHitCollectionMiniAOD"))) + , esReducedRecHitCollectionMiniAOD_( + mayConsume(cfg.getParameter("esReducedRecHitCollectionMiniAOD"))) + , vtxTokenMiniAOD_(mayConsume(cfg.getParameter("verticesMiniAOD"))) + , pfCandsTokenMiniAOD_( + mayConsume>(cfg.getParameter("pfCandidatesMiniAOD"))) + , srcMiniAOD_(mayConsume>(cfg.getParameter("srcMiniAOD"))) +{ + // Declare producibles + for (int i = 0; i < nVars_; ++i) + produces>(names[i]); } -PhotonIDValueMapProducer::~PhotonIDValueMapProducer() { -} +PhotonIDValueMapProducer::~PhotonIDValueMapProducer() {} + +void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) +{ + edm::Handle> src; -void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - - using namespace edm; - - // Constants - const float coneSizeDR = 0.3; - const float dxyMax = 0.1; - const float dzMax = 0.2; - - edm::Handle > src; - - bool isAOD = true; - iEvent.getByToken(src_, src); - if( !src.isValid() ){ - isAOD = false; - iEvent.getByToken(srcMiniAOD_,src); - } - if( !src.isValid() ) { - throw cms::Exception("IllDefinedDataTier") - << "DataFormat does not contain a photon source!"; - } - - // Configure Lazy Tools - if (usesES_) { - if( isAOD ) - lazyToolnoZS = std::make_unique(iEvent, iSetup, - ebReducedRecHitCollection_, - eeReducedRecHitCollection_, - esReducedRecHitCollection_); - else - lazyToolnoZS = std::make_unique(iEvent, iSetup, - ebReducedRecHitCollectionMiniAOD_, - eeReducedRecHitCollectionMiniAOD_, - esReducedRecHitCollectionMiniAOD_); - } else { - if( isAOD ) - lazyToolnoZS = std::make_unique(iEvent, iSetup, - ebReducedRecHitCollection_, - eeReducedRecHitCollection_); - else - lazyToolnoZS = std::make_unique(iEvent, iSetup, - ebReducedRecHitCollectionMiniAOD_, - eeReducedRecHitCollectionMiniAOD_); - - } - - // Get PV - edm::Handle vertices; - iEvent.getByToken(vtxToken_, vertices); - if( !vertices.isValid() ) - iEvent.getByToken(vtxTokenMiniAOD_, vertices); - if (vertices->empty()) return; // skip the event if no PV found - const reco::Vertex &pv = vertices->front(); - - edm::Handle< edm::ValueMap > > particleBasedIsolationMap; - if( isAOD ){ - // this exists only in AOD - iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap); - } - - edm::Handle< edm::View > pfCandidatesHandle; - - iEvent.getByToken(pfCandidatesToken_, pfCandidatesHandle); - if( !pfCandidatesHandle.isValid() ) - iEvent.getByToken(pfCandidatesTokenMiniAOD_, pfCandidatesHandle); - - if( !isAOD && !src->empty() ) { - edm::Ptr test(src->ptrAt(0)); - if( test.isNull() || !test.isAvailable() ) { - throw cms::Exception("InvalidConfiguration") - <<"DataFormat is detected as miniAOD but cannot cast to pat::Photon!"; + isAOD_ = true; + iEvent.getByToken(src_, src); + if (!src.isValid()) { + isAOD_ = false; + iEvent.getByToken(srcMiniAOD_, src); } - } - - // size_t n = src->size(); - // Cluster shapes - std::vector phoFull5x5SigmaIEtaIEta; - std::vector phoFull5x5SigmaIEtaIPhi; - std::vector phoFull5x5E1x3; - std::vector phoFull5x5E2x2; - std::vector phoFull5x5E2x5Max; - std::vector phoFull5x5E5x5; - std::vector phoESEffSigmaRR; - // Cluster shape ratios - std::vector phoFull5x5E1x3byE5x5; - std::vector phoFull5x5E2x2byE5x5; - std::vector phoFull5x5E2x5byE5x5; - // Isolations - std::vector phoChargedIsolation; - std::vector phoNeutralHadronIsolation; - std::vector phoPhotonIsolation; - std::vector phoWorstChargedIsolation; - std::vector phoWorstChargedIsolationConeVeto; - std::vector phoWorstChargedIsolationConeVetoPVConstr; - std::vector phoWorstChargedIsolationConeVetoWithPVConstraint; - - //PFCluster Isolations - std::vector phoTrkIsolation; - std::vector phoHcalPFClIsolation; - std::vector phoEcalPFClIsolation; - - // reco::Photon::superCluster() is virtual so we can exploit polymorphism - for (unsigned idxpho = 0; idxpho < src->size(); ++idxpho) { - const auto& iPho = src->ptrAt(idxpho); - - // - // Compute full 5x5 quantities - // - const auto& theseed = *(iPho->superCluster()->seed()); - - // For full5x5_sigmaIetaIeta, for 720 we use: lazy tools for AOD, - // and userFloats or lazy tools for miniAOD. From some point in 72X and on, one can - // retrieve the full5x5 directly from the object with ->full5x5_sigmaIetaIeta() - // for both formats. - float see = -999; - std::vector vCov = lazyToolnoZS->localCovariances( theseed ); - see = (isnan(vCov[0]) ? 0. : sqrt(vCov[0])); - float sep = vCov[1]; - phoFull5x5SigmaIEtaIEta.push_back(see); - phoFull5x5SigmaIEtaIPhi.push_back(sep); - - phoFull5x5E1x3 .push_back(lazyToolnoZS-> e1x3 (theseed) ); - phoFull5x5E2x2 .push_back(lazyToolnoZS-> e2x2 (theseed) ); - phoFull5x5E2x5Max.push_back(lazyToolnoZS-> e2x5Max(theseed) ); - phoFull5x5E5x5 .push_back(lazyToolnoZS-> e5x5 (theseed) ); - - phoFull5x5E1x3byE5x5.push_back(phoFull5x5E1x3[idxpho]/phoFull5x5E5x5[idxpho]); - phoFull5x5E2x2byE5x5.push_back(phoFull5x5E2x2[idxpho]/phoFull5x5E5x5[idxpho]); - phoFull5x5E2x5byE5x5.push_back(phoFull5x5E2x5Max[idxpho]/phoFull5x5E5x5[idxpho]); - - phoESEffSigmaRR .push_back(lazyToolnoZS->eseffsirir( *(iPho->superCluster()) ) ); - - // - // Compute absolute uncorrected isolations with footprint removal - // - - // First, find photon direction with respect to the good PV - math::XYZVector photon_directionWrtVtx(iPho->superCluster()->x() - pv.x(), - iPho->superCluster()->y() - pv.y(), - iPho->superCluster()->z() - pv.z()); - - //PFCluster Isolations - phoTrkIsolation .push_back( iPho->trkSumPtSolidConeDR04()); - if (isAOD) - { - phoHcalPFClIsolation .push_back(0.f); - phoEcalPFClIsolation .push_back(0.f); - } - else - { - edm::Ptr patPhotonPtr(src->ptrAt(idxpho)); - phoHcalPFClIsolation .push_back(patPhotonPtr->hcalPFClusterIso()); - phoEcalPFClIsolation .push_back(patPhotonPtr->ecalPFClusterIso()); - } - - - // Zero the isolation sums - float chargedIsoSum = 0; - float neutralHadronIsoSum = 0; - float photonIsoSum = 0; - - // Loop over all PF candidates - for (unsigned idxcand = 0; idxcand < pfCandidatesHandle->size(); ++idxcand ){ - - // Here, the type will be a simple reco::Candidate. We cast it - // for full PFCandidate or PackedCandidate below as necessary - const auto& iCand = pfCandidatesHandle->ptrAt(idxcand); - - // One would think that we should check that this iCand from - // the generic PF collection is not identical to the iPho photon - // for which we are computing the isolations. However, it turns out - // to be unnecessary. Below, in the function isInFootprint(), we drop - // this iCand if it is in the footprint, and this always removes - // the iCand if it matches the iPho. - // The explicit check at this point is not totally trivial because - // of non-triviality of implementation of this check for miniAOD (PackedCandidates - // of the PF collection do not contain the supercluser link, so can't use that). - // if( isAOD ){ - // if( ((const recoCandPtr)iCand)->superClusterRef() == iPho->superCluster() ) continue; - // } - - - // Check if this candidate is within the isolation cone - float dR2 = deltaR2(photon_directionWrtVtx.Eta(),photon_directionWrtVtx.Phi(), - iCand->eta(), iCand->phi()); - if( dR2 > coneSizeDR*coneSizeDR ) continue; - - // Check if this candidate is not in the footprint - bool inFootprint = false; - if(isAOD) { - inFootprint = isInFootprint( (*particleBasedIsolationMap)[iPho], iCand ); - } else { - edm::Ptr patPhotonPtr(src->ptrAt(idxpho)); - inFootprint = isInFootprint(patPhotonPtr->associatedPackedPFCandidates(), iCand); - } - - if( inFootprint ) continue; - - // Find candidate type - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand, isAOD); - - // Increment the appropriate isolation sum - if( thisCandidateType == reco::PFCandidate::h ){ - // for charged hadrons, additionally check consistency - // with the PV - float dxy = -999, dz=-999; - getImpactParameters(iCand, isAOD, pv, dxy, dz); - - - if(fabs(dxy) > dxyMax) continue; - if (fabs(dz) > dzMax) continue; - - // The candidate is eligible, increment the isolaiton - chargedIsoSum += iCand->pt(); - } - - if( thisCandidateType == reco::PFCandidate::h0 ) - neutralHadronIsoSum += iCand->pt(); - - if( thisCandidateType == reco::PFCandidate::gamma ) - photonIsoSum += iCand->pt(); + if (!src.isValid()) { + throw cms::Exception("IllDefinedDataTier") << "DataFormat does not contain a photon source!"; } - phoChargedIsolation .push_back( chargedIsoSum ); - phoNeutralHadronIsolation.push_back( neutralHadronIsoSum ); - phoPhotonIsolation .push_back( photonIsoSum ); - - // Worst isolation computed with no vetos or ptMin cut, as in - // Run 1 Hgg code. - float dRvetoBarrel = 0.0; - float dRvetoEndcap = 0.0; - float ptMin = 0.0; - bool isPVConstraint=false; - float worstChargedIso = - computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, - isAOD, isPVConstraint,pv,coneSizeDR, dxyMax, dzMax, - dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolation .push_back( worstChargedIso ); - - // Worst isolation computed with cone vetos and a ptMin cut, as in - // Run 2 Hgg code. - dRvetoBarrel = 0.02; - dRvetoEndcap = 0.02; - ptMin = 0.1; - float worstChargedIsoWithConeVeto = - computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, - isAOD, isPVConstraint,pv, coneSizeDR, dxyMax, dzMax, - dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationConeVeto .push_back( worstChargedIsoWithConeVeto ); - - isPVConstraint=true; - float worstChargedIsoWithPVConstraint = - computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, - isAOD, isPVConstraint,pv,coneSizeDR, dxyMax, dzMax, - dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationConeVetoPVConstr .push_back( worstChargedIsoWithPVConstraint ); - - // Worst isolation computed with cone vetos and a ptMin cut, as in - // Run 2 Hgg code. - dRvetoBarrel = 0.02; - dRvetoEndcap = 0.02; - ptMin = 0.1; - float worstChargedIsoWithConeVetoWithPVConstraint = - computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices, - isAOD,isPVConstraint, pv, coneSizeDR, dxyMax, dzMax, - dRvetoBarrel, dRvetoEndcap, ptMin); - phoWorstChargedIsolationConeVetoWithPVConstraint .push_back( worstChargedIsoWithConeVetoWithPVConstraint ); - - - - } - - // Cluster shapes - writeValueMap(iEvent, src, phoFull5x5SigmaIEtaIEta, phoFull5x5SigmaIEtaIEta_); - writeValueMap(iEvent, src, phoFull5x5SigmaIEtaIPhi, phoFull5x5SigmaIEtaIPhi_); - writeValueMap(iEvent, src, phoFull5x5E1x3 , phoFull5x5E1x3_); - writeValueMap(iEvent, src, phoFull5x5E2x2 , phoFull5x5E2x2_); - writeValueMap(iEvent, src, phoFull5x5E2x5Max, phoFull5x5E2x5Max_); - writeValueMap(iEvent, src, phoFull5x5E5x5 , phoFull5x5E5x5_); - writeValueMap(iEvent, src, phoESEffSigmaRR , phoESEffSigmaRR_); - // Cluster shape ratios - writeValueMap(iEvent, src, phoFull5x5E1x3byE5x5 , phoFull5x5E1x3byE5x5_); - writeValueMap(iEvent, src, phoFull5x5E2x2byE5x5 , phoFull5x5E2x2byE5x5_); - writeValueMap(iEvent, src, phoFull5x5E2x5byE5x5 , phoFull5x5E2x5byE5x5_); - // Isolation - writeValueMap(iEvent, src, phoChargedIsolation, phoChargedIsolation_); - writeValueMap(iEvent, src, phoNeutralHadronIsolation, phoNeutralHadronIsolation_); - writeValueMap(iEvent, src, phoPhotonIsolation, phoPhotonIsolation_); - writeValueMap(iEvent, src, phoWorstChargedIsolation, phoWorstChargedIsolation_); - writeValueMap(iEvent, src, phoWorstChargedIsolationConeVeto, phoWorstChargedIsolationConeVeto_); - writeValueMap(iEvent, src, phoWorstChargedIsolationConeVetoPVConstr, phoWorstChargedIsolationConeVetoPVConstr_); - writeValueMap(iEvent, src, phoWorstChargedIsolationConeVetoWithPVConstraint, phoWorstChargedIsolationConeVetoWithPVConstraint_); - //PFCluster Isolation - writeValueMap(iEvent, src, phoTrkIsolation, phoTrkIsolation_); - writeValueMap(iEvent, src, phoHcalPFClIsolation, phoHcalPFClIsolation_); - writeValueMap(iEvent, src, phoEcalPFClIsolation, phoEcalPFClIsolation_); + // Configure Lazy Tools + if (usesES_) { + if (isAOD_) + lazyToolnoZS = std::make_unique( + iEvent, iSetup, ebReducedRecHitCollection_, eeReducedRecHitCollection_, esReducedRecHitCollection_); + else + lazyToolnoZS + = std::make_unique(iEvent, iSetup, ebReducedRecHitCollectionMiniAOD_, + eeReducedRecHitCollectionMiniAOD_, esReducedRecHitCollectionMiniAOD_); + } else { + if (isAOD_) + lazyToolnoZS = std::make_unique( + iEvent, iSetup, ebReducedRecHitCollection_, eeReducedRecHitCollection_); + else + lazyToolnoZS = std::make_unique( + iEvent, iSetup, ebReducedRecHitCollectionMiniAOD_, eeReducedRecHitCollectionMiniAOD_); + } -} + // Get PV + edm::Handle vertices; + iEvent.getByToken(vtxToken_, vertices); + if (!vertices.isValid()) + iEvent.getByToken(vtxTokenMiniAOD_, vertices); + if (vertices->empty()) + return; // skip the event if no PV found + const reco::Vertex& pv = vertices->front(); + + edm::Handle>> particleBasedIsolationMap; + if (isAOD_) { + // this exists only in AOD + iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap); + } -void PhotonIDValueMapProducer::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - using namespace edm; - using namespace std; - auto valMap = std::make_unique>(); - edm::ValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); + edm::Handle> pfCandsHandle; + + iEvent.getByToken(pfCandsToken_, pfCandsHandle); + if (!pfCandsHandle.isValid()) + iEvent.getByToken(pfCandsTokenMiniAOD_, pfCandsHandle); + + if (!isAOD_ && !src->empty()) { + edm::Ptr test(src->ptrAt(0)); + if (test.isNull() || !test.isAvailable()) { + throw cms::Exception("InvalidConfiguration") + << "DataFormat is detected as miniAOD but cannot cast to pat::Photon!"; + } + } + + std::vector vars[nVars_]; + + // reco::Photon::superCluster() is virtual so we can exploit polymorphism + for (unsigned i = 0; i < src->size(); ++i) { + const auto& iPho = src->ptrAt(i); + + // + // Compute full 5x5 quantities + // + const auto& theseed = *(iPho->superCluster()->seed()); + + // For full5x5_sigmaIetaIeta, for 720 we use: lazy tools for AOD, + // and userFloats or lazy tools for miniAOD. From some point in 72X and on, one can + // retrieve the full5x5 directly from the object with ->full5x5_sigmaIetaIeta() + // for both formats. + std::vector vCov = lazyToolnoZS->localCovariances(theseed); + vars[0].push_back(isnan(vCov[0]) ? 0. : sqrt(vCov[0])); + vars[1].push_back(vCov[1]); + vars[2].push_back(lazyToolnoZS->e1x3(theseed)); + vars[3].push_back(lazyToolnoZS->e2x2(theseed)); + vars[4].push_back(lazyToolnoZS->e2x5Max(theseed)); + vars[5].push_back(lazyToolnoZS->e5x5(theseed)); + vars[6].push_back(lazyToolnoZS->eseffsirir(*(iPho->superCluster()))); + vars[7].push_back(vars[2][i] / vars[5][i]); + vars[8].push_back(vars[3][i] / vars[5][i]); + vars[9].push_back(vars[4][i] / vars[5][i]); + + // + // Compute absolute uncorrected isolations with footprint removal + // + + // First, find photon direction with respect to the good PV + math::XYZVector phoWrtVtx( + iPho->superCluster()->x() - pv.x(), iPho->superCluster()->y() - pv.y(), iPho->superCluster()->z() - pv.z()); + + // isolation sums + float chargedIsoSum = 0.; + float neutralHadronIsoSum = 0.; + float photonIsoSum = 0.; + + // Loop over all PF candidates + for (unsigned int idxcand = 0; idxcand < pfCandsHandle->size(); ++idxcand) { + + // Here, the type will be a simple reco::Candidate. We cast it + // for full PFCandidate or PackedCandidate below as necessary + const auto& iCand = pfCandsHandle->ptrAt(idxcand); + + // One would think that we should check that this iCand from the + // generic PF collection is not identical to the iPho photon for + // which we are computing the isolations. However, it turns out to + // be unnecessary. Below, in the function isInFootprint(), we drop + // this iCand if it is in the footprint, and this always removes + // the iCand if it matches the iPho. The explicit check at this + // point is not totally trivial because of non-triviality of + // implementation of this check for miniAOD (PackedCandidates of + // the PF collection do not contain the supercluser link, so can't + // use that). + // + // if( isAOD_ ) { + // if( ((const edm::Ptr)iCand)->superClusterRef() == iPho->superCluster() ) + // continue; + // } + + // Check if this candidate is within the isolation cone + float dR2 = deltaR2(phoWrtVtx.Eta(), phoWrtVtx.Phi(), iCand->eta(), iCand->phi()); + if (dR2 > coneSizeDR * coneSizeDR) + continue; + + // Check if this candidate is not in the footprint + if (isAOD_) { + if(isInFootprint((*particleBasedIsolationMap)[iPho], iCand)) + continue; + } else { + edm::Ptr patPhotonPtr(src->ptrAt(i)); + if(isInFootprint(patPhotonPtr->associatedPackedPFCandidates(), iCand)) + continue; + } + + // Find candidate type + reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand); + + // Increment the appropriate isolation sum + if (thisCandidateType == reco::PFCandidate::h) { + // for charged hadrons, additionally check consistency + // with the PV + float dxy = -999; + float dz = -999; + getImpactParameters(iCand, pv, dxy, dz); + + if (fabs(dxy) > dxyMax || fabs(dz) > dzMax) + continue; + + // The candidate is eligible, increment the isolaiton + chargedIsoSum += iCand->pt(); + } + + if (thisCandidateType == reco::PFCandidate::h0) + neutralHadronIsoSum += iCand->pt(); + + if (thisCandidateType == reco::PFCandidate::gamma) + photonIsoSum += iCand->pt(); + } + + vars[10].push_back(chargedIsoSum); + vars[11].push_back(neutralHadronIsoSum); + vars[12].push_back(photonIsoSum); + + // Worst isolation computed with no vetos or ptMin cut, as in Run 1 Hgg code. + unsigned char options = 0; + vars[13].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + + // Worst isolation computed with cone vetos and a ptMin cut, as in Run 2 Hgg code. + options |= PT_MIN_THRESH | DR_VETO; + vars[14].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + + // Like before, but adding primary vertex constraint + options |= PV_CONSTRAINT; + vars[15].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + + // PFCluster Isolations + vars[16].push_back(iPho->trkSumPtSolidConeDR04()); + if (isAOD_) { + vars[17].push_back(0.f); + vars[18].push_back(0.f); + } else { + edm::Ptr patPhotonPtr{ src->ptrAt(i) }; + vars[17].push_back(patPhotonPtr->hcalPFClusterIso()); + vars[18].push_back(patPhotonPtr->ecalPFClusterIso()); + } + + } + + // write the value maps + for (int i = 0; i < nVars_; ++i) { + auto valMap = std::make_unique>(); + edm::ValueMap::Filler filler(*valMap); + filler.insert(src, vars[i].begin(), vars[i].end()); + filler.fill(); + iEvent.put(std::move(valMap), names[i]); + } } -void PhotonIDValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); +void PhotonIDValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) +{ + // The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.add("ebReducedRecHitCollection"); + desc.add("ebReducedRecHitCollectionMiniAOD"); + desc.add("eeReducedRecHitCollection"); + desc.add("eeReducedRecHitCollectionMiniAOD"); + desc.add("esReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsES")); + desc.add("esReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma:reducedESRecHits")); + desc.add("vertices"); + desc.add("verticesMiniAOD"); + desc.add("src"); + desc.add("srcMiniAOD"); + desc.add("particleBasedIsolation"); + desc.add("pfCandidates"); + desc.add("pfCandidatesMiniAOD"); + descriptions.addDefault(desc); } // Charged isolation with respect to the worst vertex. See more // comments above at the function declaration. template -float PhotonIDValueMapProducer -::computeWorstPFChargedIsolation(const T& photon, const U& pfCandidates, - const edm::Handle vertices, - bool isAOD, bool isPVConstraint,const reco::Vertex& pv, - float dRmax, float dxyMax, float dzMax, - float dRvetoBarrel, float dRvetoEndcap, float ptMin){ - - - float worstIsolation = 999; - std::vector allIsolations; - - float dRveto; - if (photon->isEB()) - dRveto = dRvetoBarrel; - else - dRveto = dRvetoEndcap; - - //Calculate isolation sum separately for each vertex - for(unsigned int ivtx=0; ivtxsize(); ++ivtx) { - - // Shift the photon according to the vertex - reco::VertexRef vtx(vertices, ivtx); - math::XYZVector photon_directionWrtVtx(photon->superCluster()->x() - vtx->x(), - photon->superCluster()->y() - vtx->y(), - photon->superCluster()->z() - vtx->z()); - - float sum = 0; - // Loop over the PFCandidates - for(unsigned i=0; isize(); i++) { - - const auto& iCand = pfCandidates->ptrAt(i); - - //require that PFCandidate is a charged hadron - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand, isAOD); - if (thisCandidateType != reco::PFCandidate::h) - continue; - - if (iCand->pt() < ptMin) - continue; - - float dxy=-999, dz=-999; - if(isPVConstraint) getImpactParameters(iCand, isAOD, pv, dxy, dz); - else getImpactParameters(iCand, isAOD, *vtx, dxy, dz); - - - - if( fabs(dxy) > dxyMax) continue; - if ( fabs(dz) > dzMax) continue; - - float dR2 = deltaR2(photon_directionWrtVtx.Eta(), photon_directionWrtVtx.Phi(), - iCand->eta(), iCand->phi()); - if(dR2 > dRmax*dRmax || dR2 < dRveto*dRveto) continue; - - sum += iCand->pt(); - } +float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, const U& pfCands, + const edm::Handle vertices, const reco::Vertex& pv, unsigned char options) +{ + float worstIsolation = 0.0; - allIsolations.push_back(sum); - } + const float dRveto = photon->isEB() ? dRvetoBarrel : dRvetoEndcap; - if( !allIsolations.empty() ) - worstIsolation = * std::max_element( allIsolations.begin(), allIsolations.end() ); - - return worstIsolation; -} + // Calculate isolation sum separately for each vertex + for (unsigned int ivtx = 0; ivtx < vertices->size(); ++ivtx) { + // Shift the photon according to the vertex + reco::VertexRef vtx(vertices, ivtx); + math::XYZVector phoWrtVtx(photon->superCluster()->x() - vtx->x(), + photon->superCluster()->y() - vtx->y(), photon->superCluster()->z() - vtx->z()); -reco::PFCandidate::ParticleType -PhotonIDValueMapProducer::candidatePdgId(const edm::Ptr candidate, - bool isAOD){ - - reco::PFCandidate::ParticleType thisCandidateType = reco::PFCandidate::X; - if( isAOD ) - thisCandidateType = ( (const recoCandPtr)candidate)->particleId(); - else { - // the neutral hadrons and charged hadrons can be of pdgId types - // only 130 (K0L) and +-211 (pi+-) in packed candidates - const int pdgId = ( (const patCandPtr)candidate)->pdgId(); - if( pdgId == 22 ) - thisCandidateType = reco::PFCandidate::gamma; - else if( abs(pdgId) == 130) // PDG ID for K0L - thisCandidateType = reco::PFCandidate::h0; - else if( abs(pdgId) == 211) // PDG ID for pi+- - thisCandidateType = reco::PFCandidate::h; - } - return thisCandidateType; -} + float sum = 0; + // Loop over the PFCandidates + for (unsigned int i = 0; i < pfCands->size(); i++) { -const reco::Track* -PhotonIDValueMapProducer::getTrackPointer(const edm::Ptr candidate, bool isAOD){ + const auto& iCand = pfCands->ptrAt(i); - const reco::Track* theTrack = nullptr; - if( isAOD ) - theTrack = &*( ((const recoCandPtr) candidate)->trackRef()); - else - theTrack = &( ((const patCandPtr) candidate)->pseudoTrack()); + // require that PFCandidate is a charged hadron + reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand); + if (thisCandidateType != reco::PFCandidate::h) + continue; - return theTrack; + if ((options & PT_MIN_THRESH) && iCand->pt() < ptMin) + continue; + + float dxy = -999; + float dz = -999; + if (options & PV_CONSTRAINT) + getImpactParameters(iCand, pv, dxy, dz); + else + getImpactParameters(iCand, *vtx, dxy, dz); + + if (fabs(dxy) > dxyMax || fabs(dz) > dzMax) + continue; + + float dR2 = deltaR2(phoWrtVtx.Eta(), phoWrtVtx.Phi(), iCand->eta(), iCand->phi()); + if (dR2 > coneSizeDR * coneSizeDR || + (options & DR_VETO && dR2 < dRveto * dRveto)) + continue; + + sum += iCand->pt(); + } + + worstIsolation = std::max(sum, worstIsolation); + } + + return worstIsolation; } -void PhotonIDValueMapProducer::getImpactParameters(const edm::Ptr& candidate, - bool isAOD, const reco::Vertex& pv, - float &dxy, float &dz){ +reco::PFCandidate::ParticleType PhotonIDValueMapProducer::candidatePdgId( + const edm::Ptr candidate) +{ + if (isAOD_) + return ((const edm::Ptr)candidate)->particleId(); - dxy=-999; - dz=-999; - if( isAOD ) { - const reco::Track *theTrack = &*( ((const recoCandPtr) candidate)->trackRef()); - dxy = theTrack->dxy(pv.position()); - dz = theTrack->dz(pv.position()); - } else { - const pat::PackedCandidate & aCand = *(patCandPtr(candidate)); - dxy = aCand.dxy(pv.position()); - dz = aCand.dz(pv.position()); + // the neutral hadrons and charged hadrons can be of pdgId types + // only 130 (K0L) and +-211 (pi+-) in packed candidates + const int pdgId = ((const edm::Ptr)candidate)->pdgId(); + if (pdgId == 22) + return reco::PFCandidate::gamma; + else if (abs(pdgId) == 130) // PDG ID for K0L + return reco::PFCandidate::h0; + else if (abs(pdgId) == 211) // PDG ID for pi+- + return reco::PFCandidate::h; + else + return reco::PFCandidate::X; +} - } +const reco::Track* PhotonIDValueMapProducer::getTrackPointer(const edm::Ptr candidate) +{ + return isAOD_ ? + &*(((const edm::Ptr)candidate)->trackRef()) : + &(((const edm::Ptr)candidate)->pseudoTrack()); +} +void PhotonIDValueMapProducer::getImpactParameters( + const edm::Ptr& candidate, const reco::Vertex& pv, float& dxy, float& dz) +{ + if (isAOD_) { + auto theTrack = *static_cast>(candidate)->trackRef(); + dxy = theTrack.dxy(pv.position()); + dz = theTrack.dz(pv.position()); + } else { + auto aCand = *static_cast>(candidate); + dxy = aCand.dxy(pv.position()); + dz = aCand.dz(pv.position()); + } } DEFINE_FWK_MODULE(PhotonIDValueMapProducer); From fedf904031ee1447e01097db2aa2bf758029bfed Mon Sep 17 00:00:00 2001 From: Slava Krutelyov Date: Thu, 1 Nov 2018 13:24:30 +0100 Subject: [PATCH 08/12] cache AOD/miniAOD values to speed up repeated computations --- .../plugins/PhotonIDValueMapProducer.cc | 86 +++++++++++-------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc index bfdf872f5c473..a948286ae0124 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc @@ -12,6 +12,7 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" +namespace { // This template function finds whether theCandidate is in thefootprint // collection. It is templated to be able to handle both reco and pat // photons (from AOD and miniAOD, respectively). @@ -25,6 +26,31 @@ bool isInFootprint(const T& footprint, const U& candidate) return false; } + struct CachingPtrCandidate { + CachingPtrCandidate(const reco::Candidate* cPtr, bool isAOD) : + candidate(cPtr), + track(isAOD? &*static_cast(cPtr)->trackRef() : nullptr), + packed(isAOD? nullptr : static_cast(cPtr)) + {} + + const reco::Candidate* candidate; + const reco::Track* track; + const pat::PackedCandidate* packed; + }; + + void getImpactParameters(const CachingPtrCandidate& candidate, const reco::Vertex& pv, float& dxy, float& dz) + { + if (candidate.track != nullptr) { + dxy = candidate.track->dxy(pv.position()); + dz = candidate.track->dz(pv.position()); + } else { + dxy = candidate.packed->dxy(pv.position()); + dz = candidate.packed->dz(pv.position()); + } + } + +}; + class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { public: @@ -52,11 +78,9 @@ class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { // Some helper functions that are needed to access info in // AOD vs miniAOD - reco::PFCandidate::ParticleType candidatePdgId(const edm::Ptr candidate); + reco::PFCandidate::ParticleType candidatePdgId(const reco::Candidate* candidate); const reco::Track* getTrackPointer(const edm::Ptr candidate); - void getImpactParameters( - const edm::Ptr& candidate, const reco::Vertex& pv, float& dxy, float& dz); // The object that will compute 5x5 quantities std::unique_ptr lazyToolnoZS; @@ -305,7 +329,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup } // Find candidate type - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand); + reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(&*iCand); // Increment the appropriate isolation sum if (thisCandidateType == reco::PFCandidate::h) { @@ -313,7 +337,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup // with the PV float dxy = -999; float dz = -999; - getImpactParameters(iCand, pv, dxy, dz); + getImpactParameters(CachingPtrCandidate(&*iCand, isAOD_), pv, dxy, dz); if (fabs(dxy) > dxyMax || fabs(dz) > dzMax) continue; @@ -399,6 +423,21 @@ float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, const float dRveto = photon->isEB() ? dRvetoBarrel : dRvetoEndcap; + std::vector chargedCands; + chargedCands.reserve(pfCands->size()); + for (auto const& aCand : *pfCands){ + + // require that PFCandidate is a charged hadron + reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(&aCand); + if (thisCandidateType != reco::PFCandidate::h) + continue; + + if ((options & PT_MIN_THRESH) && aCand.pt() < ptMin) + continue; + + chargedCands.emplace_back(&aCand, isAOD_); + } + // Calculate isolation sum separately for each vertex for (unsigned int ivtx = 0; ivtx < vertices->size(); ++ivtx) { @@ -409,28 +448,19 @@ float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, float sum = 0; // Loop over the PFCandidates - for (unsigned int i = 0; i < pfCands->size(); i++) { - - const auto& iCand = pfCands->ptrAt(i); - - // require that PFCandidate is a charged hadron - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand); - if (thisCandidateType != reco::PFCandidate::h) - continue; - - if ((options & PT_MIN_THRESH) && iCand->pt() < ptMin) - continue; + for (auto const& aCCand : chargedCands) { float dxy = -999; float dz = -999; if (options & PV_CONSTRAINT) - getImpactParameters(iCand, pv, dxy, dz); + getImpactParameters(aCCand, pv, dxy, dz); else - getImpactParameters(iCand, *vtx, dxy, dz); + getImpactParameters(aCCand, *vtx, dxy, dz); if (fabs(dxy) > dxyMax || fabs(dz) > dzMax) continue; + auto iCand = aCCand.candidate; float dR2 = deltaR2(phoWrtVtx.Eta(), phoWrtVtx.Phi(), iCand->eta(), iCand->phi()); if (dR2 > coneSizeDR * coneSizeDR || (options & DR_VETO && dR2 < dRveto * dRveto)) @@ -446,14 +476,14 @@ float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, } reco::PFCandidate::ParticleType PhotonIDValueMapProducer::candidatePdgId( - const edm::Ptr candidate) + const reco::Candidate* candidate) { if (isAOD_) - return ((const edm::Ptr)candidate)->particleId(); + return static_cast(candidate)->particleId(); // the neutral hadrons and charged hadrons can be of pdgId types // only 130 (K0L) and +-211 (pi+-) in packed candidates - const int pdgId = ((const edm::Ptr)candidate)->pdgId(); + const int pdgId = static_cast(candidate)->pdgId(); if (pdgId == 22) return reco::PFCandidate::gamma; else if (abs(pdgId) == 130) // PDG ID for K0L @@ -471,18 +501,4 @@ const reco::Track* PhotonIDValueMapProducer::getTrackPointer(const edm::Ptr)candidate)->pseudoTrack()); } -void PhotonIDValueMapProducer::getImpactParameters( - const edm::Ptr& candidate, const reco::Vertex& pv, float& dxy, float& dz) -{ - if (isAOD_) { - auto theTrack = *static_cast>(candidate)->trackRef(); - dxy = theTrack.dxy(pv.position()); - dz = theTrack.dz(pv.position()); - } else { - auto aCand = *static_cast>(candidate); - dxy = aCand.dxy(pv.position()); - dz = aCand.dz(pv.position()); - } -} - DEFINE_FWK_MODULE(PhotonIDValueMapProducer); From 9b56f8afe2d9410a729452e76cdc8f67fd6636eb Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 3 Dec 2018 00:05:39 +0100 Subject: [PATCH 09/12] Cleaned imports in Spring15 phtoton MVA cfg --- .../mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py | 7 +------ .../mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py | 7 +------ .../mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py | 7 +------ .../mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py | 7 +------ .../mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py | 7 +------ .../mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py | 7 +------ .../mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py | 7 +------ 7 files changed, 7 insertions(+), 42 deletions(-) diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py index 267b3da9530cc..89c195410c3bb 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15ValMaps.txt" @@ -32,9 +30,6 @@ path.join(weightFileBaseDir, "Spring15/25ns_EE_V0.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py index 0f2e9b0eeda25..5a76e775f9da6 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15ValMaps.txt" @@ -33,9 +31,6 @@ path.join(weightFileBaseDir, "Spring15/25ns_EE_V2.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py index 548c5f4ce0e1b..b835d4f0a3283 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15.txt" @@ -35,9 +33,6 @@ path.join(weightFileBaseDir, "Spring15/25ns_EE_V2.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py index b7c1ce6c72155..d47a094c245e4 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15ValMaps.txt" @@ -32,9 +30,6 @@ path.join(weightFileBaseDir, "Spring15/50ns_EE_V0.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py index e63268bb8e121..381f20bd179ff 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15ValMaps.txt" @@ -32,9 +30,6 @@ path.join(weightFileBaseDir, "Spring15/50ns_EE_V1.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py index fe27e209e02c2..9c8cd6854d9b9 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15ValMaps.txt" @@ -34,9 +32,6 @@ path.join(weightFileBaseDir, "Spring15/50ns_EE_V2.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py index 6563250e11a2d..577de6e0de238 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py @@ -1,6 +1,4 @@ -from PhysicsTools.SelectorUtils.centralIDRegistry import central_id_registry - -import FWCore.ParameterSet.Config as cms +from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15.txt" @@ -36,9 +34,6 @@ path.join(weightFileBaseDir, "Spring15/50ns_EE_V2.weights.xml.gz"), ) -# Load some common definitions for MVA machinery -from RecoEgamma.PhotonIdentification.Identification.mvaPhotonID_tools import * - # The locatoins of value maps with the actual MVA values and categories # for all particles. # The names for the maps are ":Values" From 3cef419a64fb6c1476cd2bd82608105a5af31f50 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 3 Dec 2018 00:10:55 +0100 Subject: [PATCH 10/12] Sync PhotonIDValueMapProducer with master plus MultiToken and Utils --- .../Trigger/python/HLTEGTnPMonitor_cfi.py | 2 +- PhysicsTools/NanoAOD/python/photons_cff.py | 2 +- RecoEgamma/EgammaTools/interface/MultiToken.h | 180 ++++++++++ RecoEgamma/EgammaTools/interface/Utils.h | 25 ++ .../plugins/PhotonIDValueMapProducer.cc | 323 +++++++----------- .../python/PhotonIDValueMapProducer_cfi.py | 31 -- .../python/egmPhotonIDs_cff.py | 2 +- .../python/photonIDValueMapProducer_cff.py | 9 + 8 files changed, 342 insertions(+), 232 deletions(-) create mode 100644 RecoEgamma/EgammaTools/interface/MultiToken.h create mode 100644 RecoEgamma/EgammaTools/interface/Utils.h delete mode 100644 RecoEgamma/PhotonIdentification/python/PhotonIDValueMapProducer_cfi.py create mode 100644 RecoEgamma/PhotonIdentification/python/photonIDValueMapProducer_cff.py diff --git a/DQMOffline/Trigger/python/HLTEGTnPMonitor_cfi.py b/DQMOffline/Trigger/python/HLTEGTnPMonitor_cfi.py index 72bbd7a0f8446..84a5de9c9984a 100644 --- a/DQMOffline/Trigger/python/HLTEGTnPMonitor_cfi.py +++ b/DQMOffline/Trigger/python/HLTEGTnPMonitor_cfi.py @@ -989,7 +989,7 @@ setupVIDSelection(egmGsfElectronIDsForDQM,item) -from RecoEgamma.PhotonIdentification.PhotonIDValueMapProducer_cfi import photonIDValueMapProducer +from RecoEgamma.PhotonIdentification.photonIDValueMapProducer_cff import photonIDValueMapProducer from RecoEgamma.PhotonIdentification.egmPhotonIDs_cfi import egmPhotonIDs egmPhotonIDsForDQM = egmPhotonIDs.clone() egmPhotonIDsForDQM.physicsObjectsIDs = cms.VPSet() diff --git a/PhysicsTools/NanoAOD/python/photons_cff.py b/PhysicsTools/NanoAOD/python/photons_cff.py index af089c2eaddeb..f129799494382 100644 --- a/PhysicsTools/NanoAOD/python/photons_cff.py +++ b/PhysicsTools/NanoAOD/python/photons_cff.py @@ -11,7 +11,7 @@ from PhysicsTools.SelectorUtils.tools.vid_id_tools import setupVIDSelection from RecoEgamma.PhotonIdentification.egmPhotonIDs_cfi import * -from RecoEgamma.PhotonIdentification.PhotonIDValueMapProducer_cfi import * +from RecoEgamma.PhotonIdentification.photonIDValueMapProducer_cff import * from RecoEgamma.PhotonIdentification.PhotonMVAValueMapProducer_cfi import * from RecoEgamma.PhotonIdentification.PhotonRegressionValueMapProducer_cfi import * from RecoEgamma.EgammaIsolationAlgos.egmPhotonIsolationMiniAOD_cff import * diff --git a/RecoEgamma/EgammaTools/interface/MultiToken.h b/RecoEgamma/EgammaTools/interface/MultiToken.h new file mode 100644 index 0000000000000..ed8ee2df3c71e --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/MultiToken.h @@ -0,0 +1,180 @@ +#ifndef RecoEgamma_EgammaTools_MultiToken_H +#define RecoEgamma_EgammaTools_MultiToken_H + +#include "DataFormats/Common/interface/Handle.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/InputTag.h" + +/* + * This class is a wrapper around a vector of EDM tokens, of which at least one + * is expected to yield a valid handle. + * + * The first time you call getValidHandle() or getHandle(), it will go over all + * tokens and try to get a valid handle. If no token yields a valid handle, it + * will either throw and exception or return the last non-valid handle. + * + * Once it found a valid handle, it will remember which token was used to get + * it and therefore doesn't need to loop over all tokens from there on. + * + * Example use case: auto-detection of AOD vs. MiniAOD. + * + * Created by Jonas Rembser on August 3, 2018. + */ + +#include + +template +class MultiTokenT { + + using GoodIndexType = std::shared_ptr>; + + public: + + template + MultiTokenT(edm::ConsumesCollector && cc, Tags ... tags) + : isMaster_(true) + , tokens_({cc.mayConsume(edm::InputTag(tags))...}) + , goodIndex_(std::make_shared>(-1)) + {} + + // Constructor which gets the input tags from a config to create the tokens plus master token + template + MultiTokenT(const MultiTokenT& master, edm::ConsumesCollector && cc, Tags ... tags) + : isMaster_(false) + , tokens_({cc.mayConsume(edm::InputTag(tags))...}) + , goodIndex_(master.getGoodTokenIndexPtr()) + {} + + // Constructor which gets the input tags from a config to create the tokens + template + MultiTokenT(edm::ConsumesCollector && cc, const edm::ParameterSet& pset, Tags && ... tags) + : isMaster_(true) + , tokens_({cc.mayConsume(pset.getParameter(tags))...}) + , goodIndex_(std::make_shared>(-1)) + {} + + // Constructor which gets the input tags from a config to create the tokens plus master token + template + MultiTokenT(const MultiTokenT& master, edm::ConsumesCollector && cc, const edm::ParameterSet& pset, Tags && ... tags) + : isMaster_(false) + , tokens_({cc.mayConsume(pset.getParameter(tags))...}) + , goodIndex_(master.getGoodTokenIndexPtr()) + {} + + // Get a handle on the event data, non-valid handle is allowed + edm::Handle getHandle(const edm::Event& iEvent) const + { + edm::Handle handle; + + // If we already know which token works, take that one + if (*goodIndex_ >= 0) { + iEvent.getByToken(tokens_[*goodIndex_], handle); + return handle; + } + + if (!isMaster_) { + throw cms::Exception("MultiTokenTException") << + "Trying to get a handle from a depending MultiToken before the master!"; + } + + // If not, set the good token index parallel to getting the handle + handle = getInitialHandle(iEvent); + + if (*goodIndex_ == -1) { + *goodIndex_ = tokens_.size() - 1; + } + return handle; + } + + // Get a handle on the event data, + // throw exception if no token yields a valid handle + edm::Handle getValidHandle(const edm::Event& iEvent) const + { + edm::Handle handle; + + // If we already know which token works, take that one + if (*goodIndex_ >= 0) { + iEvent.getByToken(tokens_[*goodIndex_], handle); + if (!handle.isValid()) + throw cms::Exception("MultiTokenTException") << + "Token gave valid handle previously but not anymore!"; + return handle; + } + + if (!isMaster_) { + throw cms::Exception("MultiTokenTException") << + "Trying to get a handle from a depending MultiToken before the master!"; + } + + // If not, set the good token index parallel to getting the handle + handle = getInitialHandle(iEvent); + + if (*goodIndex_ == -1) { + throw cms::Exception("MultiTokenTException") << "Neither handle is valid!"; + } + return handle; + } + + // get the good token + edm::EDGetTokenT get(const edm::Event& iEvent) const + { + // If we already know which token works, take that index + if (*goodIndex_ >= 0) + return tokens_[*goodIndex_]; + + // If this is not a master MultiToken, just return what it got + if (!isMaster_) { + throw cms::Exception("MultiTokenTException") << + "Trying to get a handle from a depending MultiToken before the master!"; + } + + // Find which token is the good one by trying to get a handle + edm::Handle handle; + for (auto token:tokens_ ) { + iEvent.getByToken(token, handle); + if (handle.isValid()) { + return token; + } + } + + throw cms::Exception("MultiTokenTException") << "Neither token is valid!"; + } + + int getGoodTokenIndex() const + { + return *goodIndex_; + } + + GoodIndexType getGoodTokenIndexPtr() const + { + return goodIndex_; + } + + private: + + edm::Handle getInitialHandle(const edm::Event& iEvent) const + { + // Try to retrieve the collection from the event. If we fail to + // retrieve the collection with one name, we next look for the one with + // the other name and so on. + edm::Handle handle; + for (size_t i = 0; i < tokens_.size(); ++i) { + iEvent.getByToken(tokens_[i], handle); + if (handle.isValid()) { + *goodIndex_ = i; + return handle; + } + } + return handle; + } + + const bool isMaster_; + const std::vector> tokens_; + const GoodIndexType goodIndex_; +}; + +#endif diff --git a/RecoEgamma/EgammaTools/interface/Utils.h b/RecoEgamma/EgammaTools/interface/Utils.h new file mode 100644 index 0000000000000..84755b5dabfef --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/Utils.h @@ -0,0 +1,25 @@ +#ifndef RecoEgamma_EgammaTools_Utils_H +#define RecoEgamma_EgammaTools_Utils_H + +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/ValueMap.h" +#include "FWCore/Framework/interface/Event.h" + +#include +#include +#include + +template +void writeValueMap(edm::Event &iEvent, + const edm::Handle& handle, + const std::vector& values, + const std::string& label) +{ + auto valMap = std::make_unique>(); + typename edm::ValueMap::Filler filler(*valMap); + filler.insert(handle, values.begin(), values.end()); + filler.fill(); + iEvent.put(std::move(valMap),label); +} + +#endif diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc index a948286ae0124..b0ed77a3d03d6 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonIDValueMapProducer.cc @@ -8,23 +8,30 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" +#include "RecoEgamma/EgammaTools/interface/MultiToken.h" +#include "RecoEgamma/EgammaTools/interface/Utils.h" +#include "FWCore/Utilities/interface/isFinite.h" namespace { -// This template function finds whether theCandidate is in thefootprint -// collection. It is templated to be able to handle both reco and pat -// photons (from AOD and miniAOD, respectively). -template -bool isInFootprint(const T& footprint, const U& candidate) -{ - for (auto& it : footprint) { - if (it.key() == candidate.key()) - return true; - } - return false; -} + + // This template function finds whether theCandidate is in thefootprint + // collection. It is templated to be able to handle both reco and pat + // photons (from AOD and miniAOD, respectively). + template + bool isInFootprint(const T& footprint, + const edm::Ptr& candidate) + { + for (auto& it : footprint) { + if (it.key() == candidate.key()) + return true; + } + return false; + } struct CachingPtrCandidate { CachingPtrCandidate(const reco::Candidate* cPtr, bool isAOD) : @@ -49,18 +56,38 @@ bool isInFootprint(const T& footprint, const U& candidate) } } + // Some helper functions that are needed to access info in + // AOD vs miniAOD + reco::PFCandidate::ParticleType getCandidatePdgId(const reco::Candidate* candidate, bool isAOD) + { + if (isAOD) + return static_cast(candidate)->particleId(); + + // the neutral hadrons and charged hadrons can be of pdgId types + // only 130 (K0L) and +-211 (pi+-) in packed candidates + const int pdgId = static_cast(candidate)->pdgId(); + if (pdgId == 22) + return reco::PFCandidate::gamma; + else if (abs(pdgId) == 130) // PDG ID for K0L + return reco::PFCandidate::h0; + else if (abs(pdgId) == 211) // PDG ID for pi+- + return reco::PFCandidate::h; + else + return reco::PFCandidate::X; + } + }; -class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { +class PhotonIDValueMapProducer : public edm::global::EDProducer<> { public: explicit PhotonIDValueMapProducer(const edm::ParameterSet&); - ~PhotonIDValueMapProducer() override; + ~PhotonIDValueMapProducer() override {} static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: - void produce(edm::Event&, const edm::EventSetup&) override; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; // This function computes charged hadron isolation with respect to multiple // PVs and returns the worst of the found isolation values. The function @@ -68,45 +95,25 @@ class PhotonIDValueMapProducer : public edm::stream::EDProducer<> { // H->gamma gamma, specifically from the class CiCPhotonID of the // HiggsTo2photons anaysis code. Template is introduced to handle reco/pat // photons and aod/miniAOD PF candidates collections - template float computeWorstPFChargedIsolation( - const T& photon, - const U& pfCands, - const edm::Handle vertices, + const reco::Photon& photon, + const edm::View& pfCands, + const reco::VertexCollection& vertices, const reco::Vertex& pv, - unsigned char options); - - // Some helper functions that are needed to access info in - // AOD vs miniAOD - reco::PFCandidate::ParticleType candidatePdgId(const reco::Candidate* candidate); - - const reco::Track* getTrackPointer(const edm::Ptr candidate); - - // The object that will compute 5x5 quantities - std::unique_ptr lazyToolnoZS; + unsigned char options, bool isAOD) const; // check whether a non-null preshower is there const bool usesES_; - // for AOD case - const edm::EDGetTokenT ebReducedRecHitCollection_; - const edm::EDGetTokenT eeReducedRecHitCollection_; - const edm::EDGetTokenT esReducedRecHitCollection_; - const edm::EDGetTokenT vtxToken_; - const edm::EDGetTokenT>> particleBasedIsolationToken_; - const edm::EDGetTokenT> pfCandsToken_; - const edm::EDGetToken src_; - - // for miniAOD case - const edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; - const edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; - const edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; - const edm::EDGetTokenT vtxTokenMiniAOD_; - const edm::EDGetTokenT>> particleBasedIsolationTokenMiniAOD_; - const edm::EDGetTokenT> pfCandsTokenMiniAOD_; - const edm::EDGetToken srcMiniAOD_; - - bool isAOD_; + // Dual Tokens for AOD and MiniAOD case + const MultiTokenT> src_; + const MultiTokenT ebRecHits_; + const MultiTokenT eeRecHits_; + const MultiTokenT esRecHits_; + const MultiTokenT vtxToken_; + const MultiTokenT> pfCandsToken_; + const edm::EDGetToken particleBasedIsolationToken_; + }; constexpr int nVars_ = 19; @@ -152,34 +159,14 @@ const unsigned char PT_MIN_THRESH = 0x8; PhotonIDValueMapProducer::PhotonIDValueMapProducer(const edm::ParameterSet& cfg) : usesES_(!cfg.getParameter("esReducedRecHitCollection").label().empty() || !cfg.getParameter("esReducedRecHitCollectionMiniAOD").label().empty()) - // Declare consummables, handle both AOD and miniAOD case - , ebReducedRecHitCollection_( - mayConsume(cfg.getParameter("ebReducedRecHitCollection"))) - , eeReducedRecHitCollection_( - mayConsume(cfg.getParameter("eeReducedRecHitCollection"))) - , esReducedRecHitCollection_( - mayConsume(cfg.getParameter("esReducedRecHitCollection"))) - , vtxToken_(mayConsume(cfg.getParameter("vertices"))) - // The particleBasedIsolation object is relevant only for AOD, RECO format + , src_( consumesCollector(), cfg, "src", "srcMiniAOD") + , ebRecHits_ (src_, consumesCollector(), cfg, "ebReducedRecHitCollection", "ebReducedRecHitCollectionMiniAOD") + , eeRecHits_ (src_, consumesCollector(), cfg, "eeReducedRecHitCollection", "eeReducedRecHitCollectionMiniAOD") + , esRecHits_ (src_, consumesCollector(), cfg, "esReducedRecHitCollection", "esReducedRecHitCollectionMiniAOD") + , vtxToken_ (src_, consumesCollector(), cfg, "vertices", "verticesMiniAOD") + , pfCandsToken_(src_, consumesCollector(), cfg, "pfCandidates", "pfCandidatesMiniAOD") , particleBasedIsolationToken_(mayConsume>>( - cfg.getParameter("particleBasedIsolation"))) - // AOD has reco::PFCandidate vector, and miniAOD has pat::PackedCandidate - // vector. Both inherit from reco::Candidate, so we go to the base class. - // We can cast into the full type later if needed. Since the collection - // names are different, we introduce both collections - , pfCandsToken_(mayConsume>(cfg.getParameter("pfCandidates"))) - // reco photons are castable into pat photons, so no need to handle reco/pat seprately - , src_(mayConsume>(cfg.getParameter("src"))) - , ebReducedRecHitCollectionMiniAOD_( - mayConsume(cfg.getParameter("ebReducedRecHitCollectionMiniAOD"))) - , eeReducedRecHitCollectionMiniAOD_( - mayConsume(cfg.getParameter("eeReducedRecHitCollectionMiniAOD"))) - , esReducedRecHitCollectionMiniAOD_( - mayConsume(cfg.getParameter("esReducedRecHitCollectionMiniAOD"))) - , vtxTokenMiniAOD_(mayConsume(cfg.getParameter("verticesMiniAOD"))) - , pfCandsTokenMiniAOD_( - mayConsume>(cfg.getParameter("pfCandidatesMiniAOD"))) - , srcMiniAOD_(mayConsume>(cfg.getParameter("srcMiniAOD"))) + cfg.getParameter("particleBasedIsolation")) /* ...only for AOD... */ ) { // Declare producibles @@ -187,69 +174,41 @@ PhotonIDValueMapProducer::PhotonIDValueMapProducer(const edm::ParameterSet& cfg) produces>(names[i]); } -PhotonIDValueMapProducer::~PhotonIDValueMapProducer() {} - -void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) +void PhotonIDValueMapProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { - edm::Handle> src; + // Get the handles + auto src = src_.getValidHandle(iEvent); + auto vertices = vtxToken_.getValidHandle(iEvent); + auto pfCandsHandle = pfCandsToken_.getValidHandle(iEvent); - isAOD_ = true; - iEvent.getByToken(src_, src); - if (!src.isValid()) { - isAOD_ = false; - iEvent.getByToken(srcMiniAOD_, src); - } - if (!src.isValid()) { - throw cms::Exception("IllDefinedDataTier") << "DataFormat does not contain a photon source!"; + bool isAOD = src_.getGoodTokenIndex() == 0; + edm::Handle>> particleBasedIsolationMap; + if (isAOD) { // this exists only in AOD + iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap); + } else if (!src->empty()) { + edm::Ptr test(src->ptrAt(0)); + if (test.isNull() || !test.isAvailable()) { + throw cms::Exception("InvalidConfiguration") + << "DataFormat is detected as miniAOD but cannot cast to pat::Photon!"; + } } - // Configure Lazy Tools + // Configure Lazy Tools, which will compute 5x5 quantities + std::unique_ptr lazyToolnoZS; + if (usesES_) { - if (isAOD_) - lazyToolnoZS = std::make_unique( - iEvent, iSetup, ebReducedRecHitCollection_, eeReducedRecHitCollection_, esReducedRecHitCollection_); - else - lazyToolnoZS - = std::make_unique(iEvent, iSetup, ebReducedRecHitCollectionMiniAOD_, - eeReducedRecHitCollectionMiniAOD_, esReducedRecHitCollectionMiniAOD_); + lazyToolnoZS = std::make_unique( + iEvent, iSetup, ebRecHits_.get(iEvent), eeRecHits_.get(iEvent), esRecHits_.get(iEvent)); } else { - if (isAOD_) - lazyToolnoZS = std::make_unique( - iEvent, iSetup, ebReducedRecHitCollection_, eeReducedRecHitCollection_); - else - lazyToolnoZS = std::make_unique( - iEvent, iSetup, ebReducedRecHitCollectionMiniAOD_, eeReducedRecHitCollectionMiniAOD_); + lazyToolnoZS = std::make_unique( + iEvent, iSetup, ebRecHits_.get(iEvent), eeRecHits_.get(iEvent)); } // Get PV - edm::Handle vertices; - iEvent.getByToken(vtxToken_, vertices); - if (!vertices.isValid()) - iEvent.getByToken(vtxTokenMiniAOD_, vertices); if (vertices->empty()) return; // skip the event if no PV found const reco::Vertex& pv = vertices->front(); - edm::Handle>> particleBasedIsolationMap; - if (isAOD_) { - // this exists only in AOD - iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap); - } - - edm::Handle> pfCandsHandle; - - iEvent.getByToken(pfCandsToken_, pfCandsHandle); - if (!pfCandsHandle.isValid()) - iEvent.getByToken(pfCandsTokenMiniAOD_, pfCandsHandle); - - if (!isAOD_ && !src->empty()) { - edm::Ptr test(src->ptrAt(0)); - if (test.isNull() || !test.isAvailable()) { - throw cms::Exception("InvalidConfiguration") - << "DataFormat is detected as miniAOD but cannot cast to pat::Photon!"; - } - } - std::vector vars[nVars_]; // reco::Photon::superCluster() is virtual so we can exploit polymorphism @@ -266,7 +225,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup // retrieve the full5x5 directly from the object with ->full5x5_sigmaIetaIeta() // for both formats. std::vector vCov = lazyToolnoZS->localCovariances(theseed); - vars[0].push_back(isnan(vCov[0]) ? 0. : sqrt(vCov[0])); + vars[0].push_back(edm::isNotFinite(vCov[0]) ? 0. : sqrt(vCov[0])); vars[1].push_back(vCov[1]); vars[2].push_back(lazyToolnoZS->e1x3(theseed)); vars[3].push_back(lazyToolnoZS->e2x2(theseed)); @@ -308,7 +267,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup // the PF collection do not contain the supercluser link, so can't // use that). // - // if( isAOD_ ) { + // if( isAOD ) { // if( ((const edm::Ptr)iCand)->superClusterRef() == iPho->superCluster() ) // continue; // } @@ -319,7 +278,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup continue; // Check if this candidate is not in the footprint - if (isAOD_) { + if (isAOD) { if(isInFootprint((*particleBasedIsolationMap)[iPho], iCand)) continue; } else { @@ -329,7 +288,7 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup } // Find candidate type - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(&*iCand); + reco::PFCandidate::ParticleType thisCandidateType = getCandidatePdgId(&*iCand, isAOD); // Increment the appropriate isolation sum if (thisCandidateType == reco::PFCandidate::h) { @@ -337,7 +296,8 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup // with the PV float dxy = -999; float dz = -999; - getImpactParameters(CachingPtrCandidate(&*iCand, isAOD_), pv, dxy, dz); + + getImpactParameters(CachingPtrCandidate(&*iCand, isAOD), pv, dxy, dz); if (fabs(dxy) > dxyMax || fabs(dz) > dzMax) continue; @@ -359,19 +319,19 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup // Worst isolation computed with no vetos or ptMin cut, as in Run 1 Hgg code. unsigned char options = 0; - vars[13].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + vars[13].push_back(computeWorstPFChargedIsolation(*iPho, *pfCandsHandle, *vertices, pv, options, isAOD)); // Worst isolation computed with cone vetos and a ptMin cut, as in Run 2 Hgg code. options |= PT_MIN_THRESH | DR_VETO; - vars[14].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + vars[14].push_back(computeWorstPFChargedIsolation(*iPho, *pfCandsHandle, *vertices, pv, options, isAOD)); // Like before, but adding primary vertex constraint options |= PV_CONSTRAINT; - vars[15].push_back(computeWorstPFChargedIsolation(iPho, pfCandsHandle, vertices, pv, options)); + vars[15].push_back(computeWorstPFChargedIsolation(*iPho, *pfCandsHandle, *vertices, pv, options, isAOD)); // PFCluster Isolations vars[16].push_back(iPho->trkSumPtSolidConeDR04()); - if (isAOD_) { + if (isAOD) { vars[17].push_back(0.f); vars[18].push_back(0.f); } else { @@ -379,72 +339,65 @@ void PhotonIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup vars[17].push_back(patPhotonPtr->hcalPFClusterIso()); vars[18].push_back(patPhotonPtr->ecalPFClusterIso()); } - } // write the value maps for (int i = 0; i < nVars_; ++i) { - auto valMap = std::make_unique>(); - edm::ValueMap::Filler filler(*valMap); - filler.insert(src, vars[i].begin(), vars[i].end()); - filler.fill(); - iEvent.put(std::move(valMap), names[i]); + writeValueMap(iEvent, src, vars[i], names[i]); } } -void PhotonIDValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) -{ - // The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.add("ebReducedRecHitCollection"); - desc.add("ebReducedRecHitCollectionMiniAOD"); - desc.add("eeReducedRecHitCollection"); - desc.add("eeReducedRecHitCollectionMiniAOD"); - desc.add("esReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsES")); - desc.add("esReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma:reducedESRecHits")); - desc.add("vertices"); - desc.add("verticesMiniAOD"); - desc.add("src"); - desc.add("srcMiniAOD"); - desc.add("particleBasedIsolation"); - desc.add("pfCandidates"); - desc.add("pfCandidatesMiniAOD"); - descriptions.addDefault(desc); +void PhotonIDValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // photonIDValueMapProducer + edm::ParameterSetDescription desc; + desc.add("particleBasedIsolation", edm::InputTag("particleBasedIsolation","gedPhotons")); + desc.add("src", edm::InputTag("gedPhotons")); + desc.add("srcMiniAOD", edm::InputTag("slimmedPhotons","","@skipCurrentProcess")); + desc.add("esReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedESRecHits")); + desc.add("eeReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEE")); + desc.add("pfCandidates", edm::InputTag("particleFlow")); + desc.add("vertices", edm::InputTag("offlinePrimaryVertices")); + desc.add("ebReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEBRecHits")); + desc.add("eeReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEERecHits")); + desc.add("esReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsES")); + desc.add("pfCandidatesMiniAOD", edm::InputTag("packedPFCandidates")); + desc.add("verticesMiniAOD", edm::InputTag("offlineSlimmedPrimaryVertices")); + desc.add("ebReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEB")); + descriptions.add("photonIDValueMapProducer", desc); } + // Charged isolation with respect to the worst vertex. See more // comments above at the function declaration. -template -float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, const U& pfCands, - const edm::Handle vertices, const reco::Vertex& pv, unsigned char options) +float PhotonIDValueMapProducer::computeWorstPFChargedIsolation(const reco::Photon& photon, const edm::View& pfCands, + const reco::VertexCollection& vertices, const reco::Vertex& pv, unsigned char options, bool isAOD) const { float worstIsolation = 0.0; - const float dRveto = photon->isEB() ? dRvetoBarrel : dRvetoEndcap; + const float dRveto = photon.isEB() ? dRvetoBarrel : dRvetoEndcap; std::vector chargedCands; - chargedCands.reserve(pfCands->size()); - for (auto const& aCand : *pfCands){ + chargedCands.reserve(pfCands.size()); + for (auto const& aCand : pfCands){ // require that PFCandidate is a charged hadron - reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(&aCand); + reco::PFCandidate::ParticleType thisCandidateType = getCandidatePdgId(&aCand, isAOD); if (thisCandidateType != reco::PFCandidate::h) continue; if ((options & PT_MIN_THRESH) && aCand.pt() < ptMin) continue; - chargedCands.emplace_back(&aCand, isAOD_); + chargedCands.emplace_back(&aCand, isAOD); } // Calculate isolation sum separately for each vertex - for (unsigned int ivtx = 0; ivtx < vertices->size(); ++ivtx) { + for (unsigned int ivtx = 0; ivtx < vertices.size(); ++ivtx) { // Shift the photon according to the vertex - reco::VertexRef vtx(vertices, ivtx); - math::XYZVector phoWrtVtx(photon->superCluster()->x() - vtx->x(), - photon->superCluster()->y() - vtx->y(), photon->superCluster()->z() - vtx->z()); + const reco::VertexRef vtx(&vertices, ivtx); + math::XYZVector phoWrtVtx(photon.superCluster()->x() - vtx->x(), + photon.superCluster()->y() - vtx->y(), photon.superCluster()->z() - vtx->z()); float sum = 0; // Loop over the PFCandidates @@ -475,30 +428,4 @@ float PhotonIDValueMapProducer ::computeWorstPFChargedIsolation(const T& photon, return worstIsolation; } -reco::PFCandidate::ParticleType PhotonIDValueMapProducer::candidatePdgId( - const reco::Candidate* candidate) -{ - if (isAOD_) - return static_cast(candidate)->particleId(); - - // the neutral hadrons and charged hadrons can be of pdgId types - // only 130 (K0L) and +-211 (pi+-) in packed candidates - const int pdgId = static_cast(candidate)->pdgId(); - if (pdgId == 22) - return reco::PFCandidate::gamma; - else if (abs(pdgId) == 130) // PDG ID for K0L - return reco::PFCandidate::h0; - else if (abs(pdgId) == 211) // PDG ID for pi+- - return reco::PFCandidate::h; - else - return reco::PFCandidate::X; -} - -const reco::Track* PhotonIDValueMapProducer::getTrackPointer(const edm::Ptr candidate) -{ - return isAOD_ ? - &*(((const edm::Ptr)candidate)->trackRef()) : - &(((const edm::Ptr)candidate)->pseudoTrack()); -} - DEFINE_FWK_MODULE(PhotonIDValueMapProducer); diff --git a/RecoEgamma/PhotonIdentification/python/PhotonIDValueMapProducer_cfi.py b/RecoEgamma/PhotonIdentification/python/PhotonIDValueMapProducer_cfi.py deleted file mode 100644 index aa3d6ac3be251..0000000000000 --- a/RecoEgamma/PhotonIdentification/python/PhotonIDValueMapProducer_cfi.py +++ /dev/null @@ -1,31 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -photonIDValueMapProducer = cms.EDProducer('PhotonIDValueMapProducer', - # The module automatically detects AOD vs miniAOD, so we configure both - # - # AOD case - # - ebReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEB"), - eeReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEE"), - esReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsES"), - particleBasedIsolation = cms.InputTag("particleBasedIsolation","gedPhotons"), - vertices = cms.InputTag("offlinePrimaryVertices"), - pfCandidates = cms.InputTag("particleFlow"), - src = cms.InputTag('gedPhotons'), - # - # miniAOD case - # - ebReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEBRecHits"), - eeReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEERecHits"), - esReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedESRecHits"), - verticesMiniAOD = cms.InputTag("offlineSlimmedPrimaryVertices"), - pfCandidatesMiniAOD = cms.InputTag("packedPFCandidates"), - # there is no need for the isolation map here, for miniAOD it is inside packedPFCandidates - srcMiniAOD = cms.InputTag('slimmedPhotons',processName=cms.InputTag.skipCurrentProcess()), - ) - -from Configuration.Eras.Modifier_phase2_common_cff import phase2_common -phase2_common.toModify(photonIDValueMapProducer, - esReducedRecHitCollection = cms.InputTag(""), - esReducedRecHitCollectionMiniAOD = cms.InputTag(""), -) diff --git a/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py b/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py index 5640dfcc98232..26f3b0afec97e 100644 --- a/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py +++ b/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py @@ -8,7 +8,7 @@ def loadEgmIdSequence(process, dataFormat): # Load the producer module to build full 5x5 cluster shapes and whatever # else is needed for IDs - process.load("RecoEgamma.PhotonIdentification.PhotonIDValueMapProducer_cfi") + process.load("RecoEgamma.PhotonIdentification.photonIDValueMapProducer_cff") # Load the producer for MVA IDs. Make sure it is also added to the sequence! process.load("RecoEgamma.PhotonIdentification.PhotonMVAValueMapProducer_cfi") diff --git a/RecoEgamma/PhotonIdentification/python/photonIDValueMapProducer_cff.py b/RecoEgamma/PhotonIdentification/python/photonIDValueMapProducer_cff.py new file mode 100644 index 0000000000000..8eef1d5e56966 --- /dev/null +++ b/RecoEgamma/PhotonIdentification/python/photonIDValueMapProducer_cff.py @@ -0,0 +1,9 @@ +from RecoEgamma.PhotonIdentification.photonIDValueMapProducer_cfi import * + +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Modifier_phase2_common_cff import phase2_common +phase2_common.toModify(photonIDValueMapProducer, + esReducedRecHitCollection = "", + esReducedRecHitCollectionMiniAOD = "", +) From 89fe032de19437a8551770c9d9d984c8060b8527 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 5 Dec 2018 19:10:34 +0100 Subject: [PATCH 11/12] Sync with 10_4_X --- RecoEgamma/EgammaTools/BuildFile.xml | 4 +- .../interface/AnyMVAEstimatorRun2Base.h | 50 ++- .../EgammaTools/interface/ConversionTools.h | 26 +- .../EgammaTools/interface/EffectiveAreas.h | 1 - .../EgammaTools/interface/GBRForestTools.h | 39 -- .../EgammaTools/interface/MVAObjectCache.h | 30 -- .../interface/MVAValueMapProducer.h | 172 ++++----- .../EgammaTools/interface/MVAVariableHelper.h | 55 +++ .../interface/MVAVariableManager.h | 140 +++----- .../interface/ThreadSafeStringCut.h | 44 +++ RecoEgamma/EgammaTools/plugins/BuildFile.xml | 2 - .../EgammaTools/plugins/EGEnergyAnalyzer.cc | 37 +- .../plugins/EGRegressionModifierV2.cc | 5 +- ...hotonConversionMVAComputerCondUtilities.cc | 19 - .../python/hgcalElectronIDValueMap_cff.py | 4 +- .../python/hgcalPhotonIDValueMap_cff.py | 4 +- RecoEgamma/EgammaTools/src/ConversionTools.cc | 117 +++--- .../EgammaTools/src/EcalRegressionData.cc | 3 +- RecoEgamma/EgammaTools/src/EffectiveAreas.cc | 3 - .../EgammaTools/src/EnergyScaleCorrection.cc | 1 - RecoEgamma/EgammaTools/src/GBRForestTools.cc | 151 -------- RecoEgamma/EgammaTools/src/MVAObjectCache.cc | 45 --- .../EgammaTools/src/MVAVariableHelper.cc | 108 ++++++ .../src/SCEnergyCorrectorSemiParm.cc | 3 +- .../PhotonConversionMVACopyToLocalDB_cfg.py | 29 -- .../ElectronIdentification/BuildFile.xml | 1 + .../interface/ElectronMVAEstimator.h | 22 +- .../interface/ElectronMVAEstimatorRun2.h | 82 +++-- .../interface/ElectronMVAVariableHelper.h | 179 ---------- .../interface/ElectronNeuralNet.h | 26 -- .../interface/SoftElectronMVAEstimator.h | 40 +-- .../plugins/ElectronIDSelectorNeuralNet.cc | 28 -- .../plugins/ElectronIDSelectorNeuralNet.h | 35 -- .../plugins/ElectronIDValueMapProducer.cc | 221 ++++-------- .../plugins/ElectronIdMVABased.cc | 133 ++----- .../plugins/ElectronMVANtuplizer.cc | 311 ++++++---------- .../plugins/ElectronMVAVariableHelper.cc | 10 - .../ElectronRegressionValueMapProducer.cc | 244 ------------- .../plugins/SealModule.cc | 9 - .../plugins/VersionedGsfElectronIdProducer.cc | 18 +- .../plugins/VersionedPatElectronIdProducer.cc | 17 +- .../plugins/cuts/GsfEleConversionVetoCut.cc | 6 +- .../python/ElectronIDValueMapProducer_cfi.py | 19 - .../python/ElectronMVAValueMapProducer_cfi.py | 15 - .../ElectronRegressionValueMapProducer_cfi.py | 21 -- .../ElectronIdentification/python/FWLite.py | 136 +++++++ .../mvaElectronID_Fall17_iso_V1_cff.py | 2 +- .../mvaElectronID_Fall17_iso_V2_cff.py | 24 +- .../mvaElectronID_Fall17_noIso_V1_cff.py | 2 +- .../mvaElectronID_Fall17_noIso_V2_cff.py | 16 +- ...mvaElectronID_Spring15_25ns_Trig_V1_cff.py | 2 +- ...ElectronID_Spring15_25ns_nonTrig_V1_cff.py | 2 +- ...mvaElectronID_Spring15_50ns_Trig_V1_cff.py | 2 +- ...ectronID_Spring16_GeneralPurpose_V1_cff.py | 7 +- .../mvaElectronID_Spring16_HZZ_V1_cff.py | 6 +- .../Identification/mvaElectronID_tools.py | 8 +- .../Training/ElectronMVANtuplizer_cfg.py | 124 ------- .../python/egmGsfElectronIDs_cff.py | 5 +- .../python/electronIdNeuralNetExt_cfi.py | 10 - .../python/electronIdNeuralNet_cfi.py | 12 - .../src/ElectronMVAEstimator.cc | 76 +--- .../src/ElectronMVAEstimatorRun2.cc | 131 ++++--- .../src/ElectronNeuralNet.cc | 6 - .../src/SoftElectronMVAEstimator.cc | 92 +---- .../test/testElectronMVA_cfg.py | 66 +++- .../test/test_eleid_fwlite.py | 108 ++++++ .../interface/PhotonMVAEstimator.h | 63 +--- .../plugins/BuildFile.xml | 1 + .../plugins/PhotonIDSimpleAnalyzer.h | 4 +- .../plugins/PhotonMVAEstimator.cc | 102 +++--- .../plugins/PhotonMVANtuplizer.cc | 332 +++++++++--------- .../PhotonRegressionValueMapProducer.cc | 262 -------------- .../mvaPhotonID_Fall17_94X_V1_cff.py | 13 +- .../mvaPhotonID_Fall17_94X_V1p1_cff.py | 13 +- .../mvaPhotonID_Fall17_94X_V2_cff.py | 5 +- ...vaPhotonID_Spring15_25ns_nonTrig_V0_cff.py | 13 +- ...vaPhotonID_Spring15_25ns_nonTrig_V2_cff.py | 15 +- ...PhotonID_Spring15_25ns_nonTrig_V2p1_cff.py | 17 +- ...vaPhotonID_Spring15_50ns_nonTrig_V0_cff.py | 13 +- ...vaPhotonID_Spring15_50ns_nonTrig_V1_cff.py | 13 +- ...vaPhotonID_Spring15_50ns_nonTrig_V2_cff.py | 13 +- ...PhotonID_Spring15_50ns_nonTrig_V2p1_cff.py | 15 +- .../mvaPhotonID_Spring16_nonTrig_V1_cff.py | 3 + .../Identification/mvaPhotonID_tools.py | 6 +- .../PhotonRegressionValueMapProducer_cfi.py | 22 -- .../python/egmPhotonIDs_cff.py | 4 +- .../test/testPhotonMVA_cfg.py | 31 +- 87 files changed, 1444 insertions(+), 2882 deletions(-) delete mode 100644 RecoEgamma/EgammaTools/interface/GBRForestTools.h delete mode 100644 RecoEgamma/EgammaTools/interface/MVAObjectCache.h create mode 100644 RecoEgamma/EgammaTools/interface/MVAVariableHelper.h create mode 100644 RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h delete mode 100644 RecoEgamma/EgammaTools/plugins/PhotonConversionMVAComputerCondUtilities.cc delete mode 100644 RecoEgamma/EgammaTools/src/GBRForestTools.cc delete mode 100644 RecoEgamma/EgammaTools/src/MVAObjectCache.cc create mode 100644 RecoEgamma/EgammaTools/src/MVAVariableHelper.cc delete mode 100644 RecoEgamma/EgammaTools/test/PhotonConversionMVACopyToLocalDB_cfg.py delete mode 100644 RecoEgamma/ElectronIdentification/interface/ElectronMVAVariableHelper.h delete mode 100644 RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h delete mode 100644 RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.cc delete mode 100644 RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h delete mode 100644 RecoEgamma/ElectronIdentification/plugins/ElectronMVAVariableHelper.cc delete mode 100644 RecoEgamma/ElectronIdentification/plugins/ElectronRegressionValueMapProducer.cc delete mode 100644 RecoEgamma/ElectronIdentification/python/ElectronIDValueMapProducer_cfi.py delete mode 100644 RecoEgamma/ElectronIdentification/python/ElectronRegressionValueMapProducer_cfi.py create mode 100644 RecoEgamma/ElectronIdentification/python/FWLite.py delete mode 100644 RecoEgamma/ElectronIdentification/python/Training/ElectronMVANtuplizer_cfg.py delete mode 100644 RecoEgamma/ElectronIdentification/python/electronIdNeuralNetExt_cfi.py delete mode 100644 RecoEgamma/ElectronIdentification/python/electronIdNeuralNet_cfi.py delete mode 100644 RecoEgamma/ElectronIdentification/src/ElectronNeuralNet.cc create mode 100644 RecoEgamma/ElectronIdentification/test/test_eleid_fwlite.py delete mode 100644 RecoEgamma/PhotonIdentification/plugins/PhotonRegressionValueMapProducer.cc delete mode 100644 RecoEgamma/PhotonIdentification/python/PhotonRegressionValueMapProducer_cfi.py diff --git a/RecoEgamma/EgammaTools/BuildFile.xml b/RecoEgamma/EgammaTools/BuildFile.xml index 9550cfc3a89b9..112b7010f29fa 100644 --- a/RecoEgamma/EgammaTools/BuildFile.xml +++ b/RecoEgamma/EgammaTools/BuildFile.xml @@ -7,15 +7,13 @@ - - + - diff --git a/RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h b/RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h index 3a5b9a1620d00..f227025be1609 100644 --- a/RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h +++ b/RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h @@ -12,28 +12,45 @@ class AnyMVAEstimatorRun2Base { public: // Constructor, destructor - AnyMVAEstimatorRun2Base(const edm::ParameterSet& conf) : conf_(conf) {} + AnyMVAEstimatorRun2Base(const edm::ParameterSet& conf) + : tag_ (conf.getParameter("mvaTag")) + , nCategories_ (conf.getParameter("nCategories")) + , debug_ (conf.getUntrackedParameter("debug", false)) + {} + + AnyMVAEstimatorRun2Base(const::std::string& mvaName, + const::std::string& mvaTag, + int nCategories, + bool debug) + : name_ (mvaName) + , tag_ (mvaTag) + , nCategories_ (nCategories) + , debug_ (debug) + {} virtual ~AnyMVAEstimatorRun2Base(){}; // Functions that must be provided in derived classes // These function should work on electrons or photons // of the reco or pat type - virtual float mvaValue( const edm::Ptr& particle, const edm::EventBase&) const = 0; + virtual float mvaValue( const reco::Candidate* candidate, std::vector const& auxVariables, int &iCategory) const = 0; + float mvaValue( const reco::Candidate* candidate, std::vector const& auxVariables) const { + int iCategory; + return mvaValue(candidate, auxVariables, iCategory); + }; // A specific implementation of MVA is expected to have one or more categories // defined with respect to eta, pt, etc. - // This function determines the category for a given particle. - virtual int findCategory( const edm::Ptr& particle) const = 0; - virtual int getNCategories() const = 0; - // The name is a unique name associated with a particular MVA implementation, - // it is found as a const data member in a derived class. - virtual const std::string& getName() const = 0; + // This function determines the category for a given candidate. + virtual int findCategory( const reco::Candidate* candidate) const = 0; + int getNCategories() const { return nCategories_; } + const std::string& getName() const { return name_; } // An extra variable string set during construction that can be used // to distinguish different instances of the estimator configured with // different weight files. The tag can be used to construct names of ValueMaps, etc. - virtual const std::string& getTag() const = 0; + const std::string& getTag() const { return tag_; } + bool isDebug() const { return debug_; } // // Extra event content - if needed. // @@ -41,17 +58,22 @@ class AnyMVAEstimatorRun2Base { // Implement these methods only if needed in the derived classes (use "override" // for certainty). - // This method needs to be used only once after this MVA estimator is constructed - virtual void setConsumes(edm::ConsumesCollector &&cc) const {}; - private: // // Data members // - // Configuration - const edm::ParameterSet conf_; + const std::string name_; + + // MVA tag. This is an additional string variable to distinguish + // instances of the estimator of this class configured with different + // weight files. + const std::string tag_; + + // The number of categories and number of variables per category + const int nCategories_; + const bool debug_; }; // define the factory for this base class diff --git a/RecoEgamma/EgammaTools/interface/ConversionTools.h b/RecoEgamma/EgammaTools/interface/ConversionTools.h index c98781fff7200..ad9cd5b948172 100644 --- a/RecoEgamma/EgammaTools/interface/ConversionTools.h +++ b/RecoEgamma/EgammaTools/interface/ConversionTools.h @@ -48,30 +48,30 @@ class ConversionTools static bool hasMatchedConversion(const reco::GsfElectron &ele, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); static bool hasMatchedConversion(const reco::TrackRef &trk, - const edm::Handle &convCol, const math::XYZPoint &beamspot, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); static bool hasMatchedConversion(const reco::SuperCluster &sc, - const edm::Handle &convCol, const math::XYZPoint &beamspot, float dRMax = 0.1, float dEtaMax = 999., float dPhiMax = 999., float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float dRMax = 0.1, float dEtaMax = 999., float dPhiMax = 999., float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); - static reco::ConversionRef matchedConversion(const reco::GsfElectron &ele, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); + static reco::Conversion const* matchedConversion(const reco::GsfElectron &ele, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); - static reco::ConversionRef matchedConversion(const reco::TrackRef &trk, - const edm::Handle &convCol, const math::XYZPoint &beamspot, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); + static reco::Conversion const* matchedConversion(const reco::TrackRef &trk, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); - static reco::ConversionRef matchedConversion(const reco::SuperCluster &sc, - const edm::Handle &convCol, const math::XYZPoint &beamspot, float dRMax = 0.1, float dEtaMax = 999., float dPhiMax = 999., float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); + static reco::Conversion const* matchedConversion(const reco::SuperCluster &sc, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float dRMax = 0.1, float dEtaMax = 999., float dPhiMax = 999., float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=1); - static bool hasMatchedPromptElectron(const reco::SuperClusterRef &sc, const edm::Handle &eleCol, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); + static bool hasMatchedPromptElectron(const reco::SuperClusterRef &sc, const reco::GsfElectronCollection &eleCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); - static reco::GsfElectronRef matchedPromptElectron(const reco::SuperClusterRef &sc, const edm::Handle &eleCol, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); + static reco::GsfElectron const* matchedPromptElectron(const reco::SuperClusterRef &sc, const reco::GsfElectronCollection &eleCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0); }; #endif diff --git a/RecoEgamma/EgammaTools/interface/EffectiveAreas.h b/RecoEgamma/EgammaTools/interface/EffectiveAreas.h index 1a9b7cc282300..460a3205ae308 100644 --- a/RecoEgamma/EgammaTools/interface/EffectiveAreas.h +++ b/RecoEgamma/EgammaTools/interface/EffectiveAreas.h @@ -10,7 +10,6 @@ class EffectiveAreas { public: // Constructor, destructor EffectiveAreas(const std::string& filename); - ~EffectiveAreas(); // Accessors const float getEffectiveArea(float eta) const; diff --git a/RecoEgamma/EgammaTools/interface/GBRForestTools.h b/RecoEgamma/EgammaTools/interface/GBRForestTools.h deleted file mode 100644 index c72812070a2ea..0000000000000 --- a/RecoEgamma/EgammaTools/interface/GBRForestTools.h +++ /dev/null @@ -1,39 +0,0 @@ -//-------------------------------------------------------------------------------------------------- -// -// GRBForestTools -// -// Utility to read a TMVA weights file with a BDT into a GRBForest. -// -// Author: Jonas Rembser -//-------------------------------------------------------------------------------------------------- - - -#ifndef RecoEgamma_EgammaTools_GBRForestTools_h -#define RecoEgamma_EgammaTools_GBRForestTools_h - -#include -#include - -#include "CondFormats/EgammaObjects/interface/GBRForest.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" - -#include "TMVA/MethodBDT.h" -#include "TMVA/Reader.h" - -#include "CommonTools/Utils/interface/TMVAZipReader.h" - -class GBRForestTools -{ - public: - GBRForestTools() {} - - static std::unique_ptr createGBRForest(const std::string &weightFile); - static std::unique_ptr createGBRForest(const edm::FileInPath &weightFile); - - // Overloaded versions which are taking string vectors by reference to strore the variable names in - static std::unique_ptr createGBRForest(const std::string &weightFile, std::vector &varNames); - static std::unique_ptr createGBRForest(const edm::FileInPath &weightFile, std::vector &varNames); - -}; - -#endif diff --git a/RecoEgamma/EgammaTools/interface/MVAObjectCache.h b/RecoEgamma/EgammaTools/interface/MVAObjectCache.h deleted file mode 100644 index a47c8174618ea..0000000000000 --- a/RecoEgamma/EgammaTools/interface/MVAObjectCache.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __RecoEgamma_EgammaTools_MVAObjectCache_H__ -#define __RecoEgamma_EgammaTools_MVAObjectCache_H__ - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h" - -#include -#include -#include - -namespace egamma { - - class MVAObjectCache { - public: - typedef std::unique_ptr MVAPtr; - - MVAObjectCache(const edm::ParameterSet& conf); - - const MVAPtr& getMVA(const std::string& mva) const; - - const std::unordered_map& allMVAs() const { - return mvas_; - } - private: - std::unordered_map mvas_; - }; - -} -#endif diff --git a/RecoEgamma/EgammaTools/interface/MVAValueMapProducer.h b/RecoEgamma/EgammaTools/interface/MVAValueMapProducer.h index 1d0ab1f438c10..bc55e83b851a1 100644 --- a/RecoEgamma/EgammaTools/interface/MVAValueMapProducer.h +++ b/RecoEgamma/EgammaTools/interface/MVAValueMapProducer.h @@ -1,133 +1,109 @@ #ifndef __RecoEgamma_EgammaTools_MVAValueMapProducer_H__ #define __RecoEgamma_EgammaTools_MVAValueMapProducer_H__ -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" - +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/Common/interface/View.h" #include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/Framework/interface/MakerMacros.h" - #include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/Common/interface/ValueMap.h" -#include "DataFormats/Common/interface/View.h" - #include "RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h" +#include "RecoEgamma/EgammaTools/interface/Utils.h" +#include "RecoEgamma/EgammaTools/interface/MultiToken.h" +#include "RecoEgamma/EgammaTools/interface/MVAVariableHelper.h" #include #include #include template -class MVAValueMapProducer : public edm::stream::EDProducer<> { +class MVAValueMapProducer : public edm::global::EDProducer<> { public: MVAValueMapProducer(const edm::ParameterSet&); - ~MVAValueMapProducer() override; + ~MVAValueMapProducer() override {} static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: - void produce(edm::Event&, const edm::EventSetup&) override; - - template - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - // for AOD case - edm::EDGetToken src_; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - // for miniAOD case - edm::EDGetToken srcMiniAOD_; + // for AOD and MiniAOD case + const MultiTokenT> src_; - // MVA estimator - std::vector> mvaEstimators_; + // MVA estimators + const std::vector> mvaEstimators_; // Value map names - std::vector mvaValueMapNames_; - std::vector mvaRawValueMapNames_; - std::vector mvaCategoriesMapNames_; - -}; - -template -MVAValueMapProducer::MVAValueMapProducer(const edm::ParameterSet& iConfig) -{ - - // - // Declare consummables, handle both AOD and miniAOD case - // - src_ = mayConsume >(iConfig.getParameter("src")); - srcMiniAOD_ = mayConsume >(iConfig.getParameter("srcMiniAOD")); - - // Loop over the list of MVA configurations passed here from python and - // construct all requested MVA estimators. - const std::vector& mvaEstimatorConfigs - = iConfig.getParameterSetVector("mvaConfigurations"); + const std::vector mvaValueMapNames_; + const std::vector mvaRawValueMapNames_; + const std::vector mvaCategoriesMapNames_; - for( auto &imva : mvaEstimatorConfigs ){ + // To get the auxiliary MVA variables + const MVAVariableHelper variableHelper_; - // The factory below constructs the MVA of the appropriate type based - // on the "mvaName" which is the name of the derived MVA class (plugin) - if( !imva.empty() ) { - - mvaEstimators_.emplace_back(AnyMVAEstimatorRun2Factory::get()->create( - imva.getParameter("mvaName"), imva)); +}; - } else - throw cms::Exception(" MVA configuration not found: ") - << " failed to find proper configuration for one of the MVAs in the main python script " << std::endl; +namespace { - mvaEstimators_.back()->setConsumes( consumesCollector() ); + auto getMVAEstimators(const edm::VParameterSet& vConfig) + { + std::vector> mvaEstimators; - // - // Compose and save the names of the value maps to be produced - // + // Loop over the list of MVA configurations passed here from python and + // construct all requested MVA estimators. + for( auto &imva : vConfig ) + { - const std::string fullName = ( mvaEstimators_.back()->getName() + - mvaEstimators_.back()->getTag() ); + // The factory below constructs the MVA of the appropriate type based + // on the "mvaName" which is the name of the derived MVA class (plugin) + if( !imva.empty() ) { - const std::string thisValueMapName = fullName + "Values"; - const std::string thisRawValueMapName = fullName + "RawValues"; - const std::string thisCategoriesMapName = fullName + "Categories"; + mvaEstimators.emplace_back(AnyMVAEstimatorRun2Factory::get()->create( + imva.getParameter("mvaName"), imva)); - mvaValueMapNames_ .push_back( thisValueMapName ); - mvaRawValueMapNames_ .push_back( thisRawValueMapName ); - mvaCategoriesMapNames_.push_back( thisCategoriesMapName ); + } else + throw cms::Exception(" MVA configuration not found: ") + << " failed to find proper configuration for one of the MVAs in the main python script " << std::endl; + } - // Declare the maps to the framework - produces>(thisValueMapName ); - produces>(thisRawValueMapName ); - produces> (thisCategoriesMapName); + return mvaEstimators; + } - } + std::vector getValueMapNames(const edm::VParameterSet& vConfig, std::string && suffix) + { + std::vector names; + for( auto &imva : vConfig ) + { + names.push_back(imva.getParameter("mvaName") + imva.getParameter("mvaTag") + suffix); + } + return names; + } } template -MVAValueMapProducer::~MVAValueMapProducer() { +MVAValueMapProducer::MVAValueMapProducer(const edm::ParameterSet& iConfig) + : src_(consumesCollector(), iConfig, "src", "srcMiniAOD") + , mvaEstimators_(getMVAEstimators(iConfig.getParameterSetVector("mvaConfigurations"))) + , mvaValueMapNames_ (getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "Values" )) + , mvaRawValueMapNames_ (getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "RawValues" )) + , mvaCategoriesMapNames_(getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "Categories")) + , variableHelper_(consumesCollector()) +{ + for( auto const& name : mvaValueMapNames_ ) produces>(name); + for( auto const& name : mvaRawValueMapNames_ ) produces>(name); + for( auto const& name : mvaCategoriesMapNames_ ) produces>(name); } template -void MVAValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - - edm::Handle > src; - - // Retrieve the collection of particles from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - iEvent.getByToken(src_, src); - if( !src.isValid() ){ - iEvent.getByToken(srcMiniAOD_,src); - if( !src.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD particle collection " << std::endl; - } +void MVAValueMapProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const +{ + edm::Handle > src = src_.getValidHandle(iEvent); // Loop over MVA estimators for( unsigned iEstimator = 0; iEstimator < mvaEstimators_.size(); iEstimator++ ){ @@ -137,12 +113,17 @@ void MVAValueMapProducer::produce(edm::Event& iEvent, const edm::E std::vector mvaCategories; // Loop over particles - for (size_t i = 0; i < src->size(); ++i){ + for (size_t i = 0; i < src->size(); ++i) + { auto iCand = src->ptrAt(i); - const float response = mvaEstimators_[iEstimator]->mvaValue( iCand, iEvent ); + + std::vector auxVariables = variableHelper_.getAuxVariables(iCand, iEvent); + + int cat = -1; // Passed by reference to the mvaValue function to store the category + const float response = mvaEstimators_[iEstimator]->mvaValue( &(*iCand), auxVariables, cat ); mvaRawValues.push_back( response ); // The MVA score mvaValues.push_back( 2.0/(1.0+exp(-2.0*response))-1 ); // MVA output between -1 and 1 - mvaCategories.push_back( mvaEstimators_[iEstimator]->findCategory( iCand ) ); + mvaCategories.push_back( cat ); } // end loop over particles writeValueMap(iEvent, src, mvaValues , mvaValueMapNames_ [iEstimator] ); @@ -153,19 +134,6 @@ void MVAValueMapProducer::produce(edm::Event& iEvent, const edm::E } -template template -void MVAValueMapProducer::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - auto valMap = std::make_unique>(); - typename edm::ValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); -} - template void MVAValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { //The following says we do not know what parameters are allowed so do no validation diff --git a/RecoEgamma/EgammaTools/interface/MVAVariableHelper.h b/RecoEgamma/EgammaTools/interface/MVAVariableHelper.h new file mode 100644 index 0000000000000..d82edb69c44de --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/MVAVariableHelper.h @@ -0,0 +1,55 @@ +#ifndef RecoEgamma_EgammaTools_MVAVariableHelper_H +#define RecoEgamma_EgammaTools_MVAVariableHelper_H + +#include "DataFormats/Common/interface/ValueMap.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Framework/interface/Event.h" + +#include +#include +#include + +template +class MVAVariableIndexMap { + + public: + + MVAVariableIndexMap(); + + int getIndex(std::string const& name) const { return indexMap_.at(name); } + + private: + + const std::unordered_map indexMap_; +}; + +template +class MVAVariableHelper { + + public: + + MVAVariableHelper(edm::ConsumesCollector && cc); + + const std::vector getAuxVariables(edm::Ptr const& particlePtr, + const edm::Event& iEvent) const; + + private: + + static float getVariableFromValueMapToken(edm::Ptr const& particlePtr, + edm::EDGetToken const& token, edm::Event const& iEvent) { + edm::Handle> handle; + iEvent.getByToken(token, handle); + return (*handle)[particlePtr]; + } + + static float getVariableFromDoubleToken(edm::EDGetToken const& token, const edm::Event& iEvent) { + edm::Handle handle; + iEvent.getByToken(token, handle); + return *handle; + } + + const std::vector tokens_; +}; + +#endif diff --git a/RecoEgamma/EgammaTools/interface/MVAVariableManager.h b/RecoEgamma/EgammaTools/interface/MVAVariableManager.h index 2e91a9c6c4137..8bfb5e8a31772 100644 --- a/RecoEgamma/EgammaTools/interface/MVAVariableManager.h +++ b/RecoEgamma/EgammaTools/interface/MVAVariableManager.h @@ -1,48 +1,32 @@ #ifndef RecoEgamma_EgammaTools_MVAVariableManager_H #define RecoEgamma_EgammaTools_MVAVariableManager_H -#include - -#include "CommonTools/Utils/interface/StringObjectFunction.h" -#include "CommonTools/Utils/interface/StringCutObjectSelector.h" - #include "FWCore/ParameterSet/interface/FileInPath.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/ValueMap.h" - +#include "DataFormats/Candidate/interface/Candidate.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Utilities/interface/thread_safety_macros.h" +#include "RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h" +#include "RecoEgamma/EgammaTools/interface/MVAVariableHelper.h" -#include "DataFormats/Candidate/interface/Candidate.h" +#include template class MVAVariableManager { public: - MVAVariableManager() { - nVars_ = 0; - }; - - MVAVariableManager(const std::string &variableDefinitionFileName) { - init(variableDefinitionFileName); - }; - - int init(const std::string &variableDefinitionFileName) { - nVars_ = 0; - - variableInfos_.clear(); - functions_.clear(); - formulas_.clear(); - names_.clear(); - helperInputTags_.clear(); - globalInputTags_.clear(); + MVAVariableManager(const std::string &variableDefinitionFileName) + : nVars_ (0) + { edm::FileInPath variableDefinitionFileEdm(variableDefinitionFileName); std::ifstream file(variableDefinitionFileEdm.fullPath()); std::string name, formula, upper, lower; while( true ) { file >> name; + if(file.eof()) { + break; + } if (name.find("#") != std::string::npos) { file.ignore(std::numeric_limits::max(), '\n'); continue; @@ -53,10 +37,10 @@ class MVAVariableManager { } addVariable(name, formula, lower, upper); } - return nVars_; - }; + } - int getVarIndex(std::string &name) { + int getVarIndex(const std::string &name) + { std::map::iterator it = indexMap_.find(name); if (it == indexMap_.end()) { return -1; @@ -65,36 +49,22 @@ class MVAVariableManager { } } - const std::string getName(int index) const { + const std::string& getName(int index) const { return names_[index]; } - const int getNVars() const { + int getNVars() const { return nVars_; } - std::vector getHelperInputTags() const { - return helperInputTags_; - } - - std::vector getGlobalInputTags() const { - return globalInputTags_; - } - - float getValue(int index, const edm::Ptr& ptclPtr, const edm::EventBase& iEvent) const { + float getValue(int index, const ParticleType& particle, const std::vector& auxVariables) const { float value; + MVAVariableInfo varInfo = variableInfos_[index]; - if (varInfo.fromVariableHelper) { - edm::Handle> vMap; - iEvent.getByLabel(edm::InputTag(formulas_[index]), vMap); - value = (*vMap)[ptclPtr]; - } else if (varInfo.isGlobalVariable) { - edm::Handle valueHandle; - iEvent.getByLabel(edm::InputTag(formulas_[index]), valueHandle); - value = *valueHandle; - } else { - value = functions_[index](*ptclPtr); - } + + if (varInfo.auxIndex >= 0) value = auxVariables[varInfo.auxIndex]; + else value = functions_[index](particle); + if (varInfo.hasLowerClip && value < varInfo.lowerClipValue) { value = varInfo.lowerClipValue; } @@ -107,68 +77,58 @@ class MVAVariableManager { private: struct MVAVariableInfo { - bool hasLowerClip; - bool hasUpperClip; + bool hasLowerClip; + bool hasUpperClip; float lowerClipValue; float upperClipValue; - bool fromVariableHelper; - bool isGlobalVariable; + int auxIndex; }; - void addVariable(std::string &name, std::string &formula, std::string &lowerClip, std::string &upperClip) { + void addVariable(const std::string &name, const std::string &formula, + const std::string &lowerClip, const std::string &upperClip) + { bool hasLowerClip = lowerClip.find("None") == std::string::npos; bool hasUpperClip = upperClip.find("None") == std::string::npos; - bool fromVariableHelper = formula.find("MVAVariableHelper") != std::string::npos || - formula.find("IDValueMapProducer") != std::string::npos || - formula.find("egmPhotonIsolation") != std::string::npos; + bool isAuxiliary = formula.find("MVAVariableHelper") != std::string::npos || + formula.find("IDValueMapProducer") != std::string::npos || + formula.find("egmPhotonIsolation") != std::string::npos || + formula.find("Rho") != std::string::npos; + // *Rho* is still hardcoded... float lowerClipValue = hasLowerClip ? (float)::atof(lowerClip.c_str()) : 0.; float upperClipValue = hasUpperClip ? (float)::atof(upperClip.c_str()) : 0.; - // *Rho* is the only global variable used ever, so its hardcoded... - bool isGlobalVariable = formula.find("Rho") != std::string::npos; - - if ( !(fromVariableHelper || isGlobalVariable) ) { - functions_.push_back(StringObjectFunction(formula)); - } else { - // Push back a dummy function since we won't use the - // StringObjectFunction to evaluate a variable form the helper or a - // global variable - functions_.push_back(StringObjectFunction("pt")); - } + if ( !isAuxiliary ) functions_.emplace_back(formula); + // Else push back a dummy function since we won't use the + // StringObjectFunction to evaluate an auxiliary variable + else functions_.emplace_back("pt"); formulas_.push_back(formula); - if (fromVariableHelper) { - helperInputTags_.push_back(edm::InputTag(formula)); - } - if (isGlobalVariable) { - globalInputTags_.push_back(edm::InputTag(formula)); - } - MVAVariableInfo varInfo = { - .hasLowerClip = hasLowerClip, - .hasUpperClip = hasUpperClip, - .lowerClipValue = lowerClipValue, - .upperClipValue = upperClipValue, - .fromVariableHelper = fromVariableHelper, - .isGlobalVariable = isGlobalVariable + + int auxIndex = isAuxiliary ? indexMap.getIndex(formula) : -1; + + MVAVariableInfo varInfo { + .hasLowerClip = hasLowerClip, + .hasUpperClip = hasUpperClip, + .lowerClipValue = lowerClipValue, + .upperClipValue = upperClipValue, + .auxIndex = auxIndex, }; + variableInfos_.push_back(varInfo); names_.push_back(name); indexMap_[name] = nVars_; nVars_++; }; - int nVars_; + std::vector variableInfos_; - std::vector> functions_; + std::vector, ParticleType>> functions_; std::vector formulas_; std::vector names_; std::map indexMap_; - // To store the MVAVariableHelper input tags needed for the variables in this container - std::vector helperInputTags_; - - std::vector globalInputTags_; + const MVAVariableIndexMap indexMap; }; #endif diff --git a/RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h b/RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h new file mode 100644 index 0000000000000..a642504b1369d --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h @@ -0,0 +1,44 @@ +#ifndef RecoEgamma_EgammaTools_ThreadSafeStringCut_H +#define RecoEgamma_EgammaTools_ThreadSafeStringCut_H + +#include "CommonTools/Utils/interface/StringObjectFunction.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" + +#include +#include "FWCore/Utilities/interface/thread_safety_macros.h" + +/* + * This class is a simple wrapper around either a StringObjectFunction or + * StringCutObjectSelector to use them in a thread safe way. + * + */ + +template +class ThreadSafeStringCut +{ + public: + + ThreadSafeStringCut(const std::string & expr) // constructor + : func_(expr) + , expr_(expr) + {} + + ThreadSafeStringCut(ThreadSafeStringCut&& other) noexcept // move constructor + : func_(std::move(other.func_)) + , expr_(std::move(other.expr_)) + {} + + typename std::result_of::type operator()(const T & t) const + { + std::lock_guard guard(mutex_); + return func_(t); + } + + private: + + const F func_; + const std::string expr_; + CMS_THREAD_SAFE mutable std::mutex mutex_; +}; + +#endif diff --git a/RecoEgamma/EgammaTools/plugins/BuildFile.xml b/RecoEgamma/EgammaTools/plugins/BuildFile.xml index 0f2d1cf346ad3..5b8a79e4a1088 100644 --- a/RecoEgamma/EgammaTools/plugins/BuildFile.xml +++ b/RecoEgamma/EgammaTools/plugins/BuildFile.xml @@ -1,8 +1,6 @@ - - diff --git a/RecoEgamma/EgammaTools/plugins/EGEnergyAnalyzer.cc b/RecoEgamma/EgammaTools/plugins/EGEnergyAnalyzer.cc index 49bea8062ff03..3d052ec59e5cf 100644 --- a/RecoEgamma/EgammaTools/plugins/EGEnergyAnalyzer.cc +++ b/RecoEgamma/EgammaTools/plugins/EGEnergyAnalyzer.cc @@ -22,7 +22,7 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -45,7 +45,7 @@ // class declaration // -class EGEnergyAnalyzer : public edm::EDAnalyzer { +class EGEnergyAnalyzer : public edm::one::EDAnalyzer<> { public: explicit EGEnergyAnalyzer(const edm::ParameterSet&); ~EGEnergyAnalyzer() override; @@ -55,14 +55,9 @@ class EGEnergyAnalyzer : public edm::EDAnalyzer { private: void beginJob() override ; - void analyze(const edm::Event&, const edm::EventSetup&) override; + void analyze( const edm::Event&, const edm::EventSetup&) override; void endJob() override ; - void beginRun(edm::Run const&, edm::EventSetup const&) override; - void endRun(edm::Run const&, edm::EventSetup const&) override; - void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override; - void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override; - EGEnergyCorrector corfile; EGEnergyCorrector cordb; @@ -92,7 +87,7 @@ EGEnergyAnalyzer::~EGEnergyAnalyzer() // ------------ method called for each event ------------ void -EGEnergyAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) +EGEnergyAnalyzer::analyze( const edm::Event& iEvent, const edm::EventSetup& iSetup) { using namespace edm; @@ -146,30 +141,6 @@ EGEnergyAnalyzer::endJob() { } -// ------------ method called when starting to processes a run ------------ -void -EGEnergyAnalyzer::beginRun(edm::Run const&, edm::EventSetup const&) -{ -} - -// ------------ method called when ending the processing of a run ------------ -void -EGEnergyAnalyzer::endRun(edm::Run const&, edm::EventSetup const&) -{ -} - -// ------------ method called when starting to processes a luminosity block ------------ -void -EGEnergyAnalyzer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) -{ -} - -// ------------ method called when ending the processing of a luminosity block ------------ -void -EGEnergyAnalyzer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) -{ -} - // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void EGEnergyAnalyzer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { diff --git a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc index c0cc834ce04aa..afa8014e21c50 100644 --- a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc +++ b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc @@ -11,6 +11,7 @@ #include "CondFormats/DataRecord/interface/GBRDWrapperRcd.h" #include "CondFormats/EgammaObjects/interface/GBRForestD.h" #include "RecoEgamma/EgammaTools/interface/EcalClusterLocal.h" +#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include @@ -361,7 +362,7 @@ void EGRegressionModifierV2::modifyObject(reco::GsfElectron& ele) const { const edm::Ptr& theseed = the_sc->seed(); // skip HGCAL for now - if( theseed->seed().det() == DetId::Forward ) return; + if( EcalTools::isHGCalDet(theseed->seed().det()) ) return; const int numberOfClusters = the_sc->clusters().size(); const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable(); @@ -561,7 +562,7 @@ void EGRegressionModifierV2::modifyObject(reco::Photon& pho) const { const edm::Ptr& theseed = the_sc->seed(); // skip HGCAL for now - if( theseed->seed().det() == DetId::Forward ) return; + if( EcalTools::isHGCalDet(theseed->seed().det()) ) return; const int numberOfClusters = the_sc->clusters().size(); const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable(); diff --git a/RecoEgamma/EgammaTools/plugins/PhotonConversionMVAComputerCondUtilities.cc b/RecoEgamma/EgammaTools/plugins/PhotonConversionMVAComputerCondUtilities.cc deleted file mode 100644 index ac270cf6bdc4b..0000000000000 --- a/RecoEgamma/EgammaTools/plugins/PhotonConversionMVAComputerCondUtilities.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/SourceFactory.h" - -#include "PhysicsTools/MVAComputer/interface/MVAComputerESSourceImpl.h" -#include "PhysicsTools/MVATrainer/interface/MVATrainerSaveImpl.h" - -#include "CondFormats/DataRecord/interface/PhotonConversionMVAComputerRcd.h" -#include "PhysicsTools/MVAComputer/interface/HelperMacros.h" - -using namespace PhysicsTools; - -typedef MVAComputerESSourceImpl PhotonConversionMVAComputerESSource; -DEFINE_FWK_EVENTSETUP_SOURCE(PhotonConversionMVAComputerESSource); - -typedef MVATrainerContainerSaveImpl PhotonConversionMVAComputerSave; -DEFINE_FWK_MODULE(PhotonConversionMVAComputerSave); - -MVA_COMPUTER_CONTAINER_FILE_SOURCE_IMPLEMENT(PhotonConversionMVAComputerRcd, PhotonConversionMVAComputerFileSource); -// eof diff --git a/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py b/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py index dd4da071e2d2f..bb5db38ad3ceb 100644 --- a/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py +++ b/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX_weights +from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX # cfi from HGCalElectronIDValueMapProducer::fillDescriptions() from RecoEgamma.EgammaTools.hgcalElectronIDValueMap_cfi import * -hgcalElectronIDValueMap.dEdXWeights = dEdX_weights +hgcalElectronIDValueMap.dEdXWeights = dEdX.weights diff --git a/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py b/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py index dbefc5da6757d..f3c18e35f0278 100644 --- a/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py +++ b/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX_weights +from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX # cfi from HGCalPhotonIDValueMapProducer::fillDescriptions() from RecoEgamma.EgammaTools.hgcalPhotonIDValueMap_cfi import * -hgcalPhotonIDValueMap.dEdXWeights = dEdX_weights +hgcalPhotonIDValueMap.dEdXWeights = dEdX.weights diff --git a/RecoEgamma/EgammaTools/src/ConversionTools.cc b/RecoEgamma/EgammaTools/src/ConversionTools.cc index 05bdc04e7fdd3..16257e3b12ee4 100644 --- a/RecoEgamma/EgammaTools/src/ConversionTools.cc +++ b/RecoEgamma/EgammaTools/src/ConversionTools.cc @@ -1,4 +1,3 @@ - #include #include "RecoEgamma/EgammaTools/interface/ConversionTools.h" #include "DataFormats/EgammaCandidates/interface/Conversion.h" @@ -147,16 +146,16 @@ bool ConversionTools::matchesConversion(const reco::GsfTrackRef &trk, const reco //-------------------------------------------------------------------------------------------------- bool ConversionTools::hasMatchedConversion(const reco::GsfElectron &ele, - const edm::Handle &convCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given electron candidate matches to at least one conversion candidate in the //collection which also passes the selection cuts, optionally match with the closestckf track in //in addition to just the gsf track (enabled in default arguments) - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - if (!matchesConversion(ele, *it, allowCkfMatch)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + for(auto const& it : convCol) { + if (!matchesConversion(ele, it, allowCkfMatch)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; return true; } @@ -167,7 +166,7 @@ bool ConversionTools::hasMatchedConversion(const reco::GsfElectron &ele, //-------------------------------------------------------------------------------------------------- bool ConversionTools::hasMatchedConversion(const reco::TrackRef &trk, - const edm::Handle &convCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given track matches to at least one conversion candidate in the @@ -175,9 +174,9 @@ bool ConversionTools::hasMatchedConversion(const reco::TrackRef &trk, if (trk.isNull()) return false; - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - if (!matchesConversion(trk, *it)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + for(auto const& it : convCol) { + if (!matchesConversion(trk, it)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; return true; } @@ -188,16 +187,16 @@ bool ConversionTools::hasMatchedConversion(const reco::TrackRef &trk, //-------------------------------------------------------------------------------------------------- bool ConversionTools::hasMatchedConversion(const reco::SuperCluster &sc, - const edm::Handle &convCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float dRMax, float dEtaMax, float dPhiMax, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given SuperCluster matches to at least one conversion candidate in the //collection which also passes the selection cuts - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - if (!matchesConversion(sc, *it)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + for(auto const& it : convCol) { + if (!matchesConversion(sc, it)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; return true; } @@ -208,8 +207,8 @@ bool ConversionTools::hasMatchedConversion(const reco::SuperCluster &sc, //-------------------------------------------------------------------------------------------------- -reco::ConversionRef ConversionTools::matchedConversion(const reco::GsfElectron &ele, - const edm::Handle &convCol, +reco::Conversion const* ConversionTools::matchedConversion(const reco::GsfElectron &ele, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given electron candidate matches to at least one conversion candidate in the @@ -218,17 +217,17 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::GsfElectron & //If multiple conversions are found, returned reference corresponds to minimum //conversion radius - ConversionRef match; + reco::Conversion const* match = nullptr; double minRho = 999.; - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - float rho = it->conversionVertex().position().rho(); + for(auto const& it : convCol) { + float rho = it.conversionVertex().position().rho(); if (rho>minRho) continue; - if (!matchesConversion(ele, *it, allowCkfMatch)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + if (!matchesConversion(ele, it, allowCkfMatch)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; minRho = rho; - match = ConversionRef(convCol,it-convCol->begin()); + match = ⁢ } return match; @@ -236,8 +235,8 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::GsfElectron & } //-------------------------------------------------------------------------------------------------- -reco::ConversionRef ConversionTools::matchedConversion(const reco::TrackRef &trk, - const edm::Handle &convCol, +reco::Conversion const* ConversionTools::matchedConversion(const reco::TrackRef &trk, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given track matches to at least one conversion candidate in the @@ -245,19 +244,19 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::TrackRef &trk //If multiple conversions are found, returned reference corresponds to minimum //conversion radius - ConversionRef match; + reco::Conversion const* match = nullptr; if (trk.isNull()) return match; double minRho = 999.; - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - float rho = it->conversionVertex().position().rho(); + for(auto const& it : convCol) { + float rho = it.conversionVertex().position().rho(); if (rho>minRho) continue; - if (!matchesConversion(trk, *it)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + if (!matchesConversion(trk, it)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; minRho = rho; - match = ConversionRef(convCol,it-convCol->begin()); + match = ⁢ } return match; @@ -265,8 +264,8 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::TrackRef &trk } //-------------------------------------------------------------------------------------------------- -reco::ConversionRef ConversionTools::matchedConversion(const reco::SuperCluster &sc, - const edm::Handle &convCol, +reco::Conversion const* ConversionTools::matchedConversion(const reco::SuperCluster &sc, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, float dRMax, float dEtaMax, float dPhiMax, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { @@ -275,17 +274,17 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::SuperCluster //If multiple conversions are found, returned reference corresponds to minimum //conversion radius - ConversionRef match; + reco::Conversion const* match = nullptr; double minRho = 999.; - for (ConversionCollection::const_iterator it = convCol->begin(); it!=convCol->end(); ++it) { - float rho = it->conversionVertex().position().rho(); + for(auto const& it : convCol) { + float rho = it.conversionVertex().position().rho(); if (rho>minRho) continue; - if (!matchesConversion(sc, *it, dRMax,dEtaMax,dPhiMax)) continue; - if (!isGoodConversion(*it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + if (!matchesConversion(sc, it, dRMax,dEtaMax,dPhiMax)) continue; + if (!isGoodConversion(it,beamspot,lxyMin,probMin,nHitsBeforeVtxMax)) continue; minRho = rho; - match = ConversionRef(convCol,it-convCol->begin()); + match = ⁢ } return match; @@ -293,59 +292,39 @@ reco::ConversionRef ConversionTools::matchedConversion(const reco::SuperCluster } //-------------------------------------------------------------------------------------------------- -bool ConversionTools::hasMatchedPromptElectron(const reco::SuperClusterRef &sc, const edm::Handle &eleCol, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) +bool ConversionTools::hasMatchedPromptElectron(const reco::SuperClusterRef &sc, const reco::GsfElectronCollection &eleCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { - //check if a given SuperCluster matches to at least one GsfElectron having zero expected inner hits - //and not matching any conversion in the collection passing the quality cuts - - if (sc.isNull()) return false; - - for (GsfElectronCollection::const_iterator it = eleCol->begin(); it!=eleCol->end(); ++it) { - //match electron to supercluster - if (it->reco::GsfElectron::superCluster()!=sc) continue; - - //check expected inner hits - if (it->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) > 0) continue; - - //check if electron is matching to a conversion - if (hasMatchedConversion(*it,convCol,beamspot,allowCkfMatch,lxyMin,probMin,nHitsBeforeVtxMax)) continue; - - - return true; - } - - return false; - - + return !(matchedPromptElectron(sc, eleCol, convCol, beamspot, + allowCkfMatch, lxyMin, probMin, nHitsBeforeVtxMax) == nullptr); } //-------------------------------------------------------------------------------------------------- -reco::GsfElectronRef ConversionTools::matchedPromptElectron(const reco::SuperClusterRef &sc, const edm::Handle &eleCol, - const edm::Handle &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) +reco::GsfElectron const* ConversionTools::matchedPromptElectron(const reco::SuperClusterRef &sc, const reco::GsfElectronCollection &eleCol, + const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch, float lxyMin, float probMin, unsigned int nHitsBeforeVtxMax) { //check if a given SuperCluster matches to at least one GsfElectron having zero expected inner hits //and not matching any conversion in the collection passing the quality cuts - GsfElectronRef match; + reco::GsfElectron const* match = nullptr; if (sc.isNull()) return match; - for (GsfElectronCollection::const_iterator it = eleCol->begin(); it!=eleCol->end(); ++it) { + for(auto const& it : eleCol) { //match electron to supercluster - if (it->reco::GsfElectron::superCluster()!=sc) continue; + if (it.superCluster()!=sc) continue; //check expected inner hits - if (it->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) > 0) continue; + if (it.gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) > 0) continue; //check if electron is matching to a conversion - if (hasMatchedConversion(*it,convCol,beamspot,allowCkfMatch,lxyMin,probMin,nHitsBeforeVtxMax)) continue; + if (hasMatchedConversion(it,convCol,beamspot,allowCkfMatch,lxyMin,probMin,nHitsBeforeVtxMax)) continue; - match = GsfElectronRef(eleCol,it-eleCol->begin()); + match = ⁢ } return match; diff --git a/RecoEgamma/EgammaTools/src/EcalRegressionData.cc b/RecoEgamma/EgammaTools/src/EcalRegressionData.cc index 17f2b69a81cf0..b4c6dd339e7a0 100644 --- a/RecoEgamma/EgammaTools/src/EcalRegressionData.cc +++ b/RecoEgamma/EgammaTools/src/EcalRegressionData.cc @@ -1,5 +1,6 @@ #include "RecoEgamma/EgammaTools/interface/EcalRegressionData.h" +#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h" #include "DataFormats/Math/interface/deltaR.h" #include "Geometry/CaloTopology/interface/CaloTopology.h" @@ -55,7 +56,7 @@ void EcalRegressionData::fill(const reco::SuperCluster& superClus, isEB_ = ( seedid.subdetId()==EcalBarrel ); // skip HGCal - if( seedid.det() == DetId::Forward ) return; + if( EcalTools::isHGCalDet(seedid.det()) ) return; const EcalRecHitCollection* recHits = isEB_ ? ebRecHits : eeRecHits; diff --git a/RecoEgamma/EgammaTools/src/EffectiveAreas.cc b/RecoEgamma/EgammaTools/src/EffectiveAreas.cc index ea1d8613dbe15..7514f92008498 100644 --- a/RecoEgamma/EgammaTools/src/EffectiveAreas.cc +++ b/RecoEgamma/EgammaTools/src/EffectiveAreas.cc @@ -43,9 +43,6 @@ EffectiveAreas::EffectiveAreas(const std::string& filename): checkConsistency(); } -EffectiveAreas::~EffectiveAreas(){ -} - // Return effective area for given eta const float EffectiveAreas::getEffectiveArea(float eta) const{ diff --git a/RecoEgamma/EgammaTools/src/EnergyScaleCorrection.cc b/RecoEgamma/EgammaTools/src/EnergyScaleCorrection.cc index e884a0014a552..dd41135e5e4a7 100644 --- a/RecoEgamma/EgammaTools/src/EnergyScaleCorrection.cc +++ b/RecoEgamma/EgammaTools/src/EnergyScaleCorrection.cc @@ -362,7 +362,6 @@ EnergyScaleCorrection::CorrectionCategory::CorrectionCategory(const std::string& }; // R9 region p1 = category.find("-R9"); - p2 = p1 + 1; if(p1 != std::string::npos) { p1 = category.find("_", p1); p2 = category.find("_", p1 + 1); diff --git a/RecoEgamma/EgammaTools/src/GBRForestTools.cc b/RecoEgamma/EgammaTools/src/GBRForestTools.cc deleted file mode 100644 index cdcd42646924a..0000000000000 --- a/RecoEgamma/EgammaTools/src/GBRForestTools.cc +++ /dev/null @@ -1,151 +0,0 @@ -#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" - -#include -#include - -namespace { - - // Will return position of n-th occurence of a char in a string. - int strpos(const std::string &haystack, char needle, unsigned int nth) - { - int found = 0; - for (unsigned int i=0 ; i GBRForestTools::createGBRForest(const std::string &weightFile, - std::vector &varNames){ - edm::FileInPath weightFileEdm(weightFile); - return GBRForestTools::createGBRForest(weightFileEdm, varNames); -} - -// Creates a pointer to new GBRForest corresponding to a TMVA weights file -std::unique_ptr GBRForestTools::createGBRForest(const edm::FileInPath &weightFile, - std::vector &varNames){ - - std::string method; - - unsigned int NVar = 0; - unsigned int NSpec = 0; - - std::vector dumbVars; - std::vector dumbSpecs; - - varNames.clear(); - std::vector specNames; - - std::string line; - std::ifstream f; - std::string tmpstr; - - bool gzipped = false; - - // - // Set up the input buffers, for gzipped or raw xml file - // - if (reco::details::hasEnding(weightFile.fullPath(), ".xml")) { - f.open(weightFile.fullPath()); - tmpstr = ""; - } else if (reco::details::hasEnding(weightFile.fullPath(), ".gz") || reco::details::hasEnding(weightFile.fullPath(), ".gzip")) { - gzipped = true; - char *buffer = reco::details::readGzipFile(weightFile.fullPath()); - tmpstr = std::string(buffer); - free(buffer); - } - std::stringstream is(tmpstr); - - bool isend; - - while(true) { - - if (gzipped) isend = !std::getline(is, line); - else isend = !std::getline(f, line); - - if (isend) break; - - // Terminate reading of weights file - if (line.find("AddVariable(varNames[i], &dumbVars[i]); - } - - for(size_t i = 0; i < NSpec; ++i){ - mvaReader->AddSpectator(specNames[i], &dumbSpecs[i]); - } - - // - // Book the method and set up the weights file - // - - reco::details::loadTMVAWeights(mvaReader, method, weightFile.fullPath()); - - TMVA::MethodBDT* bdt = dynamic_cast( mvaReader->FindMVA(method) ); - std::unique_ptr gbrForest = std::make_unique(GBRForest(bdt)); - delete mvaReader; - - return gbrForest; -} - -std::unique_ptr GBRForestTools::createGBRForest(const std::string &weightFile){ - std::vector varNames; - return GBRForestTools::createGBRForest(weightFile, varNames); -} - -std::unique_ptr GBRForestTools::createGBRForest(const edm::FileInPath &weightFile){ - std::vector varNames; - return GBRForestTools::createGBRForest(weightFile, varNames); -} diff --git a/RecoEgamma/EgammaTools/src/MVAObjectCache.cc b/RecoEgamma/EgammaTools/src/MVAObjectCache.cc deleted file mode 100644 index e86cb5a67609e..0000000000000 --- a/RecoEgamma/EgammaTools/src/MVAObjectCache.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "RecoEgamma/EgammaTools/interface/MVAObjectCache.h" - -using namespace egamma; - -MVAObjectCache::MVAObjectCache(const edm::ParameterSet& conf) { - const std::vector& mvaEstimatorConfigs - = conf.getParameterSetVector("mvaConfigurations"); - - for( auto &imva : mvaEstimatorConfigs ){ - // building the mva class is now done in the ObjectCache, - // so we loop over what's in that. - std::unique_ptr thisEstimator; - thisEstimator.reset(nullptr); - if( !imva.empty() ) { - const std::string& pName = imva.getParameter("mvaName"); - // The factory below constructs the MVA of the appropriate type based - // on the "mvaName" which is the name of the derived MVA class (plugin) - const AnyMVAEstimatorRun2Base *estimator = AnyMVAEstimatorRun2Factory::get()->create( pName, imva ); - // Declare all event content, such as ValueMaps produced upstream or other, - // original event data pieces, that is needed (if any is implemented in the specific - // MVA classes) - const std::string full_name = estimator->getName() + estimator->getTag(); - auto diditwork = mvas_.emplace( full_name, MVAPtr(estimator) ); - if( !diditwork.second ) { - throw cms::Exception("MVA configured twice: ") - << "Tried already to make an mva of name: " << estimator->getName() - << " please ensure that the name of the MVA is unique!" << std::endl; - } - } else { - throw cms::Exception(" MVA configuration not found: ") - << " failed to find proper configuration for " - <<"one of the MVAs in the main python script " << std::endl; - } - } -} - -const MVAObjectCache::MVAPtr& -MVAObjectCache::getMVA(const std::string& mva) const { - auto itr = mvas_.find(mva); - if( itr == mvas_.end() ) { - throw cms::Exception("InvalidMVAName") - << mva << " is not managed by this evaluator!"; - } - return itr->second; -} diff --git a/RecoEgamma/EgammaTools/src/MVAVariableHelper.cc b/RecoEgamma/EgammaTools/src/MVAVariableHelper.cc new file mode 100644 index 0000000000000..5b2ccfca376ae --- /dev/null +++ b/RecoEgamma/EgammaTools/src/MVAVariableHelper.cc @@ -0,0 +1,108 @@ +#include "RecoEgamma/EgammaTools/interface/MVAVariableHelper.h" + +///////////// +// Specializations for the Electrons +///////////// + +#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" +#include "DataFormats/EgammaCandidates/interface/Conversion.h" +#include "RecoEgamma/EgammaTools/interface/ConversionTools.h" +#include "RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h" + +template<> +MVAVariableHelper::MVAVariableHelper(edm::ConsumesCollector && cc) + : tokens_({ + cc.consumes(edm::InputTag("allConversions")), + cc.consumes(edm::InputTag("reducedEgamma:reducedConversions")), + cc.consumes(edm::InputTag("offlineBeamSpot")), + cc.consumes(edm::InputTag("fixedGridRhoFastjetAll")) + }) +{} + +template<> +const std::vector MVAVariableHelper::getAuxVariables( + edm::Ptr const& particlePtr, const edm::Event& iEvent) const +{ + edm::Handle conversionsHandle; + edm::Handle beamSpotHandle; + edm::Handle rhoHandle; + + iEvent.getByToken(tokens_[0], conversionsHandle); + if( !conversionsHandle.isValid() ) { + iEvent.getByToken(tokens_[1], conversionsHandle); + if( !conversionsHandle.isValid() ) + throw cms::Exception(" Collection not found: ") + << " failed to find a standard AOD or miniAOD conversions collection " << std::endl; + } + + iEvent.getByToken(tokens_[2], beamSpotHandle); + iEvent.getByToken(tokens_[3], rhoHandle); + + return ElectronMVAEstimatorRun2::getExtraVars(*particlePtr, + conversionsHandle.product(), + beamSpotHandle.product(), + *rhoHandle); +} + +template<> +MVAVariableIndexMap::MVAVariableIndexMap() + : indexMap_({ + {"electronMVAVariableHelper:kfhits" , 0}, + {"electronMVAVariableHelper:kfchi2" , 1}, + {"electronMVAVariableHelper:convVtxFitProb", 2}, + {"fixedGridRhoFastjetAll" , 3} + }) +{} + +///////////// +// Specializations for the Photons +///////////// + +#include "DataFormats/EgammaCandidates/interface/Photon.h" + +template<> +MVAVariableHelper::MVAVariableHelper(edm::ConsumesCollector && cc) + : tokens_({ + cc.consumes>(edm::InputTag("photonIDValueMapProducer", "phoPhotonIsolation")), + cc.consumes>(edm::InputTag("photonIDValueMapProducer", "phoChargedIsolation")), + cc.consumes>(edm::InputTag("photonIDValueMapProducer", "phoWorstChargedIsolation")), + cc.consumes>(edm::InputTag("photonIDValueMapProducer", "phoWorstChargedIsolationConeVeto")), + cc.consumes>(edm::InputTag("photonIDValueMapProducer", "phoWorstChargedIsolationConeVetoPVConstr")), + cc.consumes>(edm::InputTag("egmPhotonIsolation", "gamma-DR030-")), + cc.consumes>(edm::InputTag("egmPhotonIsolation", "h+-DR030-")), + cc.consumes(edm::InputTag("fixedGridRhoFastjetAll")), + cc.consumes(edm::InputTag("fixedGridRhoAll")) + }) +{} + +template<> +const std::vector MVAVariableHelper::getAuxVariables( + edm::Ptr const& particlePtr, const edm::Event& iEvent) const +{ + return std::vector { + getVariableFromValueMapToken(particlePtr, tokens_[0], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[1], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[2], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[3], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[4], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[5], iEvent), + getVariableFromValueMapToken(particlePtr, tokens_[6], iEvent), + getVariableFromDoubleToken(tokens_[7], iEvent), + getVariableFromDoubleToken(tokens_[8], iEvent) + }; +} + +template<> +MVAVariableIndexMap::MVAVariableIndexMap() + : indexMap_({ + {"photonIDValueMapProducer:phoPhotonIsolation" , 0}, + {"photonIDValueMapProducer:phoChargedIsolation" , 1}, + {"photonIDValueMapProducer:phoWorstChargedIsolation" , 2}, + {"photonIDValueMapProducer:phoWorstChargedIsolationConeVeto" , 3}, + {"photonIDValueMapProducer:phoWorstChargedIsolationConeVetoPVConstr", 4}, + {"egmPhotonIsolation:gamma-DR030-" , 5}, + {"egmPhotonIsolation:h+-DR030-" , 6}, + {"fixedGridRhoFastjetAll" , 7}, + {"fixedGridRhoAll" , 8} + }) +{} diff --git a/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc b/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc index aaf24dcb139ce..ecec2d51f3df9 100644 --- a/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc +++ b/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc @@ -4,6 +4,7 @@ #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h" #include "DataFormats/EcalDetId/interface/EcalSubdetector.h" #include "DataFormats/VertexReco/interface/Vertex.h" +#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include "FWCore/Utilities/interface/isFinite.h" #include "DataFormats/Math/interface/deltaPhi.h" @@ -103,7 +104,7 @@ std::pair SCEnergyCorrectorSemiParm::getCorrections(const reco:: p.second=-1; // protect against HGCal, don't mod the object - if( sc.seed()->seed().det() == DetId::Forward ) return p; + if( EcalTools::isHGCalDet(sc.seed()->seed().det()) ) return p; const reco::CaloCluster &seedCluster = *(sc.seed()); const bool iseb = seedCluster.hitsAndFractions()[0].first.subdetId() == EcalBarrel; diff --git a/RecoEgamma/EgammaTools/test/PhotonConversionMVACopyToLocalDB_cfg.py b/RecoEgamma/EgammaTools/test/PhotonConversionMVACopyToLocalDB_cfg.py deleted file mode 100644 index 7a73624fed538..0000000000000 --- a/RecoEgamma/EgammaTools/test/PhotonConversionMVACopyToLocalDB_cfg.py +++ /dev/null @@ -1,29 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -process = cms.Process("Demo") - -#process.PhotonConversionMVAComputerSave = cms.ESSource("PhotonConversionMVAComputerSave", -process.PhotonConversionMVAComputerFileSource = cms.ESSource("PhotonConversionMVAComputerFileSource", - label = cms.string('test.mva'), - ) - -process.PoolDBOutputService = cms.Service("PoolDBOutputService", - DBParameters = cms.PSet( messageLevel = cms.untracked.int32(0) ), - BlobStreamerName = cms.untracked.string('TBufferBlobStreamingService'), - timetype = cms.untracked.string('runnumber'), - connect = cms.string('sqlite_file:localconditions.db'), - toPut = cms.VPSet(cms.PSet( - record = cms.string('PhotonConversionMVAComputerRcd'), - tag = cms.string('some_pooldb_tag') - )) - ) - -process.PhotonConversionMVAComputerSave = cms.EDAnalyzer("PhotonConversionMVAComputerSave", - toPut = cms.vstring(), - toCopy = cms.vstring("label") - ) - -process.source = cms.Source("EmptySource") - -process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1)) -process.outpath = cms.EndPath(process.PhotonConversionMVAComputerSave) diff --git a/RecoEgamma/ElectronIdentification/BuildFile.xml b/RecoEgamma/ElectronIdentification/BuildFile.xml index f7589cf2db2d7..289dfc278b9cb 100644 --- a/RecoEgamma/ElectronIdentification/BuildFile.xml +++ b/RecoEgamma/ElectronIdentification/BuildFile.xml @@ -4,6 +4,7 @@ + diff --git a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimator.h b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimator.h index 074cfa7f174f7..207d9f14f7432 100644 --- a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimator.h +++ b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimator.h @@ -13,7 +13,7 @@ class ElectronMVAEstimator { std::vector vweightsfiles; }; ElectronMVAEstimator(); - ElectronMVAEstimator(std::string fileName); + ElectronMVAEstimator(const std::string& fileName); ElectronMVAEstimator(const Configuration & ); ~ElectronMVAEstimator() {;} double mva(const reco::GsfElectron& myElectron, int nvertices=0) const; @@ -22,26 +22,8 @@ class ElectronMVAEstimator { const Configuration cfg_; void bindVariables(float vars[18]) const; - std::vector > gbr; + std::vector > gbr_; - Float_t fbrem; //0 - Float_t detain; //1 - Float_t dphiin; //2 - Float_t sieie; //3 - Float_t hoe; //4 - Float_t eop; //5 - Float_t e1x5e5x5; //6 - Float_t eleopout; //7 - Float_t detaeleout; //8 - Float_t kfchi2; //9 - Float_t mykfhits; //10 - Float_t mymishits; //11 - Float_t absdist; //12 - Float_t absdcot; //13 - Float_t myNvtx; //14 - Float_t eta; //15 - Float_t pt; //16 - Int_t ecalseed; //17 }; #endif diff --git a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h index 620b672f48bcf..43a845a3ee0b1 100644 --- a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h +++ b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h @@ -3,59 +3,77 @@ #include "DataFormats/PatCandidates/interface/Electron.h" #include "RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h" -#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" +#include "CommonTools/MVAUtils/interface/GBRForestTools.h" #include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" +#include "RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h" -class ElectronMVAEstimatorRun2 : public AnyMVAEstimatorRun2Base{ +#include "DataFormats/EgammaCandidates/interface/Conversion.h" +#include "RecoEgamma/EgammaTools/interface/ConversionTools.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +#include + +class ElectronMVAEstimatorRun2 : public AnyMVAEstimatorRun2Base { public: // Constructor and destructor ElectronMVAEstimatorRun2(const edm::ParameterSet& conf); - ~ElectronMVAEstimatorRun2() override; + ~ElectronMVAEstimatorRun2() override {}; // For use with FWLite/Python - ElectronMVAEstimatorRun2(const std::string &mvaTag, - const std::string &mvaName, - const bool debug = false); + ElectronMVAEstimatorRun2(const std::string& mvaTag, + const std::string& mvaName, + int nCategories, + const std::string& variableDefinition, + const std::vector& categoryCutStrings, + const std::vector &weightFileNames, + bool debug=false ); - void init(const std::vector &weightFileNames); + // For use with FWLite/Python + static std::vector getExtraVars(reco::GsfElectron const& ele, + reco::ConversionCollection const* conversions, + reco::BeamSpot const* beamSpot, + double rho) + { + // Conversion vertex fit + reco::Conversion const* conv = ConversionTools::matchedConversion(ele, *conversions, beamSpot->position()); + + float convVtxFitProb = -1.; + if(!(conv == nullptr)) { + const reco::Vertex &vtx = conv->conversionVertex(); + if (vtx.isValid()) { + convVtxFitProb = TMath::Prob( vtx.chi2(), vtx.ndof()); + } + } + + // kf track related variables + bool validKf=false; + reco::TrackRef trackRef = ele.closestCtfTrackRef(); + validKf = trackRef.isAvailable(); + validKf &= trackRef.isNonnull(); + float kfchi2 = validKf ? trackRef->normalizedChi2() : 0 ; //ielectron->track()->normalizedChi2() : 0 ; + float kfhits = validKf ? trackRef->hitPattern().trackerLayersWithMeasurement() : -1. ; + + return std::vector{kfhits, kfchi2, convVtxFitProb, static_cast(rho)}; + } // Calculation of the MVA value - float mvaValue( const edm::Ptr& candPtr, const edm::EventBase& iEvent) const override; - - // Utility functions - int getNCategories() const override { return nCategories_; } - const std::string& getName() const final { return name_; } - const std::string& getTag() const final { return tag_; } + float mvaValue( const reco::Candidate* candidate, std::vector const& auxVariables, int &iCategory) const override; - int findCategory( const edm::Ptr& candPtr) const override; - - // Call this function once after the constructor to declare - // the needed event content pieces to the framework - void setConsumes(edm::ConsumesCollector&&) const final; + int findCategory( const reco::Candidate* candidate) const override; private: - // MVA name. This is a unique name for this MVA implementation. - // It will be used as part of ValueMap names. - // For simplicity, keep it set to the class name. - const std::string name_; + void init(const std::vector &weightFileNames); - // MVA tag. This is an additional string variable to distinguish - // instances of the estimator of this class configured with different - // weight files. - const std::string tag_; + int findCategory(reco::GsfElectron const& electron) const; - // The number of categories and number of variables per category - int nCategories_; - std::vector> categoryFunctions_; + std::vector, reco::GsfElectron>> categoryFunctions_; std::vector nVariables_; // Data members std::vector< std::unique_ptr > gbrForests_; - const std::string methodName_; - // There might be different variables for each category, so the variables // names vector is itself a vector of length nCategories @@ -63,8 +81,6 @@ class ElectronMVAEstimatorRun2 : public AnyMVAEstimatorRun2Base{ MVAVariableManager mvaVarMngr_; - bool debug_; - }; #endif diff --git a/RecoEgamma/ElectronIdentification/interface/ElectronMVAVariableHelper.h b/RecoEgamma/ElectronIdentification/interface/ElectronMVAVariableHelper.h deleted file mode 100644 index ae1895f07c8c7..0000000000000 --- a/RecoEgamma/ElectronIdentification/interface/ElectronMVAVariableHelper.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef ELECTRONMVAVARIABLEHELPER_H -#define ELECTRONMVAVARIABLEHELPER_H - -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/InputTag.h" - -#include "DataFormats/Common/interface/ValueMap.h" -#include "DataFormats/Candidate/interface/CandidateFwd.h" -#include "DataFormats/Candidate/interface/Candidate.h" - -#include "DataFormats/VertexReco/interface/Vertex.h" -#include "DataFormats/VertexReco/interface/VertexFwd.h" - -#include "DataFormats/Math/interface/deltaR.h" - -#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" -#include "DataFormats/PatCandidates/interface/PackedCandidate.h" - -#include "DataFormats/Candidate/interface/CandidateFwd.h" -#include "DataFormats/Candidate/interface/Candidate.h" - -#include "DataFormats/PatCandidates/interface/Electron.h" - -#include "DataFormats/EgammaCandidates/interface/Conversion.h" -#include "RecoEgamma/EgammaTools/interface/ConversionTools.h" - -#include - -typedef edm::View CandView; - -template -class ElectronMVAVariableHelper : public edm::stream::EDProducer<> { - public: - - explicit ElectronMVAVariableHelper(const edm::ParameterSet & iConfig); - ~ElectronMVAVariableHelper() override ; - - void produce(edm::Event & iEvent, const edm::EventSetup & iSetup) override; - -private: - template - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - // for AOD case - const edm::EDGetTokenT > electronsToken_; - const edm::EDGetTokenT vtxToken_; - const edm::EDGetTokenT conversionsToken_; - const edm::EDGetTokenT beamSpotToken_; - - // for miniAOD case - const edm::EDGetTokenT > electronsTokenMiniAOD_; - const edm::EDGetTokenT vtxTokenMiniAOD_; - const edm::EDGetTokenT conversionsTokenMiniAOD_; - const edm::EDGetTokenT beamSpotTokenMiniAOD_; -}; - -template -ElectronMVAVariableHelper::ElectronMVAVariableHelper(const edm::ParameterSet & iConfig) : - electronsToken_(consumes >(iConfig.getParameter("src"))), - vtxToken_(consumes(iConfig.getParameter("vertexCollection"))), - conversionsToken_(consumes(iConfig.getParameter("conversions"))), - beamSpotToken_(consumes(iConfig.getParameter("beamSpot"))), - electronsTokenMiniAOD_(consumes >(iConfig.getParameter("srcMiniAOD"))), - vtxTokenMiniAOD_(consumes(iConfig.getParameter("vertexCollectionMiniAOD"))), - conversionsTokenMiniAOD_(consumes(iConfig.getParameter("conversionsMiniAOD"))), - beamSpotTokenMiniAOD_(consumes(iConfig.getParameter("beamSpotMiniAOD"))) { - - produces>("convVtxFitProb"); - produces>("kfhits"); - produces>("kfchi2"); -} - -template -ElectronMVAVariableHelper::~ElectronMVAVariableHelper() -{} - -template -void ElectronMVAVariableHelper::produce(edm::Event & iEvent, const edm::EventSetup & iSetup) { - - // read input - edm::Handle > electrons; - edm::Handle vtxH; - edm::Handle conversions; - edm::Handle beamSpotHandle; - - bool isAOD = true; - // Retrieve the collection of particles from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - iEvent.getByToken(electronsToken_, electrons); - if( !electrons.isValid() ){ - isAOD = false; - iEvent.getByToken(electronsTokenMiniAOD_,electrons); - if( !electrons.isValid() ) - throw cms::Exception(" Collection not found: ") << " failed to find a standard AOD or miniAOD particle collection " << std::endl; - } - - if (isAOD) { - iEvent.getByToken(vtxToken_, vtxH); - iEvent.getByToken(conversionsToken_, conversions); - iEvent.getByToken(beamSpotToken_, beamSpotHandle); - } else { - iEvent.getByToken(vtxTokenMiniAOD_, vtxH); - iEvent.getByToken(conversionsTokenMiniAOD_, conversions); - iEvent.getByToken(beamSpotTokenMiniAOD_, beamSpotHandle); - } - - // Make sure everything is retrieved successfully - if(! (beamSpotHandle.isValid() && conversions.isValid() && vtxH.isValid() ) ) { - throw cms::Exception("MVA failure: ") - << "Failed to retrieve event content needed for this MVA" - << std::endl - << "Check python MVA configuration file." - << std::endl; - } - - const reco::VertexRef vtx(vtxH, 0); - const reco::BeamSpot* beamSpot = &*(beamSpotHandle.product()); - - // prepare vector for output - std::vector convVtxFitProbVals; - std::vector kfhitsVals; - std::vector kfchi2Vals; - - for (size_t i = 0; i < electrons->size(); ++i){ - auto iCand = electrons->ptrAt(i); - - // Conversion vertex fit - reco::ConversionRef convRef = ConversionTools::matchedConversion(*iCand, conversions, beamSpot->position()); - - float convVtxFitProb = -1.; - if(!convRef.isNull()) { - const reco::Vertex &vtx = convRef.get()->conversionVertex(); - if (vtx.isValid()) { - convVtxFitProb = TMath::Prob( vtx.chi2(), vtx.ndof()); - } - } - - convVtxFitProbVals.push_back(convVtxFitProb); - - // kf track related variables - bool validKf=false; - reco::TrackRef trackRef = iCand->closestCtfTrackRef(); - validKf = trackRef.isAvailable(); - validKf &= trackRef.isNonnull(); - float kfchi2 = validKf ? trackRef->normalizedChi2() : 0 ; //ielectron->track()->normalizedChi2() : 0 ; - float kfhits = validKf ? trackRef->hitPattern().trackerLayersWithMeasurement() : -1. ; - - kfchi2Vals.push_back(kfchi2); - kfhitsVals.push_back(kfhits); - - } - - - // convert into ValueMap and store - writeValueMap(iEvent, electrons, kfchi2Vals, "kfchi2" ); - writeValueMap(iEvent, electrons, kfhitsVals, "kfhits" ); - writeValueMap(iEvent, electrons, convVtxFitProbVals, "convVtxFitProb" ); -} - -template template -void ElectronMVAVariableHelper::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - auto valMap = std::make_unique>(); - typename edm::ValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); -} - -#endif diff --git a/RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h b/RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h deleted file mode 100644 index 8b98ca86b9a43..0000000000000 --- a/RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef ElectronNeuralNet_H -#define ElectronNeuralNet_H - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" -#include "RecoEgamma/ElectronIdentification/interface/ElectronIDAlgo.h" - -class ElectronNeuralNet : public ElectronIDAlgo{ - -public: - - ElectronNeuralNet(){}; - - ~ElectronNeuralNet() override{}; - - void setup(const edm::ParameterSet& conf) override {} ; - using ElectronIDAlgo::result; - //the following is a new function not in the base class - double result(const reco::GsfElectron* electron, const edm::Event&); - - private: - -}; - -#endif // ElectronNeuralNet_H diff --git a/RecoEgamma/ElectronIdentification/interface/SoftElectronMVAEstimator.h b/RecoEgamma/ElectronIdentification/interface/SoftElectronMVAEstimator.h index b869130a4eebf..cd18c7ed24043 100644 --- a/RecoEgamma/ElectronIdentification/interface/SoftElectronMVAEstimator.h +++ b/RecoEgamma/ElectronIdentification/interface/SoftElectronMVAEstimator.h @@ -6,8 +6,8 @@ #include "DataFormats/EgammaCandidates/interface/GsfElectron.h" #include "DataFormats/VertexReco/interface/Vertex.h" #include "DataFormats/VertexReco/interface/VertexFwd.h" - #include "CondFormats/EgammaObjects/interface/GBRForest.h" + #include #include @@ -22,49 +22,15 @@ class SoftElectronMVAEstimator { ~SoftElectronMVAEstimator() ; double mva(const reco::GsfElectron& myElectron, const reco::VertexCollection&) const; - UInt_t GetMVABin(int pu,double eta,double pt ) const; + private: void bindVariables(float vars[25]) const ; void init(); private: const Configuration cfg_; - std::array, ExpectedNBins> gbr; + std::vector > gbr_; - Float_t fbrem; - Float_t EtotOvePin; - Float_t EBremOverDeltaP; - Float_t logSigmaEtaEta; - Float_t DeltaEtaTrackEcalSeed; - Float_t kfchi2; - Float_t kfhits; //number of layers - Float_t gsfchi2; - Float_t SigmaPtOverPt; - - - Float_t deta; - Float_t dphi; - Float_t detacalo; - - Float_t see; - Float_t etawidth; - Float_t phiwidth; - Float_t OneMinusE1x5E5x5; - - Float_t HoE; - //Float_t EoP; //Not being used - Float_t eleEoPout; - - Float_t spp; - Float_t R9; - Float_t IoEmIoP; - Float_t PreShowerOverRaw; - - - Float_t eta; - Float_t pt; - - Float_t nPV; }; #endif diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.cc deleted file mode 100644 index 3e46216948f2f..0000000000000 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include "RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h" - -ElectronIDSelectorNeuralNet::ElectronIDSelectorNeuralNet (const edm::ParameterSet& conf, edm::ConsumesCollector & iC) : conf_ (conf) -{ - doNeuralNet_ = conf_.getParameter ("doNeuralNet"); - - if (doNeuralNet_) - neuralNetAlgo_ = new ElectronNeuralNet(); -} - -ElectronIDSelectorNeuralNet::~ElectronIDSelectorNeuralNet () -{ - if (doNeuralNet_) - delete neuralNetAlgo_ ; -} - -void ElectronIDSelectorNeuralNet::newEvent (const edm::Event& e, const edm::EventSetup& es) -{ - if (doNeuralNet_) - neuralNetAlgo_->setup (conf_); -} - -double ElectronIDSelectorNeuralNet::operator () (const reco::GsfElectron & ele, const edm::Event& e, const edm::EventSetup& es) -{ - if (doNeuralNet_) - return static_cast(neuralNetAlgo_->result (& (ele), e) ); - return 0. ; -} diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h b/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h deleted file mode 100644 index 41214ed5bb969..0000000000000 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef ElectronIDSelectorNeuralNet_h -#define ElectronIDSelectorNeuralNet_h - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" -#include "DataFormats/Common/interface/Handle.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" -#include "RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h" - -class ElectronIDSelectorNeuralNet -{ - public: - - explicit ElectronIDSelectorNeuralNet (const edm::ParameterSet& conf, edm::ConsumesCollector && iC) : - ElectronIDSelectorNeuralNet(conf, iC) {} - explicit ElectronIDSelectorNeuralNet (const edm::ParameterSet& conf, edm::ConsumesCollector & iC) ; - virtual ~ElectronIDSelectorNeuralNet () ; - - void newEvent (const edm::Event&, const edm::EventSetup&) ; - double operator() (const reco::GsfElectron&, const edm::Event&, const edm::EventSetup&) ; - - private: - - ElectronNeuralNet* neuralNetAlgo_; - - edm::ParameterSet conf_; - - bool doNeuralNet_; - -}; - -#endif diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronIDValueMapProducer.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronIDValueMapProducer.cc index 0fe74452d009b..12f8155222841 100644 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronIDValueMapProducer.cc +++ b/RecoEgamma/ElectronIdentification/plugins/ElectronIDValueMapProducer.cc @@ -1,195 +1,118 @@ -#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 "DataFormats/Common/interface/ValueMap.h" #include "DataFormats/Common/interface/View.h" - #include "DataFormats/EgammaCandidates/interface/GsfElectron.h" #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h" - #include "DataFormats/PatCandidates/interface/Electron.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" +#include "RecoEgamma/EgammaTools/interface/MultiToken.h" +#include "RecoEgamma/EgammaTools/interface/Utils.h" +#include "FWCore/Utilities/interface/isFinite.h" -#include #include -class ElectronIDValueMapProducer : public edm::stream::EDProducer<> { +class ElectronIDValueMapProducer : public edm::global::EDProducer<> { public: - + explicit ElectronIDValueMapProducer(const edm::ParameterSet&); - ~ElectronIDValueMapProducer() override; - + ~ElectronIDValueMapProducer() override {} + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - + private: - - void produce(edm::Event&, const edm::EventSetup&) override; - - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - noZS::EcalClusterLazyTools *lazyToolnoZS; - - // for AOD case - edm::EDGetTokenT ebReducedRecHitCollection_; - edm::EDGetTokenT eeReducedRecHitCollection_; - edm::EDGetTokenT esReducedRecHitCollection_; - edm::EDGetToken src_; - - // for miniAOD case - edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; - edm::EDGetToken srcMiniAOD_; - - constexpr static char eleFull5x5SigmaIEtaIEta_[] = "eleFull5x5SigmaIEtaIEta"; - constexpr static char eleFull5x5SigmaIEtaIPhi_[] = "eleFull5x5SigmaIEtaIPhi"; - constexpr static char eleFull5x5E1x5_[] = "eleFull5x5E1x5"; - constexpr static char eleFull5x5E2x5_[] = "eleFull5x5E2x5"; - constexpr static char eleFull5x5E5x5_[] = "eleFull5x5E5x5"; - constexpr static char eleFull5x5R9_[] = "eleFull5x5R9"; - constexpr static char eleFull5x5Circularity_[] = "eleFull5x5Circularity"; -}; -constexpr char ElectronIDValueMapProducer::eleFull5x5SigmaIEtaIEta_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5SigmaIEtaIPhi_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5E1x5_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5E2x5_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5E5x5_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5R9_[]; -constexpr char ElectronIDValueMapProducer::eleFull5x5Circularity_[]; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // for AOD and MiniAOD case + const MultiTokenT> src_; + const MultiTokenT ebRecHits_; + const MultiTokenT eeRecHits_; + const MultiTokenT esRecHits_; -ElectronIDValueMapProducer::ElectronIDValueMapProducer(const edm::ParameterSet& iConfig) { +}; - // +ElectronIDValueMapProducer::ElectronIDValueMapProducer(const edm::ParameterSet& iConfig) // Declare consummables, handle both AOD and miniAOD case - // - ebReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollection")); - ebReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollectionMiniAOD")); - - eeReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollection")); - eeReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollectionMiniAOD")); - - esReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollection")); - esReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollectionMiniAOD")); - - src_ = mayConsume >(iConfig.getParameter("src")); - srcMiniAOD_ = mayConsume >(iConfig.getParameter("srcMiniAOD")); - - produces >(eleFull5x5SigmaIEtaIEta_); - produces >(eleFull5x5SigmaIEtaIPhi_); - produces >(eleFull5x5E1x5_); - produces >(eleFull5x5E2x5_); - produces >(eleFull5x5E5x5_); - produces >(eleFull5x5R9_); - produces >(eleFull5x5Circularity_); + : src_ ( consumesCollector(), iConfig, "src", "srcMiniAOD") + , ebRecHits_(src_, consumesCollector(), iConfig, "ebReducedRecHitCollection", "ebReducedRecHitCollectionMiniAOD") + , eeRecHits_(src_, consumesCollector(), iConfig, "eeReducedRecHitCollection", "eeReducedRecHitCollectionMiniAOD") + , esRecHits_(src_, consumesCollector(), iConfig, "esReducedRecHitCollection", "esReducedRecHitCollectionMiniAOD") +{ -} + produces >("eleFull5x5SigmaIEtaIEta"); + produces >("eleFull5x5SigmaIEtaIPhi"); + produces >("eleFull5x5E1x5" ); + produces >("eleFull5x5E2x5" ); + produces >("eleFull5x5E5x5" ); + produces >("eleFull5x5R9" ); + produces >("eleFull5x5Circularity" ); -ElectronIDValueMapProducer::~ElectronIDValueMapProducer() { } -void ElectronIDValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - - using namespace edm; - - edm::Handle > src; +void ElectronIDValueMapProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const +{ + // Get handle on electrons + auto src = src_.getValidHandle(iEvent); - // Retrieve the collection of electrons from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - bool isAOD = true; - iEvent.getByToken(src_, src); + noZS::EcalClusterLazyTools lazyToolnoZS(iEvent, iSetup, + ebRecHits_.get(iEvent), + eeRecHits_.get(iEvent), + esRecHits_.get(iEvent)); - if( !src.isValid() ){ - isAOD = false; - iEvent.getByToken(srcMiniAOD_,src); - } - - if( isAOD ) - lazyToolnoZS = new noZS::EcalClusterLazyTools(iEvent, iSetup, - ebReducedRecHitCollection_, - eeReducedRecHitCollection_, - esReducedRecHitCollection_ ); - else - lazyToolnoZS = new noZS::EcalClusterLazyTools(iEvent, iSetup, - ebReducedRecHitCollectionMiniAOD_, - eeReducedRecHitCollectionMiniAOD_, - esReducedRecHitCollectionMiniAOD_ ); - // size_t n = src->size(); std::vector eleFull5x5SigmaIEtaIEta, eleFull5x5SigmaIEtaIPhi; std::vector eleFull5x5R9, eleFull5x5Circularity; std::vector eleFull5x5E1x5,eleFull5x5E2x5,eleFull5x5E5x5; - + // reco::GsfElectron::superCluster() is virtual so we can exploit polymorphism - for (size_t i = 0; i < src->size(); ++i){ - auto iEle = src->ptrAt(i); - const auto& theseed = *(iEle->superCluster()->seed()); + for (const auto &ele : *src) { + const auto& theseed = *(ele.superCluster()->seed()); - std::vector vCov = lazyToolnoZS->localCovariances( theseed ); - const float see = (isnan(vCov[0]) ? 0. : sqrt(vCov[0])); + std::vector vCov = lazyToolnoZS.localCovariances( theseed ); + const float see = (edm::isNotFinite(vCov[0]) ? 0. : sqrt(vCov[0])); const float sep = vCov[1]; eleFull5x5SigmaIEtaIEta.push_back(see); eleFull5x5SigmaIEtaIPhi.push_back(sep); - eleFull5x5R9.push_back(lazyToolnoZS->e3x3( theseed ) / iEle->superCluster()->rawEnergy() ); - - const float e1x5 = lazyToolnoZS->e1x5( theseed ); - const float e2x5 = lazyToolnoZS->e2x5Max( theseed ); - const float e5x5 = lazyToolnoZS->e5x5( theseed ); + eleFull5x5R9.push_back(lazyToolnoZS.e3x3( theseed ) / ele.superCluster()->rawEnergy() ); + + const float e1x5 = lazyToolnoZS.e1x5( theseed ); + const float e2x5 = lazyToolnoZS.e2x5Max( theseed ); + const float e5x5 = lazyToolnoZS.e5x5( theseed ); const float circularity = (e5x5 != 0.) ? 1.-e1x5/e5x5 : -1; - - eleFull5x5E1x5.push_back(e1x5); + + eleFull5x5E1x5.push_back(e1x5); eleFull5x5E2x5.push_back(e2x5); eleFull5x5E5x5.push_back(e5x5); eleFull5x5Circularity.push_back(circularity); } - - writeValueMap(iEvent, src, eleFull5x5SigmaIEtaIEta, eleFull5x5SigmaIEtaIEta_); - writeValueMap(iEvent, src, eleFull5x5SigmaIEtaIPhi, eleFull5x5SigmaIEtaIPhi_); - writeValueMap(iEvent, src, eleFull5x5R9, eleFull5x5R9_); - writeValueMap(iEvent, src, eleFull5x5E1x5, eleFull5x5E1x5_); - writeValueMap(iEvent, src, eleFull5x5E2x5, eleFull5x5E2x5_); - writeValueMap(iEvent, src, eleFull5x5E5x5, eleFull5x5E5x5_); - writeValueMap(iEvent, src, eleFull5x5Circularity, eleFull5x5Circularity_); - - delete lazyToolnoZS; -} -void ElectronIDValueMapProducer::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - using namespace edm; - using namespace std; - auto valMap = std::make_unique>(); - edm::ValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); + writeValueMap(iEvent, src, eleFull5x5SigmaIEtaIEta, "eleFull5x5SigmaIEtaIEta"); + writeValueMap(iEvent, src, eleFull5x5SigmaIEtaIPhi, "eleFull5x5SigmaIEtaIPhi"); + writeValueMap(iEvent, src, eleFull5x5R9, "eleFull5x5R9"); + writeValueMap(iEvent, src, eleFull5x5E1x5, "eleFull5x5E1x5"); + writeValueMap(iEvent, src, eleFull5x5E2x5, "eleFull5x5E2x5"); + writeValueMap(iEvent, src, eleFull5x5E5x5, "eleFull5x5E5x5"); + writeValueMap(iEvent, src, eleFull5x5Circularity, "eleFull5x5Circularity"); } void ElectronIDValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters + // electronIDValueMapProducer edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); + desc.add("src", edm::InputTag("gedGsfElectrons")); + desc.add("srcMiniAOD", edm::InputTag("slimmedElectrons","","@skipCurrentProcess")); + desc.add("ebReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEB")); + desc.add("eeReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEE")); + desc.add("esReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsES")); + desc.add("ebReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEBRecHits")); + desc.add("eeReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEERecHits")); + desc.add("esReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedESRecHits")); + descriptions.add("electronIDValueMapProducer", desc); } + DEFINE_FWK_MODULE(ElectronIDValueMapProducer); diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronIdMVABased.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronIdMVABased.cc index abae473926eb7..d256dcda6a2e7 100644 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronIdMVABased.cc +++ b/RecoEgamma/ElectronIdentification/plugins/ElectronIdMVABased.cc @@ -1,15 +1,4 @@ -// -*- C++ -*- // -// Package: ElectronIdMVABased -// Class: ElectronIdMVABased -// -/**\class ElectronIdMVABased ElectronIdMVABased.cc MyAnalyzer/ElectronIdMVABased/src/ElectronIdMVABased.cc - - Description: [one line class summary] - - Implementation: - [Notes on implementation] -*/ // // Original Author: Zablocki Jakub // Created: Thu Feb 9 10:47:50 CST 2012 @@ -22,7 +11,7 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -37,104 +26,58 @@ // class declaration // -using namespace std; -using namespace reco; - -namespace gsfidhelper { - class HeavyObjectCache { - public: - HeavyObjectCache(const edm::ParameterSet& config) { - std::vector mvaWeightFileEleID = - config.getParameter >("HZZmvaWeightFile"); - ElectronMVAEstimator::Configuration cfg; - cfg.vweightsfiles = mvaWeightFileEleID; - mvaID_.reset( new ElectronMVAEstimator(cfg) ); - } - std::unique_ptr mvaID_; - }; -} - -class ElectronIdMVABased : public edm::stream::EDProducer< edm::GlobalCache > { +class ElectronIdMVABased : public edm::global::EDProducer<> { public: - explicit ElectronIdMVABased(const edm::ParameterSet&, const gsfidhelper::HeavyObjectCache*); - ~ElectronIdMVABased() override; - - - static std::unique_ptr - initializeGlobalCache( const edm::ParameterSet& conf ) { - return std::make_unique(conf); - } - - static void globalEndJob(gsfidhelper::HeavyObjectCache const* ) { - } - + explicit ElectronIdMVABased(const edm::ParameterSet&); + ~ElectronIdMVABased() override {} + private: - void produce(edm::Event&, const edm::EventSetup&) override; - - + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + // ----------member data --------------------------- - edm::EDGetTokenT vertexToken; - edm::EDGetTokenT electronToken; - std::vector mvaWeightFileEleID; - string path_mvaWeightFileEleID; - double thresholdBarrel; - double thresholdEndcap; - double thresholdIsoBarrel; - double thresholdIsoEndcap; + const edm::EDGetTokenT vertexToken; + const edm::EDGetTokenT electronToken; + const std::vector mvaWeightFileEleID; + const std::string path_mvaWeightFileEleID; + const double thresholdBarrel; + const double thresholdEndcap; + const double thresholdIsoBarrel; + const double thresholdIsoEndcap; + + const std::unique_ptr mvaID_; }; -// -// constants, enums and typedefs -// - -// -// static data member definitions -// - -// -// constructors and destructor -// -ElectronIdMVABased::ElectronIdMVABased(const edm::ParameterSet& iConfig, const gsfidhelper::HeavyObjectCache*) { - vertexToken = consumes(iConfig.getParameter("vertexTag")); - electronToken = consumes(iConfig.getParameter("electronTag")); - thresholdBarrel = iConfig.getParameter("thresholdBarrel"); - thresholdEndcap = iConfig.getParameter("thresholdEndcap"); - thresholdIsoBarrel = iConfig.getParameter("thresholdIsoDR03Barrel"); - thresholdIsoEndcap = iConfig.getParameter("thresholdIsoDR03Endcap"); - - produces(); -} - - -ElectronIdMVABased::~ElectronIdMVABased() +// constructor +ElectronIdMVABased::ElectronIdMVABased(const edm::ParameterSet& iConfig) + : vertexToken(consumes(iConfig.getParameter("vertexTag"))) + , electronToken(consumes(iConfig.getParameter("electronTag"))) + , thresholdBarrel (iConfig.getParameter("thresholdBarrel")) + , thresholdEndcap (iConfig.getParameter("thresholdEndcap")) + , thresholdIsoBarrel(iConfig.getParameter("thresholdIsoDR03Barrel")) + , thresholdIsoEndcap(iConfig.getParameter("thresholdIsoDR03Endcap")) + , mvaID_(new ElectronMVAEstimator(ElectronMVAEstimator::Configuration{ + .vweightsfiles = iConfig.getParameter >("HZZmvaWeightFile")})) { - // do anything here that needs to be done at desctruction time - // (e.g. close files, deallocate resources etc.) - + produces(); } - -// -// member functions -// - // ------------ method called on each new Event ------------ -void ElectronIdMVABased::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - using namespace edm; +void ElectronIdMVABased::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const +{ constexpr double etaEBEE = 1.485; - + auto mvaElectrons = std::make_unique(); - - Handle vertexCollection; + + edm::Handle vertexCollection; iEvent.getByToken(vertexToken, vertexCollection); int nVtx = vertexCollection->size(); - - Handle egCollection; + + edm::Handle egCollection; iEvent.getByToken(electronToken,egCollection); const reco::GsfElectronCollection egCandidates = (*egCollection.product()); for ( reco::GsfElectronCollection::const_iterator egIter = egCandidates.begin(); egIter != egCandidates.end(); ++egIter) { - double mvaVal = globalCache()->mvaID_->mva( *egIter, nVtx ); + double mvaVal = mvaID_->mva( *egIter, nVtx ); double isoDr03 = egIter->dr03TkSumPt() + egIter->dr03EcalRecHitSumEt() + egIter->dr03HcalTowerSumEt(); double eleEta = fabs(egIter->eta()); if (eleEta <= etaEBEE && mvaVal > thresholdBarrel && isoDr03 < thresholdIsoBarrel) { @@ -150,9 +93,9 @@ void ElectronIdMVABased::produce(edm::Event& iEvent, const edm::EventSetup& iSet mvaElectrons->back().setMvaOutput(myMvaOutput); } } - + iEvent.put(std::move(mvaElectrons)); - + } //define this as a plug-in diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronMVANtuplizer.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronMVANtuplizer.cc index ed14caae188b5..2e2e99d963ab2 100644 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronMVANtuplizer.cc +++ b/RecoEgamma/ElectronIdentification/plugins/ElectronMVANtuplizer.cc @@ -20,20 +20,20 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/one/EDAnalyzer.h" - #include "FWCore/Framework/interface/Event.h" - #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/InputTag.h" - #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/Framework/interface/MakerMacros.h" + #include "CommonTools/UtilAlgos/interface/TFileService.h" #include "DataFormats/EgammaCandidates/interface/GsfElectron.h" #include "DataFormats/PatCandidates/interface/Electron.h" #include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" +#include "RecoEgamma/EgammaTools/interface/MultiToken.h" + #include "SimDataFormats/PileupSummaryInfo/interface/PileupSummaryInfo.h" #include "DataFormats/VertexReco/interface/Vertex.h" @@ -62,36 +62,18 @@ class ElectronMVANtuplizer : public edm::one::EDAnalyzer int matchToTruth(const T &el, const V &genParticles, int &genIdx); // ----------member data --------------------------- - // for AOD case - const edm::EDGetToken src_; - const edm::EDGetToken vertices_; - const edm::EDGetToken pileup_; - const edm::EDGetToken genParticles_; - - // for miniAOD case - const edm::EDGetToken srcMiniAOD_; - const edm::EDGetToken verticesMiniAOD_; - const edm::EDGetToken pileupMiniAOD_; - const edm::EDGetToken genParticlesMiniAOD_; - - // other - TTree* tree_; - - MVAVariableManager mvaVarMngr_; - std::vector vars_; - int nVars_; - //global variables int nEvent_, nRun_, nLumi_; int genNpu_; @@ -113,10 +95,7 @@ class ElectronMVANtuplizer : public edm::one::EDAnalyzer mvaPasses_; - std::vector mvaValues_; - std::vector mvaCats_; + int eleIndex_; // config const bool isMC_; @@ -139,6 +118,28 @@ class ElectronMVANtuplizer : public edm::one::EDAnalyzer > > mvaCatTokens_; const std::vector< std::string > mvaCatBranchNames_; const size_t nCats_; + + // Tokens for AOD and MiniAOD case + const MultiTokenT> src_; + const MultiTokenT> vertices_; + const MultiTokenT> pileup_; + const MultiTokenT> genParticles_; + + // to hold ID decisions and categories + std::vector mvaPasses_; + std::vector mvaValues_; + std::vector mvaCats_; + + // To get the auxiliary MVA variables + const MVAVariableHelper variableHelper_; + + // other + TTree* tree_; + + MVAVariableManager mvaVarMngr_; + const int nVars_; + std::vector vars_; + }; // @@ -160,52 +161,41 @@ enum ElectronMatchType { // constructors and destructor // ElectronMVANtuplizer::ElectronMVANtuplizer(const edm::ParameterSet& iConfig) - : - src_ (consumes >(iConfig.getParameter("src"))), - vertices_ (consumes >(iConfig.getParameter("vertices"))), - pileup_ (consumes >(iConfig.getParameter("pileup"))), - genParticles_ (consumes >(iConfig.getParameter("genParticles"))), - srcMiniAOD_ (consumes >(iConfig.getParameter("srcMiniAOD"))), - verticesMiniAOD_ (consumes >(iConfig.getParameter("verticesMiniAOD"))), - pileupMiniAOD_ (consumes >(iConfig.getParameter("pileupMiniAOD"))), - genParticlesMiniAOD_ (consumes >(iConfig.getParameter("genParticlesMiniAOD"))), - mvaVarMngr_ (iConfig.getParameter("variableDefinition")), - isMC_ (iConfig.getParameter("isMC")), - deltaR_ (iConfig.getParameter("deltaR")), - ptThreshold_ (iConfig.getParameter("ptThreshold")), - eleMapTags_ (iConfig.getUntrackedParameter>("eleMVAs")), - eleMapBranchNames_ (iConfig.getUntrackedParameter>("eleMVALabels")), - nEleMaps_ (eleMapBranchNames_.size()), - valMapTags_ (iConfig.getUntrackedParameter>("eleMVAValMaps")), - valMapBranchNames_ (iConfig.getUntrackedParameter>("eleMVAValMapLabels")), - nValMaps_ (valMapBranchNames_.size()), - mvaCatTags_ (iConfig.getUntrackedParameter>("eleMVACats")), - mvaCatBranchNames_ (iConfig.getUntrackedParameter>("eleMVACatLabels")), - nCats_ (mvaCatBranchNames_.size()) + : isMC_ (iConfig.getParameter("isMC")) + , deltaR_ (iConfig.getParameter("deltaR")) + , ptThreshold_ (iConfig.getParameter("ptThreshold")) + , eleMapTags_ (iConfig.getUntrackedParameter>("eleMVAs")) + , eleMapBranchNames_ (iConfig.getUntrackedParameter>("eleMVALabels")) + , nEleMaps_ (eleMapBranchNames_.size()) + , valMapTags_ (iConfig.getUntrackedParameter>("eleMVAValMaps")) + , valMapBranchNames_ (iConfig.getUntrackedParameter>("eleMVAValMapLabels")) + , nValMaps_ (valMapBranchNames_.size()) + , mvaCatTags_ (iConfig.getUntrackedParameter>("eleMVACats")) + , mvaCatBranchNames_ (iConfig.getUntrackedParameter>("eleMVACatLabels")) + , nCats_ (mvaCatBranchNames_.size()) + , src_ (consumesCollector(), iConfig, "src" , "srcMiniAOD") + , vertices_ (src_, consumesCollector(), iConfig, "vertices" , "verticesMiniAOD") + , pileup_ (src_, consumesCollector(), iConfig, "pileup" , "pileupMiniAOD") + , genParticles_ (src_, consumesCollector(), iConfig, "genParticles", "genParticlesMiniAOD") + , mvaPasses_ (nEleMaps_) + , mvaValues_ (nValMaps_) + , mvaCats_ (nCats_) + , variableHelper_ (consumesCollector()) + , mvaVarMngr_ (iConfig.getParameter("variableDefinition")) + , nVars_ (mvaVarMngr_.getNVars()) + , vars_ (nVars_) { // eleMaps - for (size_t k = 0; k < nEleMaps_; ++k) { - - eleMapTokens_.push_back(consumes >(edm::InputTag(eleMapTags_[k]))); - - // Initialize vectors for holding ID decisions - mvaPasses_.push_back(0); + for (auto const& tag : eleMapTags_) { + eleMapTokens_.push_back(consumes >(edm::InputTag(tag))); } - // valMaps - for (size_t k = 0; k < nValMaps_; ++k) { - valMapTokens_.push_back(consumes >(edm::InputTag(valMapTags_[k]))); - - // Initialize vectors for holding MVA values - mvaValues_.push_back(0.0); + for (auto const& tag : valMapTags_) { + valMapTokens_.push_back(consumes >(edm::InputTag(tag))); } - // categories - for (size_t k = 0; k < nCats_; ++k) { - mvaCatTokens_.push_back(consumes >(edm::InputTag(mvaCatTags_[k]))); - - // Initialize vectors for holding MVA values - mvaCats_.push_back(0); + for (auto const& tag : mvaCatTags_) { + mvaCatTokens_.push_back(consumes >(edm::InputTag(tag))); } // Book tree @@ -213,8 +203,6 @@ ElectronMVANtuplizer::ElectronMVANtuplizer(const edm::ParameterSet& iConfig) edm::Service fs ; tree_ = fs->make("tree","tree"); - nVars_ = mvaVarMngr_.getNVars(); - tree_->Branch("nEvent", &nEvent_); tree_->Branch("nRun", &nRun_); tree_->Branch("nLumi", &nLumi_); @@ -228,10 +216,6 @@ ElectronMVANtuplizer::ElectronMVANtuplizer(const edm::ParameterSet& iConfig) tree_->Branch("matchedToGenEle", &matchedToGenEle_); } - // Has to be in two different loops - for (int i = 0; i < nVars_; ++i) { - vars_.push_back(0.0); - } for (int i = 0; i < nVars_; ++i) { tree_->Branch(mvaVarMngr_.getName(i).c_str(), &vars_[i]); } @@ -244,6 +228,8 @@ ElectronMVANtuplizer::ElectronMVANtuplizer(const edm::ParameterSet& iConfig) tree_->Branch("ele_isEEDeeGap",&eleIsEEDeeGap_); tree_->Branch("ele_isEERingGap",&eleIsEERingGap_); + tree_->Branch("ele_index",&eleIndex_); + // IDs for (size_t k = 0; k < nValMaps_; ++k) { tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]); @@ -256,15 +242,6 @@ ElectronMVANtuplizer::ElectronMVANtuplizer(const edm::ParameterSet& iConfig) for (size_t k = 0; k < nCats_; ++k) { tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]); } - - // All tokens for event content needed by this MVA - // Tags from the variable helper - for (auto &tag : mvaVarMngr_.getHelperInputTags()) { - consumes>(tag); - } - for (auto &tag : mvaVarMngr_.getGlobalInputTags()) { - consumes(tag); - } } @@ -290,31 +267,18 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i nRun_ = iEvent.id().run(); nLumi_ = iEvent.luminosityBlock(); + // Get Handles + auto src = src_.getValidHandle(iEvent); + auto vertices = vertices_.getValidHandle(iEvent); - // Retrieve Vertecies - edm::Handle vertices; - iEvent.getByToken(vertices_, vertices); - if( !vertices.isValid() ){ - iEvent.getByToken(verticesMiniAOD_,vertices); - if( !vertices.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD vertex collection " << std::endl; - } + // Get MC only Handles, which are allowed to be non-valid + auto genParticles = genParticles_.getHandle(iEvent); + auto pileup = pileup_.getHandle(iEvent); vtxN_ = vertices->size(); - // Retrieve Pileup Info + // Fill with true number of pileup if(isMC_) { - edm::Handle > pileup; - iEvent.getByToken(pileup_, pileup); - if( !pileup.isValid() ){ - iEvent.getByToken(pileupMiniAOD_,pileup); - if( !pileup.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD pileup collection " << std::endl; - } - - // Fill with true number of pileup for(const auto& pu : *pileup) { int bx = pu.getBunchCrossing(); @@ -326,32 +290,6 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i } } - // Retrieve genParticles - edm::Handle > genParticles; - if(isMC_) { - iEvent.getByToken(genParticles_, genParticles); - if( !genParticles.isValid() ){ - iEvent.getByToken(genParticlesMiniAOD_, genParticles); - if( !genParticles.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD genParticle collection " << std::endl; - } - } - - - edm::Handle > src; - - // Retrieve the collection of particles from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - iEvent.getByToken(src_, src); - if( !src.isValid() ){ - iEvent.getByToken(srcMiniAOD_,src); - if( !src.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD particle collection " << std::endl; - } - // Get MVA decisions edm::Handle > decisions[nEleMaps_]; for (size_t k = 0; k < nEleMaps_; ++k) { @@ -370,9 +308,10 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i iEvent.getByToken(mvaCatTokens_[k],mvaCats[k]); } - int nEle = src->size(); + eleIndex_ = -1; + for(size_t iEle = 0; iEle < src->size(); ++iEle) { - for(int iEle = 0; iEle < nEle; ++iEle) { + ++eleIndex_; const auto ele = src->ptrAt(iEle); @@ -384,7 +323,8 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i } for (int iVar = 0; iVar < nVars_; ++iVar) { - vars_[iVar] = mvaVarMngr_.getValue(iVar, ele, iEvent); + std::vector extraVariables = variableHelper_.getAuxVariables(ele, iEvent); + vars_[iVar] = mvaVarMngr_.getValue(iVar, *ele, extraVariables); } if (isMC_) { @@ -404,7 +344,7 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i // Look up and save the ID decisions // for (size_t k = 0; k < nEleMaps_; ++k) { - mvaPasses_[k] = (int)(*decisions[k])[ele]; + mvaPasses_[k] = static_cast((*decisions[k])[ele]); } for (size_t k = 0; k < nValMaps_; ++k) { @@ -421,28 +361,10 @@ ElectronMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& i } -void ElectronMVANtuplizer::findFirstNonElectronMother2(const reco::Candidate *particle, - int &ancestorPID, int &ancestorStatus){ - - if( particle == nullptr ){ - edm::LogError ("ElectronNtuplizer") << "ElectronNtuplizer: ERROR! null candidate pointer, this should never happen"; - return; - } - - // Is this the first non-electron parent? If yes, return, otherwise - // go deeper into recursion - if( abs(particle->pdgId()) == 11 ){ - findFirstNonElectronMother2(particle->mother(0), ancestorPID, ancestorStatus); - }else{ - ancestorPID = particle->pdgId(); - ancestorStatus = particle->status(); - } - - return; -} - template -int ElectronMVANtuplizer::matchToTruth(const T &el, const V &prunedGenParticles, int &genIdx){ +int ElectronMVANtuplizer::matchToTruth(const T &el, const V &genParticles, int &genIdx){ + + genIdx = -1; // // Explicit loop and geometric matching method (advised by Josh Bendavid) @@ -450,9 +372,8 @@ int ElectronMVANtuplizer::matchToTruth(const T &el, const V &prunedGenParticles, // Find the closest status 1 gen electron to the reco electron double dR = 999; - const reco::Candidate *closestElectron = nullptr; - for(size_t i=0; isize();i++){ - const reco::Candidate *particle = &(*prunedGenParticles)[i]; + for(size_t i=0; isize();i++){ + const auto particle = genParticles->ptrAt(i); // Drop everything that is not electron or not status 1 if( abs(particle->pdgId()) != 11 || particle->status() != 1 ) continue; @@ -460,73 +381,49 @@ int ElectronMVANtuplizer::matchToTruth(const T &el, const V &prunedGenParticles, double dRtmp = ROOT::Math::VectorUtil::DeltaR( el->p4(), particle->p4() ); if( dRtmp < dR ){ dR = dRtmp; - closestElectron = particle; genIdx = i; } } - // See if the closest electron (if it exists) is close enough. - // If not, no match found. - if( !(closestElectron != nullptr && dR < deltaR_) ) { + // See if the closest electron is close enough. If not, no match found. + if( genIdx == -1 || dR >= deltaR_ ) { return UNMATCHED; } - // - int ancestorPID = -999; - int ancestorStatus = -999; - findFirstNonElectronMother2(closestElectron, ancestorPID, ancestorStatus); - - if( ancestorPID == -999 && ancestorStatus == -999 ){ - // No non-electron parent??? This should never happen. - // Complain. - edm::LogError ("ElectronNtuplizer") << "ElectronNtuplizer: ERROR! null candidate pointer, this should never happen"; - return UNMATCHED; - } + const auto closestElectron = genParticles->ptrAt(genIdx); - if( abs(ancestorPID) > 50 && ancestorStatus == 2 ) - return TRUE_NON_PROMPT_ELECTRON; + if( closestElectron->fromHardProcessFinalState() ) + return TRUE_PROMPT_ELECTRON; - if( abs(ancestorPID) == 15 && ancestorStatus == 2 ) + if( closestElectron->isDirectHardProcessTauDecayProductFinalState() ) return TRUE_ELECTRON_FROM_TAU; - // What remains is true prompt electrons - return TRUE_PROMPT_ELECTRON; -} - -// ------------ method called once each job just before starting event loop ------------ -void -ElectronMVANtuplizer::beginJob() -{ -} - -// ------------ method called once each job just after ending the event loop ------------ -void -ElectronMVANtuplizer::endJob() -{ + // What remains is true non-prompt electrons + return TRUE_NON_PROMPT_ELECTRON; } // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void -ElectronMVANtuplizer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - +ElectronMVANtuplizer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) +{ edm::ParameterSetDescription desc; - desc.add("src"); - desc.add("vertices"); - desc.add("pileup"); - desc.add("genParticles"); - desc.add("srcMiniAOD"); - desc.add("verticesMiniAOD"); - desc.add("pileupMiniAOD"); - desc.add("genParticlesMiniAOD"); + desc.add("src", edm::InputTag("gedGsfElectrons")); + desc.add("vertices", edm::InputTag("offlinePrimaryVertices")); + desc.add("pileup", edm::InputTag("addPileupInfo")); + desc.add("genParticles", edm::InputTag("genParticles")); + desc.add("srcMiniAOD", edm::InputTag("slimmedElectrons")); + desc.add("verticesMiniAOD", edm::InputTag("offlineSlimmedPrimaryVertices")); + desc.add("pileupMiniAOD", edm::InputTag("slimmedAddPileupInfo")); + desc.add("genParticlesMiniAOD", edm::InputTag("prunedGenParticles")); desc.add("variableDefinition"); - desc.add("isMC"); + desc.add("isMC", true); desc.add("deltaR", 0.1); desc.add("ptThreshold", 5.0); - desc.addUntracked>("eleMVAs"); - desc.addUntracked>("eleMVALabels"); - desc.addUntracked>("eleMVAValMaps"); - desc.addUntracked>("eleMVAValMapLabels"); - desc.addUntracked>("eleMVACats"); - desc.addUntracked>("eleMVACatLabels"); + desc.addUntracked>("eleMVAs", {}); + desc.addUntracked>("eleMVALabels", {}); + desc.addUntracked>("eleMVAValMaps", {}); + desc.addUntracked>("eleMVAValMapLabels", {}); + desc.addUntracked>("eleMVACats", {}); + desc.addUntracked>("eleMVACatLabels", {}); descriptions.addDefault(desc); } diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronMVAVariableHelper.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronMVAVariableHelper.cc deleted file mode 100644 index 08b23b26c9701..0000000000000 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronMVAVariableHelper.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "RecoEgamma/ElectronIdentification/interface/ElectronMVAVariableHelper.h" - -#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" -#include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h" - -#include "FWCore/Framework/interface/MakerMacros.h" - -typedef ElectronMVAVariableHelper GsfElectronMVAVariableHelper; - -DEFINE_FWK_MODULE(GsfElectronMVAVariableHelper); diff --git a/RecoEgamma/ElectronIdentification/plugins/ElectronRegressionValueMapProducer.cc b/RecoEgamma/ElectronIdentification/plugins/ElectronRegressionValueMapProducer.cc deleted file mode 100644 index aa41f9942b810..0000000000000 --- a/RecoEgamma/ElectronIdentification/plugins/ElectronRegressionValueMapProducer.cc +++ /dev/null @@ -1,244 +0,0 @@ -#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 "DataFormats/Common/interface/ValueMap.h" -#include "DataFormats/Common/interface/View.h" - -#include "DataFormats/EgammaCandidates/interface/GsfElectron.h" -#include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h" - -#include "DataFormats/PatCandidates/interface/Electron.h" -#include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" -#include "RecoEgamma/EgammaTools/interface/EcalClusterLocal.h" - -#include "TVector2.h" - -#include -#include -#include - -namespace { - enum reg_float_vars { k_NFloatVars = 0 }; - - enum reg_int_vars { k_NIntVars = 0 }; - - const std::vector float_var_names( { } ); - - const std::vector integer_var_names( { } ); - - inline void set_map_val( const reg_float_vars index, const float value, - std::unordered_map& map) { - map[float_var_names[index]] = value; - } - inline void set_map_val( const reg_int_vars index, const int value, - std::unordered_map& map) { - map[integer_var_names[index]] = value; - } - - template - inline void check_map(const std::unordered_map& map, unsigned exp_size) { - if( map.size() != exp_size ) { - throw cms::Exception("ElectronRegressionWeirdConfig") - << "variable map size: " << map.size() - << " not equal to expected size: " << exp_size << " !" - << " The regression variable calculation code definitely has a bug, fix it!"; - } - } - - template - void calculateValues(EcalClusterLazyToolsBase* tools_tocast, - const edm::Ptr& iEle, - const edm::EventSetup& iSetup, - std::unordered_map& float_vars, - std::unordered_map& int_vars ) { - } -} - -class ElectronRegressionValueMapProducer : public edm::stream::EDProducer<> { - - public: - - explicit ElectronRegressionValueMapProducer(const edm::ParameterSet&); - ~ElectronRegressionValueMapProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - - private: - - void produce(edm::Event&, const edm::EventSetup&) override; - - template - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - std::unique_ptr lazyTools; - - // for AOD case - edm::EDGetTokenT ebReducedRecHitCollection_; - edm::EDGetTokenT eeReducedRecHitCollection_; - edm::EDGetTokenT esReducedRecHitCollection_; - edm::EDGetToken src_; - - // for miniAOD case - edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; - edm::EDGetToken srcMiniAOD_; - - const bool use_full5x5_; -}; - -ElectronRegressionValueMapProducer::ElectronRegressionValueMapProducer(const edm::ParameterSet& iConfig) : - use_full5x5_(iConfig.getParameter("useFull5x5")) { - - // - // Declare consummables, handle both AOD and miniAOD case - // - ebReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollection")); - ebReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollectionMiniAOD")); - - eeReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollection")); - eeReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollectionMiniAOD")); - - esReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollection")); - esReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollectionMiniAOD")); - - src_ = mayConsume >(iConfig.getParameter("src")); - srcMiniAOD_ = mayConsume >(iConfig.getParameter("srcMiniAOD")); - - for( const std::string& name : float_var_names ) { - produces >(name); - } - - for( const std::string& name : integer_var_names ) { - produces >(name); - } -} - -ElectronRegressionValueMapProducer::~ElectronRegressionValueMapProducer() { -} - -void ElectronRegressionValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - - using namespace edm; - - edm::Handle > src; - - // Retrieve the collection of electrons from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - bool isAOD = true; - iEvent.getByToken(src_, src); - - if( !src.isValid() ) { - isAOD = false; - iEvent.getByToken(srcMiniAOD_,src); - } - - // configure lazy tools - edm::EDGetTokenT ebrh, eerh, esrh; - - if( isAOD ) { - ebrh = ebReducedRecHitCollection_; - eerh = eeReducedRecHitCollection_; - esrh = esReducedRecHitCollection_; - } else { - ebrh = ebReducedRecHitCollectionMiniAOD_; - eerh = eeReducedRecHitCollectionMiniAOD_; - esrh = esReducedRecHitCollectionMiniAOD_; - } - - if( use_full5x5_ ) { - lazyTools = std::make_unique(iEvent, iSetup, - ebrh, eerh, esrh ); - } else { - lazyTools = std::make_unique(iEvent, iSetup, - ebrh, eerh, esrh ); - } - - std::vector > float_vars(k_NFloatVars); - std::vector > int_vars(k_NIntVars); - - std::unordered_map float_vars_map; - std::unordered_map int_vars_map; - - // reco::GsfElectron::superCluster() is virtual so we can exploit polymorphism - for (size_t i = 0; i < src->size(); ++i){ - auto iEle = src->ptrAt(i); - - if( use_full5x5_ ) { - calculateValues(lazyTools.get(), - iEle, - iSetup, - float_vars_map, - int_vars_map); - } else { - calculateValues(lazyTools.get(), - iEle, - iSetup, - float_vars_map, - int_vars_map); - } - - check_map(float_vars_map, k_NFloatVars); - check_map(int_vars_map, k_NIntVars); - - for( unsigned i = 0; i < float_vars.size(); ++i ) { - float_vars[i].emplace_back(float_vars_map.at(float_var_names[i])); - } - - for( unsigned i = 0; i < int_vars.size(); ++i ) { - int_vars[i].emplace_back(int_vars_map.at(integer_var_names[i])); - } - } - - for( unsigned i = 0; i < float_vars.size(); ++i ) { - writeValueMap(iEvent, src, float_vars[i], float_var_names[i]); - } - - for( unsigned i = 0; i < int_vars.size(); ++i ) { - writeValueMap(iEvent, src, int_vars[i], integer_var_names[i]); - } - - lazyTools.reset(); -} - -template -void ElectronRegressionValueMapProducer::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - using namespace edm; - using namespace std; - typedef ValueMap TValueMap; - - auto valMap = std::make_unique(); - typename TValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); -} - -void ElectronRegressionValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); -} - -DEFINE_FWK_MODULE(ElectronRegressionValueMapProducer); diff --git a/RecoEgamma/ElectronIdentification/plugins/SealModule.cc b/RecoEgamma/ElectronIdentification/plugins/SealModule.cc index 9dc394b1b889c..056ef8985e047 100644 --- a/RecoEgamma/ElectronIdentification/plugins/SealModule.cc +++ b/RecoEgamma/ElectronIdentification/plugins/SealModule.cc @@ -11,33 +11,24 @@ #include "RecoEgamma/ElectronIdentification/plugins/ElectronIDSelector.h" #include "RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorCutBased.h" -#include "RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorNeuralNet.h" #include "RecoEgamma/ElectronIdentification/plugins/ElectronIDSelectorLikelihood.h" typedef ElectronIDSelector EleIdCutBasedSel; -typedef ElectronIDSelector EleIdNeuralNetSel; typedef ElectronIDSelector EleIdLikelihoodSel; typedef ObjectSelector< EleIdCutBasedSel, edm::RefVector > EleIdCutBasedRef ; -typedef ObjectSelector< - EleIdNeuralNetSel, - edm::RefVector - > EleIdNeuralNetRef ; typedef ObjectSelector< EleIdLikelihoodSel, edm::RefVector > EleIdLikelihoodRef ; DEFINE_FWK_MODULE(EleIdCutBasedRef); -DEFINE_FWK_MODULE(EleIdNeuralNetRef); DEFINE_FWK_MODULE(EleIdLikelihoodRef); #include "RecoEgamma/ElectronIdentification/plugins/ElectronIDExternalProducer.h" typedef ElectronIDExternalProducer EleIdCutBasedExtProducer; -typedef ElectronIDExternalProducer EleIdNeuralNetExtProducer; typedef ElectronIDExternalProducer EleIdLikelihoodExtProducer; DEFINE_FWK_MODULE(EleIdCutBasedExtProducer); -DEFINE_FWK_MODULE(EleIdNeuralNetExtProducer); DEFINE_FWK_MODULE(EleIdLikelihoodExtProducer); #include "FWCore/Framework/interface/ModuleFactory.h" diff --git a/RecoEgamma/ElectronIdentification/plugins/VersionedGsfElectronIdProducer.cc b/RecoEgamma/ElectronIdentification/plugins/VersionedGsfElectronIdProducer.cc index 4a9d78d9ea671..7cb22123c7b14 100644 --- a/RecoEgamma/ElectronIdentification/plugins/VersionedGsfElectronIdProducer.cc +++ b/RecoEgamma/ElectronIdentification/plugins/VersionedGsfElectronIdProducer.cc @@ -1,21 +1,5 @@ -// system include files -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/Common/interface/View.h" - -#include "PhysicsTools/SelectorUtils/interface/VersionedIdProducer.h" - #include "DataFormats/EgammaCandidates/interface/GsfElectron.h" -#include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h" +#include "PhysicsTools/SelectorUtils/interface/VersionedIdProducer.h" typedef VersionedIdProducer VersionedGsfElectronIdProducer; diff --git a/RecoEgamma/ElectronIdentification/plugins/VersionedPatElectronIdProducer.cc b/RecoEgamma/ElectronIdentification/plugins/VersionedPatElectronIdProducer.cc index fbf3efa880a4d..0284671ed6d53 100644 --- a/RecoEgamma/ElectronIdentification/plugins/VersionedPatElectronIdProducer.cc +++ b/RecoEgamma/ElectronIdentification/plugins/VersionedPatElectronIdProducer.cc @@ -1,20 +1,5 @@ -// system include files -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/Common/interface/View.h" - -#include "PhysicsTools/SelectorUtils/interface/VersionedIdProducer.h" - #include "DataFormats/PatCandidates/interface/Electron.h" +#include "PhysicsTools/SelectorUtils/interface/VersionedIdProducer.h" typedef VersionedIdProducer VersionedPatElectronIdProducer; diff --git a/RecoEgamma/ElectronIdentification/plugins/cuts/GsfEleConversionVetoCut.cc b/RecoEgamma/ElectronIdentification/plugins/cuts/GsfEleConversionVetoCut.cc index 608e33cee4bce..ba8bd7f27af68 100644 --- a/RecoEgamma/ElectronIdentification/plugins/cuts/GsfEleConversionVetoCut.cc +++ b/RecoEgamma/ElectronIdentification/plugins/cuts/GsfEleConversionVetoCut.cc @@ -65,8 +65,7 @@ CutApplicatorBase::result_type GsfEleConversionVetoCut:: operator()(const reco::GsfElectronPtr& cand) const{ if( _thebs.isValid() && _convs.isValid() ) { - return !ConversionTools::hasMatchedConversion(*cand,_convs, - _thebs->position()); + return !ConversionTools::hasMatchedConversion(*cand, *_convs, _thebs->position()); } else { edm::LogWarning("GsfEleConversionVetoCut") << "Couldn't find a necessary collection, returning true!"; @@ -77,8 +76,7 @@ operator()(const reco::GsfElectronPtr& cand) const{ double GsfEleConversionVetoCut::value(const reco::CandidatePtr& cand) const { reco::GsfElectronPtr ele(cand); if( _thebs.isValid() && _convs.isValid() ) { - return !ConversionTools::hasMatchedConversion(*ele,_convs, - _thebs->position()); + return !ConversionTools::hasMatchedConversion(*ele, *_convs, _thebs->position()); } else { edm::LogWarning("GsfEleConversionVetoCut") << "Couldn't find a necessary collection, returning true!"; diff --git a/RecoEgamma/ElectronIdentification/python/ElectronIDValueMapProducer_cfi.py b/RecoEgamma/ElectronIdentification/python/ElectronIDValueMapProducer_cfi.py deleted file mode 100644 index aff1439d4d704..0000000000000 --- a/RecoEgamma/ElectronIdentification/python/ElectronIDValueMapProducer_cfi.py +++ /dev/null @@ -1,19 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -electronIDValueMapProducer = cms.EDProducer('ElectronIDValueMapProducer', - # The module automatically detects AOD vs miniAOD, so we configure both - # - # AOD case - # - ebReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEB"), - eeReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEE"), - esReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsES"), - src = cms.InputTag('gedGsfElectrons'), - # - # miniAOD case - # - ebReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEBRecHits"), - eeReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEERecHits"), - esReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedESRecHits"), - srcMiniAOD = cms.InputTag('slimmedElectrons',processName=cms.InputTag.skipCurrentProcess()), -) diff --git a/RecoEgamma/ElectronIdentification/python/ElectronMVAValueMapProducer_cfi.py b/RecoEgamma/ElectronIdentification/python/ElectronMVAValueMapProducer_cfi.py index c9d34d4415608..c094f4c20fcd3 100644 --- a/RecoEgamma/ElectronIdentification/python/ElectronMVAValueMapProducer_cfi.py +++ b/RecoEgamma/ElectronIdentification/python/ElectronMVAValueMapProducer_cfi.py @@ -27,21 +27,6 @@ import mvaEleID_Fall17_iso_V2_producer_config mvaConfigsForEleProducer.append( mvaEleID_Fall17_iso_V2_producer_config ) -# The producer to compute the MVA input variables which are not accessible with the cut parser -electronMVAVariableHelper = cms.EDProducer('GsfElectronMVAVariableHelper', - # The module automatically detects AOD vs miniAOD, so we configure both - # AOD case - src = cms.InputTag('gedGsfElectrons'), - vertexCollection = cms.InputTag("offlinePrimaryVertices"), - beamSpot = cms.InputTag("offlineBeamSpot"), - conversions = cms.InputTag("allConversions"), - # miniAOD case - srcMiniAOD = cms.InputTag('slimmedElectrons',processName=cms.InputTag.skipCurrentProcess()), - vertexCollectionMiniAOD = cms.InputTag("offlineSlimmedPrimaryVertices"), - beamSpotMiniAOD = cms.InputTag("offlineBeamSpot"), - conversionsMiniAOD = cms.InputTag("reducedEgamma:reducedConversions"), - ) - electronMVAValueMapProducer = cms.EDProducer('ElectronMVAValueMapProducer', # The module automatically detects AOD vs miniAOD, so we configure both # diff --git a/RecoEgamma/ElectronIdentification/python/ElectronRegressionValueMapProducer_cfi.py b/RecoEgamma/ElectronIdentification/python/ElectronRegressionValueMapProducer_cfi.py deleted file mode 100644 index e72bfd917276b..0000000000000 --- a/RecoEgamma/ElectronIdentification/python/ElectronRegressionValueMapProducer_cfi.py +++ /dev/null @@ -1,21 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -electronRegressionValueMapProducer = cms.EDProducer('ElectronRegressionValueMapProducer', - #presently the electron regressions use the "zero-suppressed" shower shapes - useFull5x5 = cms.bool(False), - # The module automatically detects AOD vs miniAOD, so we configure both - # - # AOD case - # - ebReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEB"), - eeReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEE"), - esReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsES"), - src = cms.InputTag('gedGsfElectrons'), - # - # miniAOD case - # - ebReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEBRecHits"), - eeReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEERecHits"), - esReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedESRecHits"), - srcMiniAOD = cms.InputTag('slimmedElectrons',processName=cms.InputTag.skipCurrentProcess()), - ) diff --git a/RecoEgamma/ElectronIdentification/python/FWLite.py b/RecoEgamma/ElectronIdentification/python/FWLite.py new file mode 100644 index 0000000000000..9ee170a0d5241 --- /dev/null +++ b/RecoEgamma/ElectronIdentification/python/FWLite.py @@ -0,0 +1,136 @@ +import ROOT +import ctypes +import pprint +from numpy import exp + +# Python wrappers around the Electron MVAs. +# Usage example in RecoEgamma/ElectronIdentification/test + +class ElectronMVAID: + """ Electron MVA wrapper class. + """ + + def __init__(self, name, tag, categoryCuts, xmls, variablesFile, debug=False): + self.name = name + self.tag = tag + self.categoryCuts = categoryCuts + self.variablesFile = variablesFile + self.xmls = ROOT.vector(ROOT.string)() + for x in xmls: self.xmls.push_back(x) + self._init = False + self._debug = debug + + def __call__(self, ele, convs, beam_spot, rho, debug=False): + '''returns a tuple mva_value, category + ele: a reco::GsfElectron + convs: conversions + beam_spot: beam spot + rho: energy density in the event + debug: enable debugging mode. + + example: + + event.getByLabel(('slimmedElectrons'), ele_handle) + event.getByLabel(('fixedGridRhoFastjetAll'), rho_handle) + event.getByLabel(('reducedEgamma:reducedConversions'), conv_handle) + event.getByLabel(('offlineBeamSpot'), bs_handle) + + electrons = ele_handle.product() + convs = conv_handle.product() + beam_spot = bs_handle.product() + rho = rho_handle.product() + + mva, category = electron_mva_id(electron[0], convs, beam_spot, rho) + ''' + if not self._init: + print('Initializing ' + self.name + self.tag) + ROOT.gSystem.Load("libRecoEgammaElectronIdentification") + categoryCutStrings = ROOT.vector(ROOT.string)() + for x in self.categoryCuts : + categoryCutStrings.push_back(x) + self.estimator = ROOT.ElectronMVAEstimatorRun2( + self.tag, self.name, len(self.xmls), + self.variablesFile, categoryCutStrings, self.xmls, self._debug) + self._init = True + extra_vars = self.estimator.getExtraVars(ele, convs, beam_spot, rho[0]) + category = ctypes.c_int(0) + mva = self.estimator.mvaValue(ele, extra_vars, category) + return mva, category.value + + +class WorkingPoints(object): + '''Working Points. Keeps track of the cuts associated to a given flavour of the MVA ID + for each working point and allows to test the working points''' + + def __init__(self, name, tag, working_points, logistic_transform=False): + self.name = name + self.tag = tag + self.working_points = self._reformat_cut_definitions(working_points) + self.logistic_transform = logistic_transform + + def _reformat_cut_definitions(self, working_points): + new_definitions = dict() + for wpname, definitions in working_points.iteritems(): + new_definitions[wpname] = dict() + for name, cut in definitions.cuts.iteritems(): + categ_id = int(name.lstrip('cutCategory')) + cut = cut.replace('pt','x') + formula = ROOT.TFormula('_'.join([self.name, wpname, name]), cut) + new_definitions[wpname][categ_id] = formula + return new_definitions + + def passed(self, ele, mva, category, wp): + '''return true if ele passes wp''' + threshold = self.working_points[wp][category].Eval(ele.pt()) + if self.logistic_transform: + mva = 2.0/(1.0+exp(-2.0*mva))-1 + return mva > threshold + + +# Import information needed to construct the e/gamma MVAs + +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_tools \ + import EleMVA_6CategoriesCuts, mvaVariablesFile, EleMVA_3CategoriesCuts + +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V2_cff \ + import mvaWeightFiles as Fall17_iso_V2_weightFiles +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V2_cff \ + import mvaWeightFiles as Fall17_noIso_V2_weightFiles +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_GeneralPurpose_V1_cff \ + import mvaSpring16WeightFiles_V1 as mvaSpring16GPWeightFiles_V1 +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_HZZ_V1_cff \ + import mvaSpring16WeightFiles_V1 as mvaSpring16HZZWeightFiles_V1 + +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_GeneralPurpose_V1_cff \ + import workingPoints as mvaSpring16GP_V1_workingPoints +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_HZZ_V1_cff \ + import workingPoints as mvaSpring16HZZ_V1_workingPoints +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V2_cff \ + import workingPoints as Fall17_iso_V2_workingPoints +from RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V2_cff \ + import workingPoints as Fall17_noIso_V2_workingPoints + +# Dictionary with the relecant e/gmma MVAs + +electron_mvas = { + "Fall17IsoV2" : ElectronMVAID("ElectronMVAEstimatorRun2","Fall17IsoV2", + EleMVA_6CategoriesCuts, Fall17_iso_V2_weightFiles, mvaVariablesFile), + "Fall17NoIsoV2" : ElectronMVAID("ElectronMVAEstimatorRun2","Fall17NoIsoV2", + EleMVA_6CategoriesCuts, Fall17_noIso_V2_weightFiles, mvaVariablesFile), + "Spring16HZZV1" : ElectronMVAID("ElectronMVAEstimatorRun2","Spring16HZZV1", + EleMVA_6CategoriesCuts, mvaSpring16HZZWeightFiles_V1, mvaVariablesFile), + "Spring16GPV1" : ElectronMVAID("ElectronMVAEstimatorRun2","Spring16GeneralPurposeV1", + EleMVA_3CategoriesCuts, mvaSpring16GPWeightFiles_V1, mvaVariablesFile), + } + +working_points = { + "Fall17IsoV2" : WorkingPoints("ElectronMVAEstimatorRun2","Fall17IsoV2", + Fall17_iso_V2_workingPoints), + "Fall17NoIsoV2" : WorkingPoints("ElectronMVAEstimatorRun2","Fall17NoIsoV2", + Fall17_noIso_V2_workingPoints), + "Spring16HZZV1" : WorkingPoints("ElectronMVAEstimatorRun2","Spring16HZZV1", + mvaSpring16HZZ_V1_workingPoints, logistic_transform=True), + "Spring16GPV1" : WorkingPoints("ElectronMVAEstimatorRun2","Spring16GeneralPurposeV1", + mvaSpring16GP_V1_workingPoints, logistic_transform=True), + + } diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V1_cff.py index 53a15b8a3538b..aac79965cdc9f 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V1_cff.py @@ -84,7 +84,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(6), - categoryCuts = EleMVA_6CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaFall17WeightFiles_V1, variableDefinition = cms.string("RecoEgamma/ElectronIdentification/data/ElectronMVAEstimatorRun2Fall17V1Variables.txt") diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V2_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V2_cff.py index 6d954bff85a32..a52bcb826fb47 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V2_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_iso_V2_cff.py @@ -9,23 +9,14 @@ weightFileDir = "RecoEgamma/ElectronIdentification/data/MVAWeightFiles/Fall17IsoV2" -mvaWeightFiles = cms.vstring( +mvaWeightFiles = [ path.join(weightFileDir, "EB1_5.weights.xml.gz"), # EB1_5 path.join(weightFileDir, "EB2_5.weights.xml.gz"), # EB2_5 path.join(weightFileDir, "EE_5.weights.xml.gz"), # EE_5 path.join(weightFileDir, "EB1_10.weights.xml.gz"), # EB1_10 path.join(weightFileDir, "EB2_10.weights.xml.gz"), # EB2_10 path.join(weightFileDir, "EE_10.weights.xml.gz"), # EE_10 - ) - -categoryCuts = cms.vstring( - "pt < 10. && abs(superCluster.eta) < 0.800", # EB1_5 - "pt < 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", # EB2_5 - "pt < 10. && abs(superCluster.eta) >= 1.479", # EE_5 - "pt >= 10. && abs(superCluster.eta) < 0.800", # EB1_10 - "pt >= 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", # EB2_10 - "pt >= 10. && abs(superCluster.eta) >= 1.479", # EE_10 - ) + ] mvaEleID_Fall17_iso_V2_wpHZZ_container = EleMVARaw_WP( idName = "mvaEleID-Fall17-iso-V2-wpHZZ", mvaTag = mvaTag, @@ -68,12 +59,19 @@ ) +workingPoints = dict( + wpHZZ = mvaEleID_Fall17_iso_V2_wpHZZ_container, + wp80 = mvaEleID_Fall17_iso_V2_wp80_container, + wpLoose = mvaEleID_Fall17_iso_V2_wpLoose_container, + wp90 = mvaEleID_Fall17_iso_V2_wp90_container +) + mvaEleID_Fall17_iso_V2_producer_config = cms.PSet( mvaName = cms.string(mvaClassName), mvaTag = cms.string(mvaTag), nCategories = cms.int32(6), - categoryCuts = categoryCuts, - weightFileNames = mvaWeightFiles, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), + weightFileNames = cms.vstring(*mvaWeightFiles), variableDefinition = cms.string(mvaVariablesFile) ) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V1_cff.py index 0f60a26ab19f8..469d18528989a 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V1_cff.py @@ -84,7 +84,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(6), - categoryCuts = EleMVA_6CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaFall17WeightFiles_V1, variableDefinition = cms.string("RecoEgamma/ElectronIdentification/data/ElectronMVAEstimatorRun2Fall17V1Variables.txt") diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V2_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V2_cff.py index ebfbb3bb58530..3d637d9333286 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V2_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Fall17_noIso_V2_cff.py @@ -18,15 +18,6 @@ path.join(weightFileDir, "EE_10.weights.xml.gz"), # EE_10 ) -categoryCuts = cms.vstring( - "pt < 10. && abs(superCluster.eta) < 0.800", # EB1_5 - "pt < 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", # EB2_5 - "pt < 10. && abs(superCluster.eta) >= 1.479", # EE_5 - "pt >= 10. && abs(superCluster.eta) < 0.800", # EB1_10 - "pt >= 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", # EB2_10 - "pt >= 10. && abs(superCluster.eta) >= 1.479", # EE_10 - ) - mvaEleID_Fall17_noIso_V2_wp80_container = EleMVARaw_WP( idName = "mvaEleID-Fall17-noIso-V2-wp80", mvaTag = mvaTag, cutCategory0 = "3.26449620468 - exp(-pt / 3.32657149223) * 8.84669783568", # EB1_5 @@ -57,12 +48,17 @@ cutCategory5 = "4.16921343208 - exp(-pt / 13.2017224621) * 9.00720913211", # EE_10 ) +workingPoints = dict( + wp80 = mvaEleID_Fall17_noIso_V2_wp80_container, + wpLoose = mvaEleID_Fall17_noIso_V2_wpLoose_container, + wp90 = mvaEleID_Fall17_noIso_V2_wp90_container +) mvaEleID_Fall17_noIso_V2_producer_config = cms.PSet( mvaName = cms.string(mvaClassName), mvaTag = cms.string(mvaTag), nCategories = cms.int32(6), - categoryCuts = categoryCuts, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), weightFileNames = mvaWeightFiles, variableDefinition = cms.string(mvaVariablesFile) ) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_Trig_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_Trig_V1_cff.py index 94e9a668ee172..dd16f16e853ba 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_Trig_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_Trig_V1_cff.py @@ -58,7 +58,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(3), - categoryCuts = EleMVA_3CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_3CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaSpring15TrigWeightFiles_V1, variableDefinition = cms.string(mvaVariablesFile) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_nonTrig_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_nonTrig_V1_cff.py index 2caa0e24f671b..9567bc4ecc66c 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_nonTrig_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_25ns_nonTrig_V1_cff.py @@ -84,7 +84,7 @@ # # Category parameters nCategories = cms.int32(6), - categoryCuts = EleMVA_6CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaSpring15NonTrigWeightFiles_V1, variableDefinition = cms.string(mvaVariablesFile) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_50ns_Trig_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_50ns_Trig_V1_cff.py index 741756d2c4014..9e1f287b4c432 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_50ns_Trig_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring15_50ns_Trig_V1_cff.py @@ -58,7 +58,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(3), - categoryCuts = EleMVA_3CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_3CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaSpring15TrigWeightFiles_V1, variableDefinition = cms.string(mvaVariablesFile) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_GeneralPurpose_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_GeneralPurpose_V1_cff.py index 45a24a641a638..0c65afc9dacd1 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_GeneralPurpose_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_GeneralPurpose_V1_cff.py @@ -45,7 +45,10 @@ cutCategory2 = "0.758484721184", # EE ) - +workingPoints = dict( + wp80 = MVA_WP80, + wp90 = MVA_WP90 +) # # Finally, set up VID configuration for all cuts @@ -57,7 +60,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(3), - categoryCuts = EleMVA_3CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_3CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaSpring16WeightFiles_V1, variableDefinition = cms.string(mvaVariablesFile) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_HZZ_V1_cff.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_HZZ_V1_cff.py index 10506aef32ab6..9d0691af2601d 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_HZZ_V1_cff.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_Spring16_HZZ_V1_cff.py @@ -51,6 +51,10 @@ cutCategory5 = "-0.763" # EE ) +workingPoints = dict( + wpLoose = MVA_WPLoose +) + # # Finally, set up VID configuration for all cuts @@ -62,7 +66,7 @@ mvaTag = cms.string(mvaTag), # Category parameters nCategories = cms.int32(6), - categoryCuts = EleMVA_6CategoriesCuts, + categoryCuts = cms.vstring(*EleMVA_6CategoriesCuts), # Weight files and variable definitions weightFileNames = mvaSpring16WeightFiles_V1, variableDefinition = cms.string(mvaVariablesFile) diff --git a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_tools.py b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_tools.py index 7af6a40296d13..568ff73584b82 100644 --- a/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_tools.py +++ b/RecoEgamma/ElectronIdentification/python/Identification/mvaElectronID_tools.py @@ -20,20 +20,20 @@ # Define some commonly used category cuts # ======================================= -EleMVA_3CategoriesCuts = cms.vstring( +EleMVA_3CategoriesCuts = [ "abs(superCluster.eta) < 0.800", "abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", "abs(superCluster.eta) >= 1.479" - ) + ] -EleMVA_6CategoriesCuts = cms.vstring( +EleMVA_6CategoriesCuts = [ "pt < 10. && abs(superCluster.eta) < 0.800", "pt < 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", "pt < 10. && abs(superCluster.eta) >= 1.479", "pt >= 10. && abs(superCluster.eta) < 0.800", "pt >= 10. && abs(superCluster.eta) >= 0.800 && abs(superCluster.eta) < 1.479", "pt >= 10. && abs(superCluster.eta) >= 1.479", - ) + ] # ======================================================= # Define simple containers for MVA cut values and related diff --git a/RecoEgamma/ElectronIdentification/python/Training/ElectronMVANtuplizer_cfg.py b/RecoEgamma/ElectronIdentification/python/Training/ElectronMVANtuplizer_cfg.py deleted file mode 100644 index bc18012168d54..0000000000000 --- a/RecoEgamma/ElectronIdentification/python/Training/ElectronMVANtuplizer_cfg.py +++ /dev/null @@ -1,124 +0,0 @@ -import FWCore.ParameterSet.Config as cms -from RecoEgamma.ElectronIdentification.ElectronMVAValueMapProducer_cfi import electronMVAVariableHelper -from PhysicsTools.SelectorUtils.tools.vid_id_tools import * -from Configuration.AlCa.GlobalTag import GlobalTag - -process = cms.Process("ElectronMVANtuplizer") - -process.load("FWCore.MessageService.MessageLogger_cfi") -process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") - -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_mc', '') - -# File with the ID variables to include in the Ntuplizer -mvaVariablesFile = "RecoEgamma/ElectronIdentification/data/ElectronIDVariables.txt" - -outputFile = "electron_ntuple.root" - -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) - -process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring( - '/store/mc/RunIIFall17MiniAOD/DYJetsToLL_M-50_TuneCP5_13TeV-madgraphMLM-pythia8/MINIAODSIM/RECOSIMstep_94X_mc2017_realistic_v10-v1/00000/0293A280-B5F3-E711-8303-3417EBE33927.root' - ) -) - -useAOD = False - -from PhysicsTools.SelectorUtils.tools.vid_id_tools import * -# turn on VID producer, indicate data format to be -# DataFormat.AOD or DataFormat.MiniAOD, as appropriate -if useAOD == True : - dataFormat = DataFormat.AOD -else : - dataFormat = DataFormat.MiniAOD - -switchOnVIDElectronIdProducer(process, dataFormat) - -# define which IDs we want to produce -my_id_modules = [ - 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V2_cff', - 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V2_cff', - 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V1_cff', - 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V1_cff', - ] - -#add them to the VID producer -for idmod in my_id_modules: - setupAllVIDIdsInModule(process,idmod,setupVIDElectronSelection) - -process.ntuplizer = cms.EDAnalyzer('ElectronMVANtuplizer', - # AOD case - src = cms.InputTag('gedGsfElectrons'), - vertices = cms.InputTag('offlinePrimaryVertices'), - pileup = cms.InputTag('addPileupInfo'), - genParticles = cms.InputTag('genParticles'), - # miniAOD case - srcMiniAOD = cms.InputTag('slimmedElectrons'), - verticesMiniAOD = cms.InputTag('offlineSlimmedPrimaryVertices'), - pileupMiniAOD = cms.InputTag('slimmedAddPileupInfo'), - genParticlesMiniAOD = cms.InputTag('prunedGenParticles'), - # - eleMVAs = cms.untracked.vstring( - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp80", - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wpLoose", - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp90", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wpHZZ", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp80", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wpLoose", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp90", - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wp90", - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wp80", - "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wpLoose", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wp90", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wp80", - "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wpLoose", - ), - eleMVALabels = cms.untracked.vstring( - "Fall17noIsoV2wp80", - "Fall17noIsoV2wpLoose", - "Fall17noIsoV2wp90", - "Fall17isoV2wpHZZ", - "Fall17isoV2wp80", - "Fall17isoV2wpLoose", - "Fall17isoV2wp90", - "Fall17noIsoV1wp90", - "Fall17noIsoV1wp80", - "Fall17noIsoV1wpLoose", - "Fall17isoV1wp90", - "Fall17isoV1wp80", - "Fall17isoV1wpLoose", - ), - eleMVAValMaps = cms.untracked.vstring( - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV2Values", - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV2RawValues", - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV2Values", - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV2RawValues", - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV1Values", - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV1Values", - ), - eleMVAValMapLabels = cms.untracked.vstring( - "Fall17NoIsoV2Vals", - "Fall17NoIsoV2RawVals", - "Fall17IsoV2Vals", - "Fall17IsoV2RawVals", - "Fall17IsoV1Vals", - "Fall17NoIsoV1Vals", - ), - eleMVACats = cms.untracked.vstring( - "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV1Categories", - ), - eleMVACatLabels = cms.untracked.vstring( - "EleMVACats", - ), - # - variableDefinition = cms.string(mvaVariablesFile), - isMC = cms.bool(True), - deltaR = cms.double(0.1), - ) - -process.TFileService = cms.Service("TFileService", - fileName = cms.string( outputFile ) - ) - -process.p = cms.Path(process.egmGsfElectronIDSequence * process.ntuplizer) diff --git a/RecoEgamma/ElectronIdentification/python/egmGsfElectronIDs_cff.py b/RecoEgamma/ElectronIdentification/python/egmGsfElectronIDs_cff.py index 885d21c4baa36..443f78cd27168 100644 --- a/RecoEgamma/ElectronIdentification/python/egmGsfElectronIDs_cff.py +++ b/RecoEgamma/ElectronIdentification/python/egmGsfElectronIDs_cff.py @@ -14,12 +14,9 @@ # Load the producer for MVA IDs. Make sure it is also added to the sequence! from RecoEgamma.ElectronIdentification.ElectronMVAValueMapProducer_cfi import * -from RecoEgamma.ElectronIdentification.ElectronRegressionValueMapProducer_cfi import * egmGsfElectronIDTask = cms.Task( - electronMVAVariableHelper, electronMVAValueMapProducer, - egmGsfElectronIDs, - electronRegressionValueMapProducer + egmGsfElectronIDs ) egmGsfElectronIDSequence = cms.Sequence(egmGsfElectronIDTask) diff --git a/RecoEgamma/ElectronIdentification/python/electronIdNeuralNetExt_cfi.py b/RecoEgamma/ElectronIdentification/python/electronIdNeuralNetExt_cfi.py deleted file mode 100644 index 8623ed2974809..0000000000000 --- a/RecoEgamma/ElectronIdentification/python/electronIdNeuralNetExt_cfi.py +++ /dev/null @@ -1,10 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -eidNeuralNetExt = cms.EDProducer("EleIdNeuralNetExtProducer", - src = cms.InputTag("gedGsfElectrons"), - doNeuralNet = cms.bool(True), - weightsDir = cms.string(''), - NN_set = cms.string('ZeeZmumuJets-2500ev') -) - - diff --git a/RecoEgamma/ElectronIdentification/python/electronIdNeuralNet_cfi.py b/RecoEgamma/ElectronIdentification/python/electronIdNeuralNet_cfi.py deleted file mode 100644 index 55502f2201c3d..0000000000000 --- a/RecoEgamma/ElectronIdentification/python/electronIdNeuralNet_cfi.py +++ /dev/null @@ -1,12 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -eidNeuralNet = cms.EDFilter("EleIdNeuralNetRef", - filter = cms.bool(False), - threshold = cms.double(0.5), - src = cms.InputTag("gedGsfElectrons"), - doNeuralNet = cms.bool(True), - weightsDir = cms.string(''), - NN_set = cms.string('ZeeZmumuJets-2500ev') -) - - diff --git a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc index 30727c9fa0490..2cfaafb7ef422 100644 --- a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc +++ b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc @@ -3,85 +3,25 @@ #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" - -#include "TMVA/Reader.h" -#include "TMVA/MethodBDT.h" -#include "TMVA/MethodCategory.h" - -namespace { - constexpr char ele_mva_name[] = "BDTSimpleCat"; -} +#include "CommonTools/MVAUtils/interface/GBRForestTools.h" ElectronMVAEstimator::ElectronMVAEstimator(): cfg_{} {} -ElectronMVAEstimator::ElectronMVAEstimator(std::string fileName): +ElectronMVAEstimator::ElectronMVAEstimator(const std::string& fileName): cfg_{} { - TMVA::Reader tmvaReader("!Color:Silent"); - tmvaReader.AddVariable("fbrem",&fbrem); - tmvaReader.AddVariable("detain", &detain); - tmvaReader.AddVariable("dphiin", &dphiin); - tmvaReader.AddVariable("sieie", &sieie); - tmvaReader.AddVariable("hoe", &hoe); - tmvaReader.AddVariable("eop", &eop); - tmvaReader.AddVariable("e1x5e5x5", &e1x5e5x5); - tmvaReader.AddVariable("eleopout", &eleopout); - tmvaReader.AddVariable("detaeleout", &detaeleout); - tmvaReader.AddVariable("kfchi2", &kfchi2); - tmvaReader.AddVariable("kfhits", &mykfhits); - tmvaReader.AddVariable("mishits",&mymishits); - tmvaReader.AddVariable("dist", &absdist); - tmvaReader.AddVariable("dcot", &absdcot); - tmvaReader.AddVariable("nvtx", &myNvtx); - - tmvaReader.AddSpectator("eta",&eta); - tmvaReader.AddSpectator("pt",&pt); - tmvaReader.AddSpectator("ecalseed",&ecalseed); - // Taken from Daniele (his mail from the 30/11) // tmvaReader.BookMVA("BDTSimpleCat","../Training/weights_Root527b_3Depth_DanVarConvRej_2PtBins_10Pt_800TPrune5_Min100Events_NoBjets_half/TMVA_BDTSimpleCat.weights.xm"); // training of the 7/12 with Nvtx added - tmvaReader.BookMVA(ele_mva_name,fileName.c_str()); - gbr.emplace_back(new GBRForest( dynamic_cast( tmvaReader.FindMVA(ele_mva_name) ) ) ); + gbr_.push_back( createGBRForest(fileName) ); } -ElectronMVAEstimator::ElectronMVAEstimator(const Configuration & cfg):cfg_(cfg){ - std::vector weightsfiles; - std::string path_mvaWeightFileEleID; - for(unsigned ifile=0 ; ifile < cfg_.vweightsfiles.size() ; ++ifile) { - path_mvaWeightFileEleID = edm::FileInPath ( cfg_.vweightsfiles[ifile].c_str() ).fullPath(); - weightsfiles.push_back(path_mvaWeightFileEleID); - } - for( const auto& wgtfile : weightsfiles ) { - TMVA::Reader tmvaReader("!Color:Silent"); - tmvaReader.AddVariable("fbrem",&fbrem); - tmvaReader.AddVariable("detain", &detain); - tmvaReader.AddVariable("dphiin", &dphiin); - tmvaReader.AddVariable("sieie", &sieie); - tmvaReader.AddVariable("hoe", &hoe); - tmvaReader.AddVariable("eop", &eop); - tmvaReader.AddVariable("e1x5e5x5", &e1x5e5x5); - tmvaReader.AddVariable("eleopout", &eleopout); - tmvaReader.AddVariable("detaeleout", &detaeleout); - tmvaReader.AddVariable("kfchi2", &kfchi2); - tmvaReader.AddVariable("kfhits", &mykfhits); - tmvaReader.AddVariable("mishits",&mymishits); - tmvaReader.AddVariable("dist", &absdist); - tmvaReader.AddVariable("dcot", &absdcot); - tmvaReader.AddVariable("nvtx", &myNvtx); - - tmvaReader.AddSpectator("eta",&eta); - tmvaReader.AddSpectator("pt",&pt); - tmvaReader.AddSpectator("ecalseed",&ecalseed); - - // Taken from Daniele (his mail from the 30/11) - // tmvaReader.BookMVA("BDTSimpleCat","../Training/weights_Root527b_3Depth_DanVarConvRej_2PtBins_10Pt_800TPrune5_Min100Events_NoBjets_half/TMVA_BDTSimpleCat.weights.xm"); - // training of the 7/12 with Nvtx added - tmvaReader.BookMVA(ele_mva_name,wgtfile); - gbr.emplace_back(new GBRForest( dynamic_cast( tmvaReader.FindMVA(ele_mva_name) ) ) ); +ElectronMVAEstimator::ElectronMVAEstimator(const Configuration & cfg):cfg_(cfg) +{ + for(const auto& weightsfile : cfg_.vweightsfiles) { + gbr_.push_back( createGBRForest(weightsfile) ); } } @@ -122,7 +62,7 @@ double ElectronMVAEstimator::mva(const reco::GsfElectron& myElectron, int nverti const unsigned index = (unsigned)(myElectron.pt() >= 10) + 2*(unsigned)(std::abs(myElectron.eta()) > 1.485); - double result = gbr[index]->GetAdaBoostClassifier(vars); + double result = gbr_[index]->GetAdaBoostClassifier(vars); // // std::cout << "fbrem" << vars[0] << std::endl; // std::cout << "detain"<< vars[1] << std::endl; diff --git a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc index 28325eb8a352d..82a357d7254ff 100644 --- a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc +++ b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc @@ -2,72 +2,72 @@ ElectronMVAEstimatorRun2::ElectronMVAEstimatorRun2(const edm::ParameterSet& conf): AnyMVAEstimatorRun2Base(conf), - name_(conf.getParameter("mvaName")), - tag_(conf.getParameter("mvaTag")), - nCategories_ (conf.getParameter("nCategories")), - methodName_ ("BDTG method"), - mvaVarMngr_(conf.getParameter("variableDefinition")), - debug_(conf.getUntrackedParameter("debug", false)) + mvaVarMngr_(conf.getParameter("variableDefinition")) { - const std::vector weightFileNames - = conf.getParameter >("weightFileNames"); + const auto weightFileNames = conf.getParameter >("weightFileNames"); + const auto categoryCutStrings = conf.getParameter >("categoryCuts"); - const std::vector categoryCutStrings - = conf.getParameter >("categoryCuts"); - - if( (int)(categoryCutStrings.size()) != nCategories_ ) + if( (int)(categoryCutStrings.size()) != getNCategories() ) throw cms::Exception("MVA config failure: ") - << "wrong number of category cuts in " << name_ << tag_ << std::endl; + << "wrong number of category cuts in ElectronMVAEstimatorRun2" << getTag() << std::endl; - for (int i = 0; i < nCategories_; ++i) { - StringCutObjectSelector select(categoryCutStrings[i]); - categoryFunctions_.push_back(select); + for (int i = 0; i < getNCategories(); ++i) { + categoryFunctions_.emplace_back(categoryCutStrings[i]); } // Initialize GBRForests from weight files init(weightFileNames); - } -ElectronMVAEstimatorRun2::ElectronMVAEstimatorRun2( - const std::string &mvaTag, const std::string &mvaName, const bool debug): - AnyMVAEstimatorRun2Base( edm::ParameterSet() ), - name_ (mvaName), - tag_ (mvaTag), - methodName_ ("BDTG method"), - debug_ (debug) { - } +ElectronMVAEstimatorRun2::ElectronMVAEstimatorRun2( const std::string& mvaTag, + const std::string& mvaName, + int nCategories, + const std::string& variableDefinition, + const std::vector& categoryCutStrings, + const std::vector &weightFileNames, + bool debug) + : AnyMVAEstimatorRun2Base( mvaName, mvaTag, nCategories, debug ) + , mvaVarMngr_ (variableDefinition) +{ + + if( (int)(categoryCutStrings.size()) != getNCategories() ) + throw cms::Exception("MVA config failure: ") + << "wrong number of category cuts in " << getName() << getTag() << std::endl; + + for (auto const& cut : categoryCutStrings) categoryFunctions_.emplace_back(cut); + init(weightFileNames); +} void ElectronMVAEstimatorRun2::init(const std::vector &weightFileNames) { - if(debug_) { - std::cout << " *** Inside " << name_ << tag_ << std::endl; + if(isDebug()) { + std::cout << " *** Inside ElectronMVAEstimatorRun2" << getTag() << std::endl; } // Initialize GBRForests - if( (int)(weightFileNames.size()) != nCategories_ ) + if( (int)(weightFileNames.size()) != getNCategories() ) throw cms::Exception("MVA config failure: ") - << "wrong number of weightfiles in " << name_ << tag_ << std::endl; + << "wrong number of weightfiles in ElectronMVAEstimatorRun2" << getTag() << std::endl; gbrForests_.clear(); // Create a TMVA reader object for each category - for(int i=0; i variableNamesInCategory; std::vector variablesInCategory; // Use unique_ptr so that all readers are properly cleaned up // when the vector clear() is called in the destructor - gbrForests_.push_back( GBRForestTools::createGBRForest( weightFileNames[i], variableNamesInCategory ) ); + std::vector variableNamesInCategory; + gbrForests_.push_back(createGBRForest(weightFileNames[i], variableNamesInCategory)); nVariables_.push_back(variableNamesInCategory.size()); variables_.push_back(variablesInCategory); - if(debug_) { - std::cout << " *** Inside " << name_ << tag_ << std::endl; + if(isDebug()) { + std::cout << " *** Inside ElectronMVAEstimatorRun2" << getTag() << std::endl; std::cout << " category " << i << " with nVariables " << nVariables_[i] << std::endl; } @@ -75,7 +75,7 @@ void ElectronMVAEstimatorRun2::init(const std::vector &weightFileNa int index = mvaVarMngr_.getVarIndex(variableNamesInCategory[j]); if(index == -1) { throw cms::Exception("MVA config failure: ") - << "Concerning " << name_ << tag_ << std::endl + << "Concerning ElectronMVAEstimatorRun2" << getTag() << std::endl << "Variable " << variableNamesInCategory[j] << " not found in variable definition file!" << std::endl; } @@ -85,44 +85,29 @@ void ElectronMVAEstimatorRun2::init(const std::vector &weightFileNa } } -ElectronMVAEstimatorRun2:: -~ElectronMVAEstimatorRun2(){ -} - -void ElectronMVAEstimatorRun2::setConsumes(edm::ConsumesCollector&& cc) const { - // All tokens for event content needed by this MVA - // Tags from the variable helper - for (auto &tag : mvaVarMngr_.getHelperInputTags()) { - cc.consumes>(tag); - } - for (auto &tag : mvaVarMngr_.getGlobalInputTags()) { - cc.consumes(tag); - } -} - float ElectronMVAEstimatorRun2:: -mvaValue( const edm::Ptr& candPtr, const edm::EventBase & iEvent) const { +mvaValue( const reco::Candidate* candidate, const std::vector& auxVariables, int &iCategory) const { - const int iCategory = findCategory( candPtr ); + const reco::GsfElectron* electron = dynamic_cast(candidate); - if (iCategory < 0) return -999; - - std::vector vars; - - const edm::Ptr gsfPtr{ candPtr }; - - if( gsfPtr.get() == nullptr ) { + if( electron == nullptr ) { throw cms::Exception("MVA failure: ") << " given particle is expected to be reco::GsfElectron or pat::Electron," << std::endl << " but appears to be neither" << std::endl; } + iCategory = findCategory( electron ); + + if (iCategory < 0) return -999; + + std::vector vars; + for (int i = 0; i < nVariables_[iCategory]; ++i) { - vars.push_back(mvaVarMngr_.getValue(variables_[iCategory][i], gsfPtr, iEvent)); + vars.push_back(mvaVarMngr_.getValue(variables_[iCategory][i], *electron, auxVariables)); } - if(debug_) { - std::cout << " *** Inside " << name_ << tag_ << std::endl; + if(isDebug()) { + std::cout << " *** Inside ElectronMVAEstimatorRun2" << getTag() << std::endl; std::cout << " category " << iCategory << std::endl; for (int i = 0; i < nVariables_[iCategory]; ++i) { std::cout << " " << mvaVarMngr_.getName(variables_[iCategory][i]) << " " << vars[i] << std::endl; @@ -130,30 +115,36 @@ mvaValue( const edm::Ptr& candPtr, const edm::EventBase & iEven } const float response = gbrForests_.at(iCategory)->GetResponse(vars.data()); // The BDT score - if(debug_) { + if(isDebug()) { std::cout << " ### MVA " << response << std::endl << std::endl; } return response; } -int ElectronMVAEstimatorRun2::findCategory( const edm::Ptr& candPtr) const { +int ElectronMVAEstimatorRun2::findCategory( const reco::Candidate* candidate) const { - auto gsfEle = dynamic_cast(candPtr.get()); + const reco::GsfElectron* electron = dynamic_cast(candidate); - if( gsfEle == nullptr ) { + if( electron == nullptr ) { throw cms::Exception("MVA failure: ") << " given particle is expected to be reco::GsfElectron or pat::Electron," << std::endl << " but appears to be neither" << std::endl; } - for (int i = 0; i < nCategories_; ++i) { - if (categoryFunctions_[i](*gsfEle)) return i; + return findCategory(*electron); + +} + +int ElectronMVAEstimatorRun2::findCategory(reco::GsfElectron const& electron) const { + + for (int i = 0; i < getNCategories(); ++i) { + if (categoryFunctions_[i](electron)) return i; } edm::LogWarning ("MVA warning") << - "category not defined for particle with pt " << gsfEle->pt() << " GeV, eta " << - gsfEle->superCluster()->eta() << " in " << name_ << tag_; + "category not defined for particle with pt " << electron.pt() << " GeV, eta " << + electron.superCluster()->eta() << " in ElectronMVAEstimatorRun2" << getTag(); return -1; diff --git a/RecoEgamma/ElectronIdentification/src/ElectronNeuralNet.cc b/RecoEgamma/ElectronIdentification/src/ElectronNeuralNet.cc deleted file mode 100644 index 77247ae33a5dc..0000000000000 --- a/RecoEgamma/ElectronIdentification/src/ElectronNeuralNet.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "RecoEgamma/ElectronIdentification/interface/ElectronNeuralNet.h" - -double ElectronNeuralNet::result(const reco::GsfElectron* electron, - const edm::Event& e) { - return 1.; -} diff --git a/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc b/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc index fc765ec3a1c9f..935b4b0048392 100644 --- a/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc +++ b/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc @@ -3,66 +3,22 @@ #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" -#include "TMVA/Reader.h" -#include "TMVA/MethodBDT.h" - -SoftElectronMVAEstimator::SoftElectronMVAEstimator(const Configuration & cfg):cfg_(cfg){ - std::vector weightsfiles; - std::string path_mvaWeightFileEleID; - for(unsigned ifile=0 ; ifile < cfg_.vweightsfiles.size() ; ++ifile) { - path_mvaWeightFileEleID = edm::FileInPath ( cfg_.vweightsfiles[ifile].c_str() ).fullPath(); - weightsfiles.push_back(path_mvaWeightFileEleID); - } - - //initialize - //Define expected number of bins +#include "CommonTools/MVAUtils/interface/GBRForestTools.h" +SoftElectronMVAEstimator::SoftElectronMVAEstimator(const Configuration & cfg):cfg_(cfg) +{ //Check number of weight files given if (ExpectedNBins != cfg_.vweightsfiles.size() ) { - std::cout << "Error: Expected Number of bins = " << ExpectedNBins << " does not equal to weightsfiles.size() = " - << cfg_.vweightsfiles.size() << std::endl; - - assert(ExpectedNBins == cfg_.vweightsfiles.size()); + edm::LogError ("Soft Electron MVA Error") << + "Expected Number of bins = " << ExpectedNBins << + " does not equal to weightsfiles.size() = " << + cfg_.vweightsfiles.size() << std::endl; } - - for (unsigned int i=0;i( tmvaReader.FindMVA("BDT") ) ) ); + gbr_.push_back(createGBRForest( weightsfile )); } } @@ -70,34 +26,6 @@ SoftElectronMVAEstimator::SoftElectronMVAEstimator(const Configuration & cfg):cf SoftElectronMVAEstimator::~SoftElectronMVAEstimator() { } - -UInt_t SoftElectronMVAEstimator::GetMVABin(int pu, double eta, double pt) const { - - //Default is to return the first bin - unsigned int bin = 0; - - bool ptrange[3],etarange[3],purange[2]; - ptrange[0]=pt > 2 && pt < 5; - ptrange[1]=pt > 5 && pt < 10; - ptrange[2]=pt > 10; - etarange[0]=fabs(eta) < 0.8; - etarange[1]=fabs(eta) > 0.8 && fabs(eta) <1.4; - etarange[2]=fabs(eta) > 1.4; - purange[0]=nPV<=20; - purange[1]=nPV>20; - - int index=0; - for(int kPU=0;kPU<2;kPU++) - for(int kETA=0;kETA<3;kETA++) - for(int kPT=0;kPT<3;kPT++){ - if (purange[kPU] && ptrange[kPT] && etarange[kETA]) bin=index; - index++; - } - return bin; -} - - - double SoftElectronMVAEstimator::mva(const reco::GsfElectron& myElectron, const reco::VertexCollection& pvc) const { float vars[25]; @@ -163,7 +91,7 @@ double SoftElectronMVAEstimator::mva(const reco::GsfElectron& myElectron, */ bindVariables(vars); - double result= gbr[0]->GetClassifier(vars); + double result= gbr_[0]->GetClassifier(vars); return result; } diff --git a/RecoEgamma/ElectronIdentification/test/testElectronMVA_cfg.py b/RecoEgamma/ElectronIdentification/test/testElectronMVA_cfg.py index 0db740321493a..d552be07c746b 100644 --- a/RecoEgamma/ElectronIdentification/test/testElectronMVA_cfg.py +++ b/RecoEgamma/ElectronIdentification/test/testElectronMVA_cfg.py @@ -1,5 +1,4 @@ import FWCore.ParameterSet.Config as cms -# from RecoEgamma.ElectronIdentification.ElectronMVAValueMapProducer_cfi import electronMVAVariableHelper from PhysicsTools.SelectorUtils.tools.vid_id_tools import * from Configuration.AlCa.GlobalTag import GlobalTag @@ -13,7 +12,7 @@ # File with the ID variables to include in the Ntuplizer mvaVariablesFile = "RecoEgamma/ElectronIdentification/data/ElectronIDVariables.txt" -outputFile = "electron_validation_ntuple.root" +outputFile = "electron_ntuple.root" process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) @@ -41,6 +40,8 @@ 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_HZZ_V1_cff', 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V1_cff', 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V1_cff', + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V2_cff', + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V2_cff', ] #add them to the VID producer @@ -48,30 +49,64 @@ setupAllVIDIdsInModule(process,idmod,setupVIDElectronSelection) process.ntuplizer = cms.EDAnalyzer('ElectronMVANtuplizer', - # AOD case - src = cms.InputTag('gedGsfElectrons'), - vertices = cms.InputTag('offlinePrimaryVertices'), - pileup = cms.InputTag('addPileupInfo'), - genParticles = cms.InputTag('genParticles'), - # miniAOD case - srcMiniAOD = cms.InputTag('slimmedElectrons'), - verticesMiniAOD = cms.InputTag('offlineSlimmedPrimaryVertices'), - pileupMiniAOD = cms.InputTag('slimmedAddPileupInfo'), - genParticlesMiniAOD = cms.InputTag('prunedGenParticles'), # eleMVAs = cms.untracked.vstring( + "egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp80", + "egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp90", + "egmGsfElectronIDs:mvaEleID-Spring16-HZZ-V1-wpLoose", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp80", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wpLoose", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp90", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wpHZZ", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp80", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wpLoose", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp90", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wp90", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wp80", + "egmGsfElectronIDs:mvaEleID-Fall17-noIso-V1-wpLoose", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wp90", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wp80", + "egmGsfElectronIDs:mvaEleID-Fall17-iso-V1-wpLoose", ), eleMVALabels = cms.untracked.vstring( + "Spring16GPV1wp80", + "Spring16GPV1wp90", + "Spring16HZZV1wpLoose", + "Fall17noIsoV2wp80", + "Fall17noIsoV2wpLoose", + "Fall17noIsoV2wp90", + "Fall17isoV2wpHZZ", + "Fall17isoV2wp80", + "Fall17isoV2wpLoose", + "Fall17isoV2wp90", + "Fall17noIsoV1wp90", + "Fall17noIsoV1wp80", + "Fall17noIsoV1wpLoose", + "Fall17isoV1wp90", + "Fall17isoV1wp80", + "Fall17isoV1wpLoose", ), eleMVAValMaps = cms.untracked.vstring( "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16GeneralPurposeV1Values", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16GeneralPurposeV1RawValues", "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16HZZV1Values", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16HZZV1RawValues", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV2Values", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV2RawValues", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV2Values", + "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV2RawValues", "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV1Values", "electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV1Values", ), eleMVAValMapLabels = cms.untracked.vstring( - "Spring16GPVals", - "Spring16HZZVals", + "Spring16GPV1Vals", + "Spring16GPV1RawVals", + "Spring16HZZV1Vals", + "Spring16HZZV1RawVals", + "Fall17NoIsoV2Vals", + "Fall17NoIsoV2RawVals", + "Fall17IsoV2Vals", + "Fall17IsoV2RawVals", "Fall17IsoV1Vals", "Fall17NoIsoV1Vals", ), @@ -83,8 +118,7 @@ ), # variableDefinition = cms.string(mvaVariablesFile), - isMC = cms.bool(True), - deltaR = cms.double(0.1), + ptThreshold = cms.double(5.0), ) process.TFileService = cms.Service("TFileService", diff --git a/RecoEgamma/ElectronIdentification/test/test_eleid_fwlite.py b/RecoEgamma/ElectronIdentification/test/test_eleid_fwlite.py new file mode 100644 index 0000000000000..2dceeb27dc10b --- /dev/null +++ b/RecoEgamma/ElectronIdentification/test/test_eleid_fwlite.py @@ -0,0 +1,108 @@ +from RecoEgamma.ElectronIdentification.FWLite import electron_mvas, working_points +from DataFormats.FWLite import Events, Handle + +# Small script to validate Electron MVA implementation in FWlite + +import numpy as np +import pandas as pd + +print('open input file...') + +events = Events('root://cms-xrd-global.cern.ch//store/mc/'+ \ + 'RunIIFall17MiniAOD/DYJetsToLL_M-50_TuneCP5_13TeV-madgraphMLM-pythia8/'+ \ + 'MINIAODSIM/RECOSIMstep_94X_mc2017_realistic_v10-v1/00000/0293A280-B5F3-E711-8303-3417EBE33927.root') + +# Get Handles on the electrons and other products needed to calculate the MVAs +ele_handle = Handle('std::vector') +rho_handle = Handle('double') +conv_handle = Handle('reco::ConversionCollection') +bs_handle = Handle('reco::BeamSpot') + +n = 100000 + +data = {"Fall17IsoV2" : np.zeros(n), + "Fall17IsoV2-wp80" : np.zeros(n, dtype=bool), + "Fall17IsoV2-wp90" : np.zeros(n, dtype=bool), + "Fall17IsoV2-wpLoose" : np.zeros(n, dtype=bool), + "Fall17IsoV2-wpHZZ" : np.zeros(n, dtype=bool), + + "Fall17NoIsoV2" : np.zeros(n), + "Fall17NoIsoV2-wp80" : np.zeros(n, dtype=bool), + "Fall17NoIsoV2-wp90" : np.zeros(n, dtype=bool), + "Fall17NoIsoV2-wpLoose" : np.zeros(n, dtype=bool), + + "Spring16HZZV1" : np.zeros(n), + "Spring16HZZV1-wpLoose" : np.zeros(n, dtype=bool), + + "Spring16GPV1" : np.zeros(n), + "Spring16GPV1-wp80" : np.zeros(n, dtype=bool), + "Spring16GPV1-wp90" : np.zeros(n, dtype=bool), + + "nEvent" : -np.ones(n, dtype=int), + "pt" : np.zeros(n)} + +print('start processing') + +accepted = 0 +for i,event in enumerate(events): + + nEvent = event._event.id().event() + + print("processing event {0}: {1}...".format(i, nEvent)) + + # Save information on the first electron in an event, + # if there is any the first electron of the + + event.getByLabel(('slimmedElectrons'), ele_handle) + electrons = ele_handle.product() + + if not len(electrons): + continue + + event.getByLabel(('fixedGridRhoFastjetAll'), rho_handle) + event.getByLabel(('reducedEgamma:reducedConversions'), conv_handle) + event.getByLabel(('offlineBeamSpot'), bs_handle) + + convs = conv_handle.product() + beam_spot = bs_handle.product() + rho = rho_handle.product() + + ele = electrons[0] + i = accepted + + if ele.pt() in data["pt"][i-10:i]: + continue + + data["nEvent"][i] = nEvent + data["pt"][i] = ele.pt() + + mva, category = electron_mvas["Fall17IsoV2"](ele, convs, beam_spot, rho) + data["Fall17IsoV2"][i] = mva + data["Fall17IsoV2-wp80"][i] = working_points["Fall17IsoV2"].passed(ele, mva, category, 'wp80') + data["Fall17IsoV2-wp90"][i] = working_points["Fall17IsoV2"].passed(ele, mva, category, 'wp90') + data["Fall17IsoV2-wpLoose"][i] = working_points["Fall17IsoV2"].passed(ele, mva, category, 'wpLoose') + data["Fall17IsoV2-wpHZZ"][i] = working_points["Fall17IsoV2"].passed(ele, mva, category, 'wpHZZ') + + mva, category = electron_mvas["Fall17NoIsoV2"](ele, convs, beam_spot, rho) + data["Fall17NoIsoV2"][i] = mva + data["Fall17NoIsoV2-wp80"][i] = working_points["Fall17NoIsoV2"].passed(ele, mva, category, 'wp80') + data["Fall17NoIsoV2-wp90"][i] = working_points["Fall17NoIsoV2"].passed(ele, mva, category, 'wp90') + data["Fall17NoIsoV2-wpLoose"][i] = working_points["Fall17NoIsoV2"].passed(ele, mva, category, 'wpLoose') + + mva, category = electron_mvas["Spring16HZZV1"](ele, convs, beam_spot, rho) + data["Spring16HZZV1"][i] = mva + data["Spring16HZZV1-wpLoose"][i] = working_points["Spring16HZZV1"].passed(ele, mva, category, 'wpLoose') + + mva, category = electron_mvas["Spring16GPV1"](ele, convs, beam_spot, rho) + data["Spring16GPV1"][i] = mva + data["Spring16GPV1-wp80"][i] = working_points["Spring16GPV1"].passed(ele, mva, category, 'wp80') + data["Spring16GPV1-wp90"][i] = working_points["Spring16GPV1"].passed(ele, mva, category, 'wp90') + + accepted += 1 + + if accepted==n: + break + +ele_df = pd.DataFrame(data) +ele_df = ele_df[ele_df["nEvent"] > 0] +ele_df.to_hdf("test_eleid_fwlite.h5", key="electron_data") diff --git a/RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h b/RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h index b51c4a8d2d13e..c2a827378a8b1 100644 --- a/RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h +++ b/RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h @@ -2,75 +2,42 @@ #define RecoEgamma_PhotonIdentification_PhotonMVAEstimator_H #include "FWCore/Framework/interface/ConsumesCollector.h" - +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "DataFormats/Common/interface/ValueMap.h" - #include "RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h" - #include "DataFormats/EgammaCandidates/interface/Photon.h" - -#include "FWCore/ParameterSet/interface/FileInPath.h" - -#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" -#include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" - #include "RecoEgamma/EgammaTools/interface/EffectiveAreas.h" - -#include -#include +#include "CondFormats/EgammaObjects/interface/GBRForest.h" +#include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" +#include "RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h" class PhotonMVAEstimator : public AnyMVAEstimatorRun2Base{ public: - // Define here the number and the meaning of the categories - // for this specific MVA - const int nCategories_ = 2; - enum mvaCategories { - CAT_EB = 0, - CAT_EE = 1 - }; - // Constructor and destructor PhotonMVAEstimator(const edm::ParameterSet& conf); - ~PhotonMVAEstimator() override; + ~PhotonMVAEstimator() override {}; // Calculation of the MVA value - float mvaValue( const edm::Ptr& candPtr, const edm::EventBase&) const override; - - // Utility functions - std::unique_ptr createSingleReader(const int iCategory, const edm::FileInPath &weightFile); - - int getNCategories() const override { return nCategories_; } - const std::string& getName() const final { return name_; } - const std::string& getTag() const final { return tag_; } + float mvaValue( const reco::Candidate* candPtr, std::vector const& auxVars, int &iCategory) const override; - int findCategory( const edm::Ptr& candPtr ) const override; + int findCategory( const reco::Candidate* candPtr) const override; - // Call this function once after the constructor to declare - // the needed event content pieces to the framework - void setConsumes(edm::ConsumesCollector&&) const override; - - private: + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - // MVA name. This is a unique name for this MVA implementation. - // It will be used as part of ValueMap names. - // For simplicity, keep it set to the class name. - const std::string name_; + private: - // MVA tag. This is an additional string variable to distinguish - // instances of the estimator of this class configured with different - // weight files. - const std::string tag_; + int findCategory(reco::Photon const& photon) const; + // The number of categories and number of variables per category + int nCategories_; + std::vector,reco::Photon>> categoryFunctions_; std::vector nVariables_; // Data members std::vector< std::unique_ptr > gbrForests_; - // All variables needed by this MVA - const std::string methodName_; - // There might be different variables for each category, so the variables // names vector is itself a vector of length nCategories std::vector> variables_; @@ -78,10 +45,6 @@ class PhotonMVAEstimator : public AnyMVAEstimatorRun2Base{ // The variable manager which stores how to obtain the variables MVAVariableManager mvaVarMngr_; - const double ebeeSplit_; - - const bool debug_; - // Other objects needed by the MVA std::unique_ptr effectiveAreas_; std::vector phoIsoPtScalingCoeff_; diff --git a/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml b/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml index dc26d96bbc9f7..5044557c4eb77 100644 --- a/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml +++ b/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml @@ -7,6 +7,7 @@ + diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonIDSimpleAnalyzer.h b/RecoEgamma/PhotonIdentification/plugins/PhotonIDSimpleAnalyzer.h index b59d3fe5ee8a6..90954e451f3f5 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonIDSimpleAnalyzer.h +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonIDSimpleAnalyzer.h @@ -17,7 +17,7 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -34,7 +34,7 @@ class TFile; // // class declaration // -class PhotonIDSimpleAnalyzer : public edm::EDAnalyzer { +class PhotonIDSimpleAnalyzer : public edm::one::EDAnalyzer<> { public: explicit PhotonIDSimpleAnalyzer( const edm::ParameterSet& ); ~PhotonIDSimpleAnalyzer() override; diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc index 0fba9750e6535..47e24a865c756 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc @@ -1,42 +1,43 @@ #include "RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "CommonTools/MVAUtils/interface/GBRForestTools.h" -PhotonMVAEstimator::PhotonMVAEstimator(const edm::ParameterSet& conf): - AnyMVAEstimatorRun2Base(conf), - name_(conf.getParameter("mvaName")), - tag_(conf.getParameter("mvaTag")), - methodName_("BDTG method"), - mvaVarMngr_(conf.getParameter("variableDefinition")), - ebeeSplit_ (conf.getParameter ("ebeeSplit")), - debug_(conf.getUntrackedParameter("debug", false)) +PhotonMVAEstimator::PhotonMVAEstimator(const edm::ParameterSet& conf) + : AnyMVAEstimatorRun2Base(conf) + , mvaVarMngr_ (conf.getParameter("variableDefinition")) { + // // Construct the MVA estimators // - if (tag_ == "Run2Spring16NonTrigV1") { + if (getTag() == "Run2Spring16NonTrigV1") { effectiveAreas_ = std::make_unique((conf.getParameter("effAreasConfigFile")).fullPath()); phoIsoPtScalingCoeff_ = conf.getParameter>("phoIsoPtScalingCoeff"); phoIsoCutoff_ = conf.getParameter("phoIsoCutoff"); } - const std::vector weightFileNames - = conf.getParameter >("weightFileNames"); + const auto weightFileNames = conf.getParameter >("weightFileNames"); + const auto categoryCutStrings = conf.getParameter >("categoryCuts"); + + if( (int)(categoryCutStrings.size()) != getNCategories() ) + throw cms::Exception("MVA config failure: ") + << "wrong number of category cuts in PhotonMVAEstimator" << getTag() << std::endl; + + for (auto const& cut : categoryCutStrings) categoryFunctions_.emplace_back(cut); // Initialize GBRForests - if( (int)(weightFileNames.size()) != nCategories_ ) + if( static_cast(weightFileNames.size()) != getNCategories() ) throw cms::Exception("MVA config failure: ") - << "wrong number of weightfiles in " << name_ << tag_ << std::endl; + << "wrong number of weightfiles in PhotonMVAEstimator" << getTag() << std::endl; gbrForests_.clear(); // Create a TMVA reader object for each category - for(int i=0; i variableNamesInCategory; std::vector variablesInCategory; - // Use unique_ptr so that all readers are properly cleaned up - // when the vector clear() is called in the destructor - - gbrForests_.push_back( GBRForestTools::createGBRForest( weightFileNames[i], variableNamesInCategory ) ); + std::vector variableNamesInCategory; + gbrForests_.push_back(createGBRForest(weightFileNames[i], variableNamesInCategory)); nVariables_.push_back(variableNamesInCategory.size()); @@ -46,7 +47,7 @@ PhotonMVAEstimator::PhotonMVAEstimator(const edm::ParameterSet& conf): int index = mvaVarMngr_.getVarIndex(variableNamesInCategory[j]); if(index == -1) { throw cms::Exception("MVA config failure: ") - << "Concerning " << name_ << tag_ << std::endl + << "Concerning PhotonMVAEstimator" << getTag() << std::endl << "Variable " << variableNamesInCategory[j] << " not found in variable definition file!" << std::endl; } @@ -56,30 +57,26 @@ PhotonMVAEstimator::PhotonMVAEstimator(const edm::ParameterSet& conf): } } -PhotonMVAEstimator:: -~PhotonMVAEstimator(){ -} - float PhotonMVAEstimator:: -mvaValue(const edm::Ptr& candPtr, const edm::EventBase& iEvent) const { - - const int iCategory = findCategory( candPtr ); +mvaValue(const reco::Candidate* candPtr, std::vector const& auxVars, int &iCategory) const { - const edm::Ptr phoPtr{ candPtr }; - if( phoPtr.get() == nullptr) { + const reco::Photon* phoPtr = dynamic_cast(candPtr); + if( phoPtr == nullptr) { throw cms::Exception("MVA failure: ") << " given particle is expected to be reco::Photon or pat::Photon," << std::endl << " but appears to be neither" << std::endl; } + iCategory = findCategory( phoPtr ); + std::vector vars; for (int i = 0; i < nVariables_[iCategory]; ++i) { - vars.push_back(mvaVarMngr_.getValue(variables_[iCategory][i], phoPtr, iEvent)); + vars.push_back(mvaVarMngr_.getValue(variables_[iCategory][i], *phoPtr, auxVars)); } // Special case for Spring16! - if (tag_ == "Run2Spring16NonTrigV1" and iCategory == CAT_EE) { + if (getTag() == "Run2Spring16NonTrigV1" and iCategory == 1) { // Endcap category // Raw value for EB only, because of loss of transparency in EE // for endcap MVA only in 2016 double eA = effectiveAreas_->getEffectiveArea( std::abs(phoPtr->superCluster()->eta()) ); @@ -87,8 +84,8 @@ mvaValue(const edm::Ptr& candPtr, const edm::EventBase& iEvent) vars[10] = TMath::Max( phoIsoCorr, phoIsoCutoff_); } - if(debug_) { - std::cout << " *** Inside " << name_ << tag_ << std::endl; + if(isDebug()) { + std::cout << " *** Inside PhotonMVAEstimator" << getTag() << std::endl; std::cout << " category " << iCategory << std::endl; for (int i = 0; i < nVariables_[iCategory]; ++i) { std::cout << " " << mvaVarMngr_.getName(variables_[iCategory][i]) << " " << vars[i] << std::endl; @@ -97,45 +94,38 @@ mvaValue(const edm::Ptr& candPtr, const edm::EventBase& iEvent) const float response = gbrForests_.at(iCategory)->GetResponse(vars.data()); - if(debug_) { + if(isDebug()) { std::cout << " ### MVA " << response << std::endl << std::endl; } return response; } -int PhotonMVAEstimator::findCategory( const edm::Ptr& candPtr) const { - - // Try to cast the particle into a reco particle. - // This should work for both reco and pat. - auto pho = dynamic_cast(candPtr.get()); +int PhotonMVAEstimator::findCategory( const reco::Candidate* candPtr) const { - if( pho == nullptr) { + const reco::Photon* phoPtr = dynamic_cast(candPtr); + if( phoPtr == nullptr ) { throw cms::Exception("MVA failure: ") << " given particle is expected to be reco::Photon or pat::Photon," << std::endl << " but appears to be neither" << std::endl; } - float eta = pho->superCluster()->eta(); + return findCategory(*phoPtr); - // - // Determine the category - // - if ( std::abs(eta) < ebeeSplit_) - return CAT_EB; - else - return CAT_EE; } -void PhotonMVAEstimator::setConsumes(edm::ConsumesCollector&& cc) const { - // All tokens for event content needed by this MVA - // Tags from the variable helper - for (auto &tag : mvaVarMngr_.getHelperInputTags()) { - cc.consumes>(tag); - } - for (auto &tag : mvaVarMngr_.getGlobalInputTags()) { - cc.consumes(tag); +int PhotonMVAEstimator::findCategory(reco::Photon const& photon) const { + + for (int i = 0; i < getNCategories(); ++i) { + if (categoryFunctions_[i](photon)) return i; } + + edm::LogWarning ("MVA warning") << + "category not defined for particle with pt " << photon.pt() << " GeV, eta " << + photon.superCluster()->eta() << " in PhotonMVAEstimator" << getTag(); + + return -1; + } DEFINE_EDM_PLUGIN(AnyMVAEstimatorRun2Factory, diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonMVANtuplizer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonMVANtuplizer.cc index 7bc735a2ce243..268324c53f788 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonMVANtuplizer.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonMVANtuplizer.cc @@ -31,8 +31,10 @@ #include "CommonTools/UtilAlgos/interface/TFileService.h" #include "DataFormats/EgammaCandidates/interface/Photon.h" +#include "DataFormats/PatCandidates/interface/Photon.h" #include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" +#include "RecoEgamma/EgammaTools/interface/MultiToken.h" #include "SimDataFormats/PileupSummaryInfo/interface/PileupSummaryInfo.h" #include "DataFormats/VertexReco/interface/Vertex.h" @@ -46,53 +48,31 @@ // class declaration // -// If the analyzer does not use TFileService, please remove -// the template argument to the base class so the class inherits -// from edm::one::EDAnalyzer<> -// This will improve performance in multithreaded jobs. -// - class PhotonMVANtuplizer : public edm::one::EDAnalyzer { public: explicit PhotonMVANtuplizer(const edm::ParameterSet&); - ~PhotonMVANtuplizer() override; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: - void beginJob() override; void analyze(const edm::Event&, const edm::EventSetup&) override; - void endJob() override; // ----------member data --------------------------- - // for AOD case - const edm::EDGetToken src_; - const edm::EDGetToken vertices_; - const edm::EDGetToken pileup_; - - // for miniAOD case - const edm::EDGetToken srcMiniAOD_; - const edm::EDGetToken verticesMiniAOD_; - const edm::EDGetToken pileupMiniAOD_; - // other TTree* tree_; - std::vector vars_; - int nVars_; - //global variables int nEvent_, nRun_, nLumi_; int genNpu_; int vtxN_; + double pT_, eta_; - // to hold ID decisions and categories - std::vector mvaPasses_; - std::vector mvaValues_; - std::vector mvaCats_; + // photon genMatch variable + int matchedToGenPh_; + int matchedGenIdx_; // ID decisions objects const std::vector< std::string > phoMapTags_; @@ -114,108 +94,138 @@ class PhotonMVANtuplizer : public edm::one::EDAnalyzer> src_; + const MultiTokenT> vertices_; + const MultiTokenT> pileup_; + const MultiTokenT> genParticles_; + + // to hold ID decisions and categories + std::vector mvaPasses_; + std::vector mvaValues_; + std::vector mvaCats_; + + // To get the auxiliary MVA variables + const MVAVariableHelper variableHelper_; + + // To manage the variables which are parsed from the text file + MVAVariableManager mvaVarMngr_; + + const int nVars_; + std::vector vars_; }; -// -// constants, enums and typedefs -// +enum PhotonMatchType { + FAKE_PHOTON, + TRUE_PROMPT_PHOTON, + TRUE_NON_PROMPT_PHOTON, +}; -// -// static data member definitions -// +namespace { + + int matchToTruth( const reco::Photon& ph, + const edm::View& genParticles, + double deltaR) + { + // Find the closest status 1 gen photon to the reco photon + double dR = 999; + reco::GenParticle const * closestPhoton = &genParticles[0]; + for (auto & particle : genParticles) { + // Drop everything that is not photon or not status 1 + if( abs(particle.pdgId()) != 22 || particle.status() != 1 ) continue; + + double dRtmp = ROOT::Math::VectorUtil::DeltaR( ph.p4(), particle.p4() ); + if( dRtmp < dR ) { + dR = dRtmp; + closestPhoton = &particle; + } + } + // See if the closest photon (if it exists) is close enough. + // If not, no match found. + if(dR < deltaR) { + if( closestPhoton->isPromptFinalState() ) return TRUE_PROMPT_PHOTON; + else return TRUE_NON_PROMPT_PHOTON; + } + return FAKE_PHOTON; + } -// -// constructors and destructor -// +}; + +// constructor PhotonMVANtuplizer::PhotonMVANtuplizer(const edm::ParameterSet& iConfig) - : - src_ (consumes >(iConfig.getParameter("src"))), - vertices_ (consumes >(iConfig.getParameter("vertices"))), - pileup_ (consumes >(iConfig.getParameter("pileup"))), - srcMiniAOD_ (consumes >(iConfig.getParameter("srcMiniAOD"))), - verticesMiniAOD_ (consumes >(iConfig.getParameter("verticesMiniAOD"))), - pileupMiniAOD_ (consumes >(iConfig.getParameter("pileupMiniAOD"))), - phoMapTags_ (iConfig.getUntrackedParameter>("phoMVAs")), - phoMapBranchNames_ (iConfig.getUntrackedParameter>("phoMVALabels")), - nPhoMaps_ (phoMapBranchNames_.size()), - valMapTags_ (iConfig.getUntrackedParameter>("phoMVAValMaps")), - valMapBranchNames_ (iConfig.getUntrackedParameter>("phoMVAValMapLabels")), - nValMaps_ (valMapBranchNames_.size()), - mvaCatTags_ (iConfig.getUntrackedParameter>("phoMVACats")), - mvaCatBranchNames_ (iConfig.getUntrackedParameter>("phoMVACatLabels")), - nCats_ (mvaCatBranchNames_.size()), - isMC_ (iConfig.getParameter("isMC")), - ptThreshold_ (iConfig.getParameter("ptThreshold")) + : phoMapTags_ (iConfig.getUntrackedParameter>("phoMVAs")) + , phoMapBranchNames_ (iConfig.getUntrackedParameter>("phoMVALabels")) + , nPhoMaps_ (phoMapBranchNames_.size()) + , valMapTags_ (iConfig.getUntrackedParameter>("phoMVAValMaps")) + , valMapBranchNames_ (iConfig.getUntrackedParameter>("phoMVAValMapLabels")) + , nValMaps_ (valMapBranchNames_.size()) + , mvaCatTags_ (iConfig.getUntrackedParameter>("phoMVACats")) + , mvaCatBranchNames_ (iConfig.getUntrackedParameter>("phoMVACatLabels")) + , nCats_ (mvaCatBranchNames_.size()) + , isMC_ (iConfig.getParameter("isMC")) + , ptThreshold_ (iConfig.getParameter("ptThreshold")) + , deltaR_ (iConfig.getParameter("deltaR")) + , src_ (consumesCollector(), iConfig, "src" , "srcMiniAOD") + , vertices_ (src_, consumesCollector(), iConfig, "vertices", "verticesMiniAOD") + , pileup_ (src_, consumesCollector(), iConfig, "pileup" , "pileupMiniAOD") + , genParticles_ (src_, consumesCollector(), iConfig, "genParticles", "genParticlesMiniAOD") + , mvaPasses_ (nPhoMaps_) + , mvaValues_ (nValMaps_) + , mvaCats_ (nCats_) + , variableHelper_ (consumesCollector()) + , mvaVarMngr_ (iConfig.getParameter("variableDefinition")) + , nVars_ (mvaVarMngr_.getNVars()) + , vars_ (nVars_) { // phoMaps - for (size_t k = 0; k < nPhoMaps_; ++k) { - - phoMapTokens_.push_back(consumes >(edm::InputTag(phoMapTags_[k]))); - - // Initialize vectors for holding ID decisions - mvaPasses_.push_back(0); + for (auto const& tag : phoMapTags_) { + phoMapTokens_.push_back(consumes >(edm::InputTag(tag))); } - // valMaps - for (size_t k = 0; k < nValMaps_; ++k) { - valMapTokens_.push_back(consumes >(edm::InputTag(valMapTags_[k]))); - - // Initialize vectors for holding MVA values - mvaValues_.push_back(0.0); + for (auto const& tag : valMapTags_) { + valMapTokens_.push_back(consumes >(edm::InputTag(tag))); } - // categories - for (size_t k = 0; k < nCats_; ++k) { - mvaCatTokens_.push_back(consumes >(edm::InputTag(mvaCatTags_[k]))); - - // Initialize vectors for holding MVA values - mvaCats_.push_back(0); + for (auto const& tag : mvaCatTags_) { + mvaCatTokens_.push_back(consumes >(edm::InputTag(tag))); } - // Book tree - usesResource(TFileService::kSharedResource); - edm::Service fs ; - tree_ = fs->make("tree","tree"); - - tree_->Branch("nEvent", &nEvent_); - tree_->Branch("nRun", &nRun_); - tree_->Branch("nLumi", &nLumi_); - if (isMC_) tree_->Branch("genNpu", &genNpu_); - tree_->Branch("vtxN", &vtxN_); - - // Has to be in two different loops - for (int i = 0; i < nVars_; ++i) { - vars_.push_back(0.0); - } - - // IDs - for (size_t k = 0; k < nValMaps_; ++k) { - tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]); - } - - for (size_t k = 0; k < nPhoMaps_; ++k) { - tree_->Branch(phoMapBranchNames_[k].c_str() , &mvaPasses_[k]); - } - - for (size_t k = 0; k < nCats_; ++k) { - tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]); - } -} + // Book tree + usesResource(TFileService::kSharedResource); + edm::Service fs ; + tree_ = fs->make("tree","tree"); + + tree_->Branch("nEvent", &nEvent_); + tree_->Branch("nRun", &nRun_); + tree_->Branch("nLumi", &nLumi_); + if (isMC_) { + tree_->Branch("genNpu", &genNpu_); + tree_->Branch("matchedToGenPh", &matchedToGenPh_); + } + tree_->Branch("vtxN", &vtxN_); + tree_->Branch("pT", &pT_); + tree_->Branch("eta", &eta_); + for (int i = 0; i < nVars_; ++i) { + tree_->Branch(mvaVarMngr_.getName(i).c_str(), &vars_[i]); + } -PhotonMVANtuplizer::~PhotonMVANtuplizer() -{ + // IDs + for (size_t k = 0; k < nValMaps_; ++k) { + tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]); + } - // do anything here that needs to be done at desctruction time - // (e.g. close files, deallocate resources etc.) + for (size_t k = 0; k < nPhoMaps_; ++k) { + tree_->Branch(phoMapBranchNames_[k].c_str() , &mvaPasses_[k]); + } + for (size_t k = 0; k < nCats_; ++k) { + tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]); + } } - -// -// member functions -// - // ------------ method called for each event ------------ void PhotonMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) @@ -225,29 +235,14 @@ PhotonMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSe nRun_ = iEvent.id().run(); nLumi_ = iEvent.luminosityBlock(); - - // Retrieve Vertecies - edm::Handle vertices; - iEvent.getByToken(vertices_, vertices); - if( !vertices.isValid() ){ - iEvent.getByToken(verticesMiniAOD_,vertices); - if( !vertices.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD vertex collection " << std::endl; - } + // Get Handles + auto src = src_.getValidHandle(iEvent); + auto vertices = vertices_.getValidHandle(iEvent); + auto pileup = pileup_.getValidHandle(iEvent); + auto genParticles = genParticles_.getValidHandle(iEvent); vtxN_ = vertices->size(); - // Retrieve Pileup Info - edm::Handle > pileup; - iEvent.getByToken(pileup_, pileup); - if( !pileup.isValid() ){ - iEvent.getByToken(pileupMiniAOD_,pileup); - if( !pileup.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD pileup collection " << std::endl; - } - // Fill with true number of pileup if(isMC_) { for(const auto& pu : *pileup) @@ -261,19 +256,6 @@ PhotonMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSe } } - edm::Handle > src; - - // Retrieve the collection of particles from the event. - // If we fail to retrieve the collection with the standard AOD - // name, we next look for the one with the stndard miniAOD name. - iEvent.getByToken(src_, src); - if( !src.isValid() ){ - iEvent.getByToken(srcMiniAOD_,src); - if( !src.isValid() ) - throw cms::Exception(" Collection not found: ") - << " failed to find a standard AOD or miniAOD particle collection " << std::endl; - } - // Get MVA decisions edm::Handle > decisions[nPhoMaps_]; for (size_t k = 0; k < nPhoMaps_; ++k) { @@ -301,61 +283,63 @@ PhotonMVANtuplizer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSe if (pho->pt() < ptThreshold_) { continue; } + pT_ = pho->pt(); + eta_ = pho->eta(); + + // variables from the text file + for (int iVar = 0; iVar < nVars_; ++iVar) { + std::vector extraVariables = variableHelper_.getAuxVariables(pho, iEvent); + vars_[iVar] = mvaVarMngr_.getValue(iVar, *pho, extraVariables); + } + + if (isMC_) { + matchedToGenPh_ = matchToTruth( *pho, *genParticles, deltaR_); + } // // Look up and save the ID decisions // for (size_t k = 0; k < nPhoMaps_; ++k) { - mvaPasses_[k] = (int)(*decisions[k])[pho]; + mvaPasses_[k] = static_cast((*decisions[k])[pho]); } for (size_t k = 0; k < nValMaps_; ++k) { - mvaValues_[k] = (*values[k])[pho]; + mvaValues_[k] = (*values[k])[pho]; } for (size_t k = 0; k < nCats_; ++k) { mvaCats_[k] = (*mvaCats[k])[pho]; } - tree_->Fill(); } } -// ------------ method called once each job just before starting event loop ------------ -void -PhotonMVANtuplizer::beginJob() -{ -} - -// ------------ method called once each job just after ending the event loop ------------ -void -PhotonMVANtuplizer::endJob() -{ -} - // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void -PhotonMVANtuplizer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - +PhotonMVANtuplizer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) +{ edm::ParameterSetDescription desc; - desc.add("src"); - desc.add("vertices"); - desc.add("pileup"); - desc.add("srcMiniAOD"); - desc.add("verticesMiniAOD"); - desc.add("pileupMiniAOD"); - desc.addUntracked>("phoMVAs"); - desc.addUntracked>("phoMVALabels"); - desc.addUntracked>("phoMVAValMaps"); - desc.addUntracked>("phoMVAValMapLabels"); - desc.addUntracked>("phoMVACats"); - desc.addUntracked>("phoMVACatLabels"); - desc.add("isMC"); - desc.add("ptThreshold", 5.0); + desc.add("src", edm::InputTag("gedPhotons")); + desc.add("vertices", edm::InputTag("offlinePrimaryVertices")); + desc.add("pileup", edm::InputTag("addPileupInfo")); + desc.add("genParticles", edm::InputTag("genParticles")); + desc.add("srcMiniAOD", edm::InputTag("slimmedPhotons")); + desc.add("verticesMiniAOD", edm::InputTag("offlineSlimmedPrimaryVertices")); + desc.add("pileupMiniAOD", edm::InputTag("slimmedAddPileupInfo")); + desc.add("genParticlesMiniAOD", edm::InputTag("prunedGenParticles")); + desc.addUntracked>("phoMVAs", {}); + desc.addUntracked>("phoMVALabels", {}); + desc.addUntracked>("phoMVAValMaps", {}); + desc.addUntracked>("phoMVAValMapLabels", {}); + desc.addUntracked>("phoMVACats", {}); + desc.addUntracked>("phoMVACatLabels", {}); + desc.add("isMC", true); + desc.add("ptThreshold", 15.0); + desc.add("deltaR", 0.1); + desc.add("variableDefinition"); descriptions.addDefault(desc); - } //define this as a plug-in diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonRegressionValueMapProducer.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonRegressionValueMapProducer.cc deleted file mode 100644 index 25b814b123e92..0000000000000 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonRegressionValueMapProducer.cc +++ /dev/null @@ -1,262 +0,0 @@ -#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 "DataFormats/Common/interface/ValueMap.h" -#include "DataFormats/Common/interface/View.h" - -#include "DataFormats/EgammaCandidates/interface/Photon.h" -#include "DataFormats/PatCandidates/interface/Photon.h" - -#include "DataFormats/PatCandidates/interface/PackedCandidate.h" - -#include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h" - -#include -#include -#include - -namespace { - // Cluster shapes - enum reg_float_vars { k_NFloatVars = 0 }; - - enum reg_int_vars { k_NIntVars = 0 }; - - const std::vector float_var_names( { } ); - - const std::vector integer_var_names( { } ); - - inline void set_map_val( const reg_float_vars index, const float value, - std::unordered_map& map) { - map[float_var_names[index]] = value; - } - inline void set_map_val( const reg_int_vars index, const int value, - std::unordered_map& map) { - map[integer_var_names[index]] = value; - } - - template - inline void check_map(const std::unordered_map& map, unsigned exp_size) { - if( map.size() != exp_size ) { - throw cms::Exception("PhotonRegressionWeirdConfig") - << "variable map size: " << map.size() - << " not equal to expected size: " << exp_size << " !" - << " The regression variable calculation code definitely has a bug, fix it!"; - } - } - - template - inline void calculateValues(EcalClusterLazyToolsBase* tools_tocast, - const SeedType& the_seed, - std::unordered_map& float_vars, - std::unordered_map& int_vars ) { - } -} - -class PhotonRegressionValueMapProducer : public edm::stream::EDProducer<> { - - public: - - explicit PhotonRegressionValueMapProducer(const edm::ParameterSet&); - ~PhotonRegressionValueMapProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - - private: - - void produce(edm::Event&, const edm::EventSetup&) override; - - template - void writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const ; - - // The object that will compute 5x5 quantities - std::unique_ptr lazyTools; - - // for AOD case - edm::EDGetTokenT ebReducedRecHitCollection_; - edm::EDGetTokenT eeReducedRecHitCollection_; - edm::EDGetTokenT esReducedRecHitCollection_; - edm::EDGetToken src_; - - // for miniAOD case - edm::EDGetTokenT ebReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT eeReducedRecHitCollectionMiniAOD_; - edm::EDGetTokenT esReducedRecHitCollectionMiniAOD_; - edm::EDGetToken srcMiniAOD_; - - const bool use_full5x5_; -}; - -PhotonRegressionValueMapProducer::PhotonRegressionValueMapProducer(const edm::ParameterSet& iConfig) : - use_full5x5_(iConfig.getParameter("useFull5x5")) { - - // - // Declare consummables, handle both AOD and miniAOD case - // - ebReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollection")); - ebReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("ebReducedRecHitCollectionMiniAOD")); - - eeReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollection")); - eeReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("eeReducedRecHitCollectionMiniAOD")); - - esReducedRecHitCollection_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollection")); - esReducedRecHitCollectionMiniAOD_ = mayConsume(iConfig.getParameter - ("esReducedRecHitCollectionMiniAOD")); - - // reco photons are castable into pat photons, so no need to handle reco/pat seprately - src_ = mayConsume >(iConfig.getParameter("src")); - srcMiniAOD_ = mayConsume >(iConfig.getParameter("srcMiniAOD")); - - // - // Declare producibles - // - // Cluster shapes - for( const std::string& name : float_var_names ) { - produces >(name); - } - - for( const std::string& name : integer_var_names ) { - produces >(name); - } -} - -PhotonRegressionValueMapProducer::~PhotonRegressionValueMapProducer() -{} - -void PhotonRegressionValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - - using namespace edm; - - edm::Handle > src; - - bool isAOD = true; - iEvent.getByToken(src_, src); - if(!src.isValid() ){ - isAOD = false; - iEvent.getByToken(srcMiniAOD_, src); - } - - if( !src.isValid() ) { - throw cms::Exception("IllDefinedDataTier") - << "DataFormat does not contain a photon source!"; - } - - // configure lazy tools - edm::EDGetTokenT ebrh, eerh, esrh; - - if( isAOD ) { - ebrh = ebReducedRecHitCollection_; - eerh = eeReducedRecHitCollection_; - esrh = esReducedRecHitCollection_; - } else { - ebrh = ebReducedRecHitCollectionMiniAOD_; - eerh = eeReducedRecHitCollectionMiniAOD_; - esrh = esReducedRecHitCollectionMiniAOD_; - } - - if( use_full5x5_ ) { - lazyTools = std::make_unique( iEvent, iSetup, - ebrh, eerh, esrh ); - } else { - lazyTools = std::make_unique( iEvent, iSetup, - ebrh, eerh, esrh ); - } - - if( !isAOD && !src->empty() ) { - edm::Ptr test(src->ptrAt(0)); - if( test.isNull() || !test.isAvailable() ) { - throw cms::Exception("InvalidConfiguration") - <<"DataFormat is detected as miniAOD but cannot cast to pat::Photon!"; - } - } - - std::vector > float_vars(k_NFloatVars); - std::vector > int_vars(k_NIntVars); - - std::unordered_map float_vars_map; - std::unordered_map int_vars_map; - - // reco::Photon::superCluster() is virtual so we can exploit polymorphism - for (unsigned idxpho = 0; idxpho < src->size(); ++idxpho) { - const auto& iPho = src->ptrAt(idxpho); - - // - // Compute full 5x5 quantities - // - const auto& theseed = *(iPho->superCluster()->seed()); - - if( use_full5x5_ ) { - calculateValues(lazyTools.get(), - theseed, - float_vars_map, - int_vars_map); - } else { - calculateValues(lazyTools.get(), - theseed, - float_vars_map, - int_vars_map); - } - - check_map(float_vars_map, k_NFloatVars); - check_map(int_vars_map, k_NIntVars); - - for( unsigned i = 0; i < float_vars.size(); ++i ) { - float_vars[i].emplace_back(float_vars_map.at(float_var_names[i])); - } - - - for( unsigned i = 0; i < int_vars.size(); ++i ) { - int_vars[i].emplace_back(int_vars_map.at(integer_var_names[i])); - } - - } - - for( unsigned i = 0; i < float_vars.size(); ++i ) { - writeValueMap(iEvent, src, float_vars[i], float_var_names[i]); - } - - for( unsigned i = 0; i < int_vars.size(); ++i ) { - writeValueMap(iEvent, src, int_vars[i], integer_var_names[i]); - } - - lazyTools.reset(nullptr); -} - -template -void PhotonRegressionValueMapProducer::writeValueMap(edm::Event &iEvent, - const edm::Handle > & handle, - const std::vector & values, - const std::string & label) const -{ - using namespace edm; - using namespace std; - typedef ValueMap TValueMap; - - auto valMap = std::make_unique(); - typename TValueMap::Filler filler(*valMap); - filler.insert(handle, values.begin(), values.end()); - filler.fill(); - iEvent.put(std::move(valMap), label); -} - -void PhotonRegressionValueMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); -} - -DEFINE_FWK_MODULE(PhotonRegressionValueMapProducer); diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py index 266f08c520ccb..79d3317d66c6c 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1_cff.py @@ -19,13 +19,13 @@ # The working point for this MVA that is expected to have about 90% signal # efficiency in each category for photons with pt>30 GeV (somewhat lower # for lower pt photons). - {"idName" : "mvaPhoID-RunIIFall17-v1-wp90", + {"idName" : "mvaPhoID-RunIIFall17-v1-wp90", "cuts" : { "EB" : 0.27, "EE" : 0.14 }}, # The working point for this MVA that is expected to have about 90% signal # efficiency in each category for photons with pt>30 GeV (somewhat lower # for lower pt photons). - {"idName" : "mvaPhoID-RunIIFall17-v1-wp80", + {"idName" : "mvaPhoID-RunIIFall17-v1-wp80", "cuts" : { "EB" : 0.67, "EE" : 0.54 }}, ] @@ -35,14 +35,17 @@ configs = configureFullVIDMVAPhoID(mvaTag=mvaTag, variablesFile=mvaVariablesFile, weightFiles=mvaWeightFiles, - wpConfig=wpConfig) + wpConfig=wpConfig, + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts) mvaPhoID_RunIIFall17_v1_producer_config = configs["producer_config"] mvaPhoID_RunIIFall17_v1_wp90 = configs["VID_config"]["mvaPhoID-RunIIFall17-v1-wp90"] mvaPhoID_RunIIFall17_v1_wp80 = configs["VID_config"]["mvaPhoID-RunIIFall17-v1-wp80"] # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateIdMD5 # 3) update the MD5 sum strings below and uncomment the lines again. diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py index 3c063828407a8..2608516681a77 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V1p1_cff.py @@ -19,13 +19,13 @@ # The working point for this MVA that is expected to have about 90% signal # efficiency in each category for photons with pt>30 GeV (somewhat lower # for lower pt photons). - {"idName" : "mvaPhoID-RunIIFall17-v1p1-wp90", + {"idName" : "mvaPhoID-RunIIFall17-v1p1-wp90", "cuts" : { "EB" : 0.27, "EE" : 0.14 }}, # The working point for this MVA that is expected to have about 90% signal # efficiency in each category for photons with pt>30 GeV (somewhat lower # for lower pt photons). - {"idName" : "mvaPhoID-RunIIFall17-v1p1-wp80", + {"idName" : "mvaPhoID-RunIIFall17-v1p1-wp80", "cuts" : { "EB" : 0.67, "EE" : 0.54 }}, ] @@ -35,14 +35,17 @@ configs = configureFullVIDMVAPhoID(mvaTag=mvaTag, variablesFile=mvaVariablesFile, weightFiles=mvaWeightFiles, - wpConfig=wpConfig) + wpConfig=wpConfig, + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts) mvaPhoID_RunIIFall17_v1p1_producer_config = configs["producer_config"] mvaPhoID_RunIIFall17_v1p1_wp90 = configs["VID_config"]["mvaPhoID-RunIIFall17-v1p1-wp90"] mvaPhoID_RunIIFall17_v1p1_wp80 = configs["VID_config"]["mvaPhoID-RunIIFall17-v1p1-wp80"] # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateIdMD5 # 3) update the MD5 sum strings below and uncomment the lines again. diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py index adf420d87a609..31f963ffd16b5 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Fall17_94X_V2_cff.py @@ -34,7 +34,10 @@ configs = configureFullVIDMVAPhoID(mvaTag=mvaTag, variablesFile=mvaVariablesFile, weightFiles=mvaWeightFiles, - wpConfig=wpConfig) + wpConfig=wpConfig, + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts) mvaPhoID_RunIIFall17_v2_producer_config = configs["producer_config"] mvaPhoID_RunIIFall17_v2_wp90 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp90"] mvaPhoID_RunIIFall17_v2_wp80 = configs["VID_config"]["mvaPhoID-RunIIFall17-v2-wp80"] diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py index 89c195410c3bb..e8adbeb823265 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V0_cff.py @@ -32,7 +32,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -55,18 +55,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_25ns_nonTrig_V0_producer_config = cms.PSet( +mvaPhoID_Spring15_25ns_nonTrig_V0_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V0, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_25ns_nonTrig_V0_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py index 5a76e775f9da6..05e766feaf6dc 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2_cff.py @@ -10,7 +10,7 @@ # # The following MVA is derived for Spring15 MC samples for non-triggering photons. # See more documentation in this presentation: -# +# # https://indico.cern.ch/event/369241/contribution/1/attachments/1140148/1632879/egamma-Aug14-2015.pdf # @@ -33,7 +33,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -56,18 +56,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_25ns_nonTrig_V2_producer_config = cms.PSet( +mvaPhoID_Spring15_25ns_nonTrig_V2_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V2, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_25ns_nonTrig_V2_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py index b835d4f0a3283..bb861e124575b 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_25ns_nonTrig_V2p1_cff.py @@ -2,7 +2,7 @@ mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15.txt" -# This MVA ID is the same as 25ns V2 except it uses quantities embedded +# This MVA ID is the same as 25ns V2 except it uses quantities embedded # in the objects rather than value maps. # # In this file we define the locations of the MVA weights, cuts on the MVA values @@ -12,7 +12,7 @@ # # The following MVA is derived for Spring15 MC samples for non-triggering photons. # See more documentation in this presentation: -# +# # https://indico.cern.ch/event/369241/contribution/1/attachments/1140148/1632879/egamma-Aug14-2015.pdf # @@ -35,7 +35,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -58,18 +58,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_25ns_nonTrig_V2p1_producer_config = cms.PSet( +mvaPhoID_Spring15_25ns_nonTrig_V2p1_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V2p1, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_25ns_nonTrig_V2p1_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py index d47a094c245e4..6c2ed49afcc79 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V0_cff.py @@ -32,7 +32,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -55,18 +55,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_50ns_nonTrig_V0_producer_config = cms.PSet( +mvaPhoID_Spring15_50ns_nonTrig_V0_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V0, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_50ns_nonTrig_V0_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py index 381f20bd179ff..71d5a057f90f3 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V1_cff.py @@ -32,7 +32,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -55,18 +55,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_50ns_nonTrig_V1_producer_config = cms.PSet( +mvaPhoID_Spring15_50ns_nonTrig_V1_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V1, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_50ns_nonTrig_V1_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py index 9c8cd6854d9b9..0dbace35d5cfd 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2_cff.py @@ -34,7 +34,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -57,18 +57,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_50ns_nonTrig_V2_producer_config = cms.PSet( +mvaPhoID_Spring15_50ns_nonTrig_V2_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V2, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_50ns_nonTrig_V2_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py index 577de6e0de238..1420960d7b678 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring15_50ns_nonTrig_V2p1_cff.py @@ -2,7 +2,7 @@ mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesSpring15.txt" -# This MVA ID is the same as 50ns V2 except it uses quantities embedded +# This MVA ID is the same as 50ns V2 except it uses quantities embedded # in the objects rather than value maps. # # In this file we define the locations of the MVA weights, cuts on the MVA values @@ -36,7 +36,7 @@ # The locatoins of value maps with the actual MVA values and categories # for all particles. -# The names for the maps are ":Values" +# The names for the maps are ":Values" # and ":Categories" mvaProducerModuleLabel = "photonMVAValueMapProducer" mvaValueMapName = mvaProducerModuleLabel + ":" + mvaSpring15NonTrigClassName + mvaTag + "Values" @@ -59,18 +59,21 @@ # # Create the PSet that will be fed to the MVA value map producer -mvaPhoID_Spring15_50ns_nonTrig_V2p1_producer_config = cms.PSet( +mvaPhoID_Spring15_50ns_nonTrig_V2p1_producer_config = cms.PSet( mvaName = cms.string(mvaSpring15NonTrigClassName), mvaTag = cms.string(mvaTag), weightFileNames = mvaSpring15NonTrigWeightFiles_V2p1, - variableDefinition = cms.string(mvaVariablesFile) + variableDefinition = cms.string(mvaVariablesFile), + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts ) # Create the VPset's for VID cuts mvaPhoID_Spring15_50ns_nonTrig_V2p1_wp90 = configureVIDMVAPhoID_V1( MVA_WP90 ) # The MD5 sum numbers below reflect the exact set of cut variables -# and values above. If anything changes, one has to -# 1) comment out the lines below about the registry, +# and values above. If anything changes, one has to +# 1) comment out the lines below about the registry, # 2) run "calculateMD5 # 3) update the MD5 sum strings below and uncomment the lines again. # diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py index 2f4b29b7d38cf..d8540a92cbe8a 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_Spring16_nonTrig_V1_cff.py @@ -38,6 +38,9 @@ variablesFile=mvaVariablesFile, weightFiles=mvaWeightFiles, wpConfig=wpConfig, + # Category parameters + nCategories = cms.int32(2), + categoryCuts = category_cuts, # In this MVA for endcap the corrected photon isolation is defined as # iso = max( photon_isolation_raw - rho*effArea - coeff*pt, cutoff) # as discussed in the indico presentations listed in the beginning of this file. diff --git a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py index fdf395761c9dc..a0585b82ace70 100644 --- a/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py +++ b/RecoEgamma/PhotonIdentification/python/Identification/mvaPhotonID_tools.py @@ -6,6 +6,11 @@ # division between barrel and endcap ebeeSplit = 1.479 +# categories +category_cuts = cms.vstring( + "abs(superCluster.eta) < 1.479", + "abs(superCluster.eta) >= 1.479", + ) # This MVA implementation class name mvaClassName = "PhotonMVAEstimator" @@ -96,7 +101,6 @@ def configureFullVIDMVAPhoID(mvaTag, variablesFile, weightFiles, wpConfig, **add mvaTag = cms.string(mvaTag), weightFileNames = cms.vstring(*weightFiles), variableDefinition = cms.string(variablesFile), - ebeeSplit = cms.double(ebeeSplit), **addKwargsForValueProducer ) diff --git a/RecoEgamma/PhotonIdentification/python/PhotonRegressionValueMapProducer_cfi.py b/RecoEgamma/PhotonIdentification/python/PhotonRegressionValueMapProducer_cfi.py deleted file mode 100644 index d741db108d5a6..0000000000000 --- a/RecoEgamma/PhotonIdentification/python/PhotonRegressionValueMapProducer_cfi.py +++ /dev/null @@ -1,22 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -photonRegressionValueMapProducer = cms.EDProducer('PhotonRegressionValueMapProducer', - #presently the photon regressions use the fraction-ized (PF clustering) shower shapes - useFull5x5 = cms.bool(False), - # The module automatically detects AOD vs miniAOD, so we configure both - # - # AOD case - # - ebReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEB"), - eeReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsEE"), - esReducedRecHitCollection = cms.InputTag("reducedEcalRecHitsES"), - src = cms.InputTag('gedPhotons'), - # - # miniAOD case - # - ebReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEBRecHits"), - eeReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedEERecHits"), - esReducedRecHitCollectionMiniAOD = cms.InputTag("reducedEgamma:reducedESRecHits"), - srcMiniAOD = cms.InputTag('slimmedPhotons', - processName=cms.InputTag.skipCurrentProcess()), - ) diff --git a/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py b/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py index 26f3b0afec97e..3ccca8493ed2d 100644 --- a/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py +++ b/RecoEgamma/PhotonIdentification/python/egmPhotonIDs_cff.py @@ -12,7 +12,6 @@ def loadEgmIdSequence(process, dataFormat): # Load the producer for MVA IDs. Make sure it is also added to the sequence! process.load("RecoEgamma.PhotonIdentification.PhotonMVAValueMapProducer_cfi") - process.load("RecoEgamma.PhotonIdentification.PhotonRegressionValueMapProducer_cfi") # Load tasks for isolations computed with CITK for both AOD and miniAOD cases process.egmPhotonIDTask = cms.Task() @@ -37,6 +36,5 @@ def loadEgmIdSequence(process, dataFormat): # Add everything else other then isolation process.egmPhotonIDTask.add(process.photonIDValueMapProducer, process.photonMVAValueMapProducer, - process.egmPhotonIDs, - process.photonRegressionValueMapProducer) + process.egmPhotonIDs) process.egmPhotonIDSequence = cms.Sequence(process.egmPhotonIDTask) diff --git a/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py b/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py index d0d0f7aaa493c..dafe8e2ebd74d 100644 --- a/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py +++ b/RecoEgamma/PhotonIdentification/test/testPhotonMVA_cfg.py @@ -4,20 +4,22 @@ process = cms.Process("PhotonMVANtuplizer") -process.load("FWCore.MessageService.MessageLogger_cfi") -process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") - -process.load("Configuration.StandardSequences.GeometryRecoDB_cff") +process.load("Configuration.StandardSequences.GeometryDB_cff") +process.load("Configuration.StandardSequences.MagneticField_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_condDBv2_cff") process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_mc', '') -outputFile = "photon_validation_ntuple.root" +# File with the ID variables form the text file to include in the Ntuplizer +mvaVariablesFile = "RecoEgamma/PhotonIdentification/data/PhotonMVAEstimatorRun2VariablesFall17V1p1.txt" + +outputFile = "photon_ntuple.root" -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1000) ) process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( - '/store/mc/RunIIFall17MiniAOD/DYJetsToLL_M-50_TuneCP5_13TeV-madgraphMLM-pythia8/MINIAODSIM/RECOSIMstep_94X_mc2017_realistic_v10-v1/00000/0293A280-B5F3-E711-8303-3417EBE33927.root' + '/store/mc/RunIIFall17MiniAODv2/GJet_Pt-20to40_DoubleEMEnriched_MGG-80toInf_TuneCP5_13TeV_Pythia8/MINIAODSIM/PU2017_12Apr2018_94X_mc2017_realistic_v14-v1/00000/00AE0E2A-6F42-E811-8EA2-0025905B85AA.root' ) ) @@ -46,18 +48,9 @@ setupAllVIDIdsInModule(process,idmod,setupVIDPhotonSelection) process.ntuplizer = cms.EDAnalyzer('PhotonMVANtuplizer', - # AOD case - src = cms.InputTag('gedPhotons'), - vertices = cms.InputTag('offlinePrimaryVertices'), - pileup = cms.InputTag('addPileupInfo'), - # miniAOD case - srcMiniAOD = cms.InputTag('slimmedPhotons'), - verticesMiniAOD = cms.InputTag('offlineSlimmedPrimaryVertices'), - pileupMiniAOD = cms.InputTag('slimmedAddPileupInfo'), - # - phoMVAs = cms.untracked.vstring( + phoMVAs = cms.untracked.vstring( ), - phoMVALabels = cms.untracked.vstring( + phoMVALabels = cms.untracked.vstring( ), phoMVAValMaps = cms.untracked.vstring( "photonMVAValueMapProducer:PhotonMVAEstimatorRun2Spring16NonTrigV1Values", @@ -77,7 +70,7 @@ phoMVACatLabels = cms.untracked.vstring( "PhoMVACats", ), - isMC = cms.bool(True), + variableDefinition = cms.string(mvaVariablesFile), ) process.TFileService = cms.Service("TFileService", From 38f3ee4aa0d6cab99e49a198a5367af3c6d456a7 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 5 Dec 2018 19:30:50 +0100 Subject: [PATCH 12/12] Undid some part of the sync with 10_4_X --- .../EgammaTools/interface/GBRForestTools.h | 39 +++++ .../plugins/EGRegressionModifierV2.cc | 5 +- .../python/hgcalElectronIDValueMap_cff.py | 4 +- .../python/hgcalPhotonIDValueMap_cff.py | 4 +- .../EgammaTools/src/EcalRegressionData.cc | 3 +- RecoEgamma/EgammaTools/src/GBRForestTools.cc | 151 ++++++++++++++++++ .../src/SCEnergyCorrectorSemiParm.cc | 3 +- .../ElectronIdentification/BuildFile.xml | 1 - .../interface/ElectronMVAEstimatorRun2.h | 2 +- .../src/ElectronMVAEstimator.cc | 6 +- .../src/ElectronMVAEstimatorRun2.cc | 2 +- .../src/SoftElectronMVAEstimator.cc | 4 +- .../plugins/BuildFile.xml | 1 - .../plugins/PhotonMVAEstimator.cc | 2 +- 14 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 RecoEgamma/EgammaTools/interface/GBRForestTools.h create mode 100644 RecoEgamma/EgammaTools/src/GBRForestTools.cc diff --git a/RecoEgamma/EgammaTools/interface/GBRForestTools.h b/RecoEgamma/EgammaTools/interface/GBRForestTools.h new file mode 100644 index 0000000000000..c72812070a2ea --- /dev/null +++ b/RecoEgamma/EgammaTools/interface/GBRForestTools.h @@ -0,0 +1,39 @@ +//-------------------------------------------------------------------------------------------------- +// +// GRBForestTools +// +// Utility to read a TMVA weights file with a BDT into a GRBForest. +// +// Author: Jonas Rembser +//-------------------------------------------------------------------------------------------------- + + +#ifndef RecoEgamma_EgammaTools_GBRForestTools_h +#define RecoEgamma_EgammaTools_GBRForestTools_h + +#include +#include + +#include "CondFormats/EgammaObjects/interface/GBRForest.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" + +#include "TMVA/MethodBDT.h" +#include "TMVA/Reader.h" + +#include "CommonTools/Utils/interface/TMVAZipReader.h" + +class GBRForestTools +{ + public: + GBRForestTools() {} + + static std::unique_ptr createGBRForest(const std::string &weightFile); + static std::unique_ptr createGBRForest(const edm::FileInPath &weightFile); + + // Overloaded versions which are taking string vectors by reference to strore the variable names in + static std::unique_ptr createGBRForest(const std::string &weightFile, std::vector &varNames); + static std::unique_ptr createGBRForest(const edm::FileInPath &weightFile, std::vector &varNames); + +}; + +#endif diff --git a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc index afa8014e21c50..c0cc834ce04aa 100644 --- a/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc +++ b/RecoEgamma/EgammaTools/plugins/EGRegressionModifierV2.cc @@ -11,7 +11,6 @@ #include "CondFormats/DataRecord/interface/GBRDWrapperRcd.h" #include "CondFormats/EgammaObjects/interface/GBRForestD.h" #include "RecoEgamma/EgammaTools/interface/EcalClusterLocal.h" -#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include @@ -362,7 +361,7 @@ void EGRegressionModifierV2::modifyObject(reco::GsfElectron& ele) const { const edm::Ptr& theseed = the_sc->seed(); // skip HGCAL for now - if( EcalTools::isHGCalDet(theseed->seed().det()) ) return; + if( theseed->seed().det() == DetId::Forward ) return; const int numberOfClusters = the_sc->clusters().size(); const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable(); @@ -562,7 +561,7 @@ void EGRegressionModifierV2::modifyObject(reco::Photon& pho) const { const edm::Ptr& theseed = the_sc->seed(); // skip HGCAL for now - if( EcalTools::isHGCalDet(theseed->seed().det()) ) return; + if( theseed->seed().det() == DetId::Forward ) return; const int numberOfClusters = the_sc->clusters().size(); const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable(); diff --git a/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py b/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py index bb5db38ad3ceb..dd4da071e2d2f 100644 --- a/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py +++ b/RecoEgamma/EgammaTools/python/hgcalElectronIDValueMap_cff.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX +from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX_weights # cfi from HGCalElectronIDValueMapProducer::fillDescriptions() from RecoEgamma.EgammaTools.hgcalElectronIDValueMap_cfi import * -hgcalElectronIDValueMap.dEdXWeights = dEdX.weights +hgcalElectronIDValueMap.dEdXWeights = dEdX_weights diff --git a/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py b/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py index f3c18e35f0278..dbefc5da6757d 100644 --- a/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py +++ b/RecoEgamma/EgammaTools/python/hgcalPhotonIDValueMap_cff.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX +from RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi import dEdX_weights # cfi from HGCalPhotonIDValueMapProducer::fillDescriptions() from RecoEgamma.EgammaTools.hgcalPhotonIDValueMap_cfi import * -hgcalPhotonIDValueMap.dEdXWeights = dEdX.weights +hgcalPhotonIDValueMap.dEdXWeights = dEdX_weights diff --git a/RecoEgamma/EgammaTools/src/EcalRegressionData.cc b/RecoEgamma/EgammaTools/src/EcalRegressionData.cc index b4c6dd339e7a0..17f2b69a81cf0 100644 --- a/RecoEgamma/EgammaTools/src/EcalRegressionData.cc +++ b/RecoEgamma/EgammaTools/src/EcalRegressionData.cc @@ -1,6 +1,5 @@ #include "RecoEgamma/EgammaTools/interface/EcalRegressionData.h" -#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h" #include "DataFormats/Math/interface/deltaR.h" #include "Geometry/CaloTopology/interface/CaloTopology.h" @@ -56,7 +55,7 @@ void EcalRegressionData::fill(const reco::SuperCluster& superClus, isEB_ = ( seedid.subdetId()==EcalBarrel ); // skip HGCal - if( EcalTools::isHGCalDet(seedid.det()) ) return; + if( seedid.det() == DetId::Forward ) return; const EcalRecHitCollection* recHits = isEB_ ? ebRecHits : eeRecHits; diff --git a/RecoEgamma/EgammaTools/src/GBRForestTools.cc b/RecoEgamma/EgammaTools/src/GBRForestTools.cc new file mode 100644 index 0000000000000..cdcd42646924a --- /dev/null +++ b/RecoEgamma/EgammaTools/src/GBRForestTools.cc @@ -0,0 +1,151 @@ +#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" + +#include +#include + +namespace { + + // Will return position of n-th occurence of a char in a string. + int strpos(const std::string &haystack, char needle, unsigned int nth) + { + int found = 0; + for (unsigned int i=0 ; i GBRForestTools::createGBRForest(const std::string &weightFile, + std::vector &varNames){ + edm::FileInPath weightFileEdm(weightFile); + return GBRForestTools::createGBRForest(weightFileEdm, varNames); +} + +// Creates a pointer to new GBRForest corresponding to a TMVA weights file +std::unique_ptr GBRForestTools::createGBRForest(const edm::FileInPath &weightFile, + std::vector &varNames){ + + std::string method; + + unsigned int NVar = 0; + unsigned int NSpec = 0; + + std::vector dumbVars; + std::vector dumbSpecs; + + varNames.clear(); + std::vector specNames; + + std::string line; + std::ifstream f; + std::string tmpstr; + + bool gzipped = false; + + // + // Set up the input buffers, for gzipped or raw xml file + // + if (reco::details::hasEnding(weightFile.fullPath(), ".xml")) { + f.open(weightFile.fullPath()); + tmpstr = ""; + } else if (reco::details::hasEnding(weightFile.fullPath(), ".gz") || reco::details::hasEnding(weightFile.fullPath(), ".gzip")) { + gzipped = true; + char *buffer = reco::details::readGzipFile(weightFile.fullPath()); + tmpstr = std::string(buffer); + free(buffer); + } + std::stringstream is(tmpstr); + + bool isend; + + while(true) { + + if (gzipped) isend = !std::getline(is, line); + else isend = !std::getline(f, line); + + if (isend) break; + + // Terminate reading of weights file + if (line.find("AddVariable(varNames[i], &dumbVars[i]); + } + + for(size_t i = 0; i < NSpec; ++i){ + mvaReader->AddSpectator(specNames[i], &dumbSpecs[i]); + } + + // + // Book the method and set up the weights file + // + + reco::details::loadTMVAWeights(mvaReader, method, weightFile.fullPath()); + + TMVA::MethodBDT* bdt = dynamic_cast( mvaReader->FindMVA(method) ); + std::unique_ptr gbrForest = std::make_unique(GBRForest(bdt)); + delete mvaReader; + + return gbrForest; +} + +std::unique_ptr GBRForestTools::createGBRForest(const std::string &weightFile){ + std::vector varNames; + return GBRForestTools::createGBRForest(weightFile, varNames); +} + +std::unique_ptr GBRForestTools::createGBRForest(const edm::FileInPath &weightFile){ + std::vector varNames; + return GBRForestTools::createGBRForest(weightFile, varNames); +} diff --git a/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc b/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc index ecec2d51f3df9..aaf24dcb139ce 100644 --- a/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc +++ b/RecoEgamma/EgammaTools/src/SCEnergyCorrectorSemiParm.cc @@ -4,7 +4,6 @@ #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h" #include "DataFormats/EcalDetId/interface/EcalSubdetector.h" #include "DataFormats/VertexReco/interface/Vertex.h" -#include "RecoEcal/EgammaCoreTools/interface/EcalTools.h" #include "FWCore/Utilities/interface/isFinite.h" #include "DataFormats/Math/interface/deltaPhi.h" @@ -104,7 +103,7 @@ std::pair SCEnergyCorrectorSemiParm::getCorrections(const reco:: p.second=-1; // protect against HGCal, don't mod the object - if( EcalTools::isHGCalDet(sc.seed()->seed().det()) ) return p; + if( sc.seed()->seed().det() == DetId::Forward ) return p; const reco::CaloCluster &seedCluster = *(sc.seed()); const bool iseb = seedCluster.hitsAndFractions()[0].first.subdetId() == EcalBarrel; diff --git a/RecoEgamma/ElectronIdentification/BuildFile.xml b/RecoEgamma/ElectronIdentification/BuildFile.xml index 289dfc278b9cb..f7589cf2db2d7 100644 --- a/RecoEgamma/ElectronIdentification/BuildFile.xml +++ b/RecoEgamma/ElectronIdentification/BuildFile.xml @@ -4,7 +4,6 @@ - diff --git a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h index 43a845a3ee0b1..bd0c598328cae 100644 --- a/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h +++ b/RecoEgamma/ElectronIdentification/interface/ElectronMVAEstimatorRun2.h @@ -3,7 +3,7 @@ #include "DataFormats/PatCandidates/interface/Electron.h" #include "RecoEgamma/EgammaTools/interface/AnyMVAEstimatorRun2Base.h" -#include "CommonTools/MVAUtils/interface/GBRForestTools.h" +#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" #include "RecoEgamma/EgammaTools/interface/MVAVariableManager.h" #include "RecoEgamma/EgammaTools/interface/ThreadSafeStringCut.h" diff --git a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc index 2cfaafb7ef422..2c5fbef1ca6e1 100644 --- a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc +++ b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimator.cc @@ -3,7 +3,7 @@ #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h" -#include "CommonTools/MVAUtils/interface/GBRForestTools.h" +#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" ElectronMVAEstimator::ElectronMVAEstimator(): cfg_{} @@ -15,13 +15,13 @@ ElectronMVAEstimator::ElectronMVAEstimator(const std::string& fileName): // Taken from Daniele (his mail from the 30/11) // tmvaReader.BookMVA("BDTSimpleCat","../Training/weights_Root527b_3Depth_DanVarConvRej_2PtBins_10Pt_800TPrune5_Min100Events_NoBjets_half/TMVA_BDTSimpleCat.weights.xm"); // training of the 7/12 with Nvtx added - gbr_.push_back( createGBRForest(fileName) ); + gbr_.push_back( GBRForestTools::createGBRForest(fileName) ); } ElectronMVAEstimator::ElectronMVAEstimator(const Configuration & cfg):cfg_(cfg) { for(const auto& weightsfile : cfg_.vweightsfiles) { - gbr_.push_back( createGBRForest(weightsfile) ); + gbr_.push_back( GBRForestTools::createGBRForest(weightsfile) ); } } diff --git a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc index 82a357d7254ff..2acd48b8efe22 100644 --- a/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc +++ b/RecoEgamma/ElectronIdentification/src/ElectronMVAEstimatorRun2.cc @@ -60,7 +60,7 @@ void ElectronMVAEstimatorRun2::init(const std::vector &weightFileNa // when the vector clear() is called in the destructor std::vector variableNamesInCategory; - gbrForests_.push_back(createGBRForest(weightFileNames[i], variableNamesInCategory)); + gbrForests_.push_back(GBRForestTools::createGBRForest(weightFileNames[i], variableNamesInCategory)); nVariables_.push_back(variableNamesInCategory.size()); diff --git a/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc b/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc index 935b4b0048392..144f15dcd07b0 100644 --- a/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc +++ b/RecoEgamma/ElectronIdentification/src/SoftElectronMVAEstimator.cc @@ -3,7 +3,7 @@ #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h" -#include "CommonTools/MVAUtils/interface/GBRForestTools.h" +#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" SoftElectronMVAEstimator::SoftElectronMVAEstimator(const Configuration & cfg):cfg_(cfg) { @@ -18,7 +18,7 @@ SoftElectronMVAEstimator::SoftElectronMVAEstimator(const Configuration & cfg):cf for(auto& weightsfile : cfg_.vweightsfiles) { // Taken from Daniele (his mail from the 30/11) // training of the 7/12 with Nvtx added - gbr_.push_back(createGBRForest( weightsfile )); + gbr_.push_back(GBRForestTools::createGBRForest( weightsfile )); } } diff --git a/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml b/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml index 5044557c4eb77..dc26d96bbc9f7 100644 --- a/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml +++ b/RecoEgamma/PhotonIdentification/plugins/BuildFile.xml @@ -7,7 +7,6 @@ - diff --git a/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc b/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc index 47e24a865c756..27b94cbd59275 100644 --- a/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc +++ b/RecoEgamma/PhotonIdentification/plugins/PhotonMVAEstimator.cc @@ -1,6 +1,6 @@ #include "RecoEgamma/PhotonIdentification/interface/PhotonMVAEstimator.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "CommonTools/MVAUtils/interface/GBRForestTools.h" +#include "RecoEgamma/EgammaTools/interface/GBRForestTools.h" PhotonMVAEstimator::PhotonMVAEstimator(const edm::ParameterSet& conf) : AnyMVAEstimatorRun2Base(conf)