Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DeepMET into NanoAOD #30291

Merged
merged 6 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions PhysicsTools/NanoAOD/python/met_cff.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,32 @@
),
)

deepMetResolutionTuneTable = cms.EDProducer("SimpleCandidateFlatTableProducer",
# current deepMets are saved in slimmedMETs in MiniAOD,
# in the same way as chsMet/TkMET
src = metTable.src,
name = cms.string("DeepMETResolutionTune"),
doc = cms.string("Deep MET trained with resolution tune"),
singleton = cms.bool(True), # there's always exactly one MET per event
extension = cms.bool(False), # this is the main table for the MET
variables = cms.PSet(#NOTA BENE: we don't copy PTVars here!
pt = Var("corPt('RawDeepResolutionTune')", float, doc="raw DeepResolutionTune pt"),
phi = Var("corPhi('RawDeepResolutionTune')", float, doc="raw DeepResolutionTune phi"),
),
)

deepMetResponseTuneTable = cms.EDProducer("SimpleCandidateFlatTableProducer",
src = metTable.src,
name = cms.string("DeepMETResponseTune"),
doc = cms.string("Deep MET trained with extra response tune"),
singleton = cms.bool(True), # there's always exactly one MET per event
extension = cms.bool(False), # this is the main table for the MET
variables = cms.PSet(#NOTA BENE: we don't copy PTVars here!
pt = Var("corPt('RawDeepResponseTune')", float, doc="raw DeepResponseTune pt"),
phi = Var("corPhi('RawDeepResponseTune')", float, doc="raw DeepResponseTune phi"),
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to ad variable like sumET and uncertainties ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently sumEt is not calculated in the DeepMETProducer, and it is not needed in past studies we did. If it is needed for other people, we can included this, but it requires the updates in DeepMETProducer as well. For the uncertainties, it is a bit different from pfMET and PuppiMET since we don't have 'DeepJets' clustered with the same weights here. Our approach is to define the DeepMET uncertainties from the calibration process, and calculate it at the analysis level.

For the phi var, maybe it's better to change the precision to 12, to be consistent with the phis in PF and Puppi MET and save a little bit space?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point about the precision. you can reduce the precision for both pt and phi. go ahead.

)

metFixEE2017Table = metTable.clone()
metFixEE2017Table.src = cms.InputTag("slimmedMETsFixEE2017")
metFixEE2017Table.name = cms.string("METFixEE2017")
Expand All @@ -127,6 +153,7 @@


metTables = cms.Sequence( metTable + rawMetTable + caloMetTable + puppiMetTable + rawPuppiMetTable+ tkMetTable + chsMetTable)
deepMetTables = cms.Sequence( deepMetResolutionTuneTable + deepMetResponseTuneTable )
_withFixEE2017_sequence = cms.Sequence(metTables.copy() + metFixEE2017Table)
for modifier in run2_nanoAOD_94XMiniAODv1, run2_nanoAOD_94XMiniAODv2:
modifier.toReplaceWith(metTables,_withFixEE2017_sequence) # only in old miniAOD, the new ones will come from the UL rereco
Expand Down
14 changes: 14 additions & 0 deletions PhysicsTools/NanoAOD/python/nanoDQM_cfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@
Plot1D('rawPt', 'rawPt', 20, 5, 25, "pt()*jecFactor('Uncorrected')"),
)
),
DeepMETResolutionTune = cms.PSet(
sels = cms.PSet(),
plots = cms.VPSet(
Plot1D('phi', 'phi', 20, -3.14159, 3.14159, 'Deep MET Resolution Tune phi'),
Plot1D('pt', 'pt', 20, 0, 400, 'Deep MET Response Tune pt'),
)
),
DeepMETResponseTune = cms.PSet(
sels = cms.PSet(),
plots = cms.VPSet(
Plot1D('phi', 'phi', 20, -3.14159, 3.14159, 'Deep MET Response Tune phi'),
Plot1D('pt', 'pt', 20, 0, 400, 'Deep MET Response Tune pt'),
)
),
Electron = cms.PSet(
sels = cms.PSet(
Good = cms.string('pt > 15 && abs(dxy) < 0.2 && abs(dz) < 0.5 && cutBased >= 3 && miniPFRelIso_all < 0.4')
Expand Down
33 changes: 32 additions & 1 deletion PhysicsTools/NanoAOD/python/nano_cff.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,41 @@ def nanoAOD_addDeepInfo(process,addDeepBTag,addDeepFlavour):
process.updatedJets.jetSource="selectedUpdatedPatJetsWithDeepInfo"
return process

def nanoAOD_addDeepMET(process, addDeepMETProducer, ResponseTune_Graph):
if addDeepMETProducer:
# produce DeepMET on the fly if it is not in MiniAOD
print("add DeepMET Producers")
process.load('RecoMET.METPUSubtraction.deepMETProducer_cfi')
process.deepMETsResolutionTune = process.deepMETProducer.clone()
process.deepMETsResponseTune = process.deepMETProducer.clone()
#process.deepMETsResponseTune.graph_path = 'RecoMET/METPUSubtraction/data/deepmet/deepmet_resp_v1_2018.pb'
process.deepMETsResponseTune.graph_path = ResponseTune_Graph.value()
process.metTables += process.deepMetTables
return process

from PhysicsTools.PatUtils.tools.runMETCorrectionsAndUncertainties import runMetCorAndUncFromMiniAOD
#from PhysicsTools.PatAlgos.slimming.puppiForMET_cff import makePuppiesFromMiniAOD
def nanoAOD_recalibrateMETs(process,isData):
runMetCorAndUncFromMiniAOD(process,isData=isData)
# add DeepMETs
nanoAOD_DeepMET_switch = cms.PSet(
nanoAOD_addDeepMET_switch = cms.untracked.bool(True), # decide if DeeMET should be included in Nano
nanoAOD_produceDeepMET_switch = cms.untracked.bool(False), # decide if DeepMET should be computed on the fly
ResponseTune_Graph = cms.untracked.string('RecoMET/METPUSubtraction/data/deepmet/deepmet_resp_v1_2018.pb')
)
for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016, run2_nanoAOD_94XMiniAODv1, run2_nanoAOD_94XMiniAODv2, run2_nanoAOD_102Xv1, run2_nanoAOD_106Xv1:
# compute DeepMETs in these eras (before 111X)
modifier.toModify(nanoAOD_DeepMET_switch, nanoAOD_produceDeepMET_switch = cms.untracked.bool(True))
for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
modifier.toModify(nanoAOD_DeepMET_switch, ResponseTune_Graph=cms.untracked.string("RecoMET/METPUSubtraction/data/deepmet/deepmet_resp_v1_2016.pb"))
if nanoAOD_DeepMET_switch.nanoAOD_addDeepMET_switch:
process = nanoAOD_addDeepMET(process,
addDeepMETProducer=nanoAOD_DeepMET_switch.nanoAOD_produceDeepMET_switch,
ResponseTune_Graph=nanoAOD_DeepMET_switch.ResponseTune_Graph)

# if included in Nano, and not computed in the fly, then it should be extracted from minAOD
extractDeepMETs = nanoAOD_DeepMET_switch.nanoAOD_addDeepMET_switch and not nanoAOD_DeepMET_switch.nanoAOD_produceDeepMET_switch

runMetCorAndUncFromMiniAOD(process,isData=isData, extractDeepMETs=extractDeepMETs)
process.nanoSequenceCommon.insert(process.nanoSequenceCommon.index(process.jetSequence),cms.Sequence(process.fullPatMetSequence))
process.basicJetsForMetForT1METNano = process.basicJetsForMet.clone(
src = process.updatedJetsWithUserData.src,
Expand Down
4 changes: 4 additions & 0 deletions PhysicsTools/PatAlgos/plugins/RecoMETExtractor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ RecoMETExtractor::RecoMETExtractor(const edm::ParameterSet& iConfig) {
corLevel_ = pat::MET::Type01SmearXY;
} else if (corLevel == "rawCalo") {
corLevel_ = pat::MET::RawCalo;
} else if (corLevel == "rawDeepResponseTune") {
corLevel_ = pat::MET::RawDeepResponseTune;
} else if (corLevel == "rawDeepResolutionTune") {
corLevel_ = pat::MET::RawDeepResolutionTune;
} else {
//throw exception
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def __init__(self):
"Exclude jets and PF candidates with EE noise characteristics (fix for 2017 run)", Type=bool)
self.addParameter(self._defaultParameters,'fixEE2017Params', {'userawPt': True, 'ptThreshold': 50.0, 'minEtaThreshold': 2.65, 'maxEtaThreshold': 3.139},
"Parameters dict for fixEE2017: userawPt, ptThreshold, minEtaThreshold, maxEtaThreshold", Type=dict)
self.addParameter(self._defaultParameters, 'extractDeepMETs', False,
"Extract DeepMETs from miniAOD, instead of recomputing them.", Type=bool)

#private parameters
self.addParameter(self._defaultParameters, 'Puppi', False,
Expand Down Expand Up @@ -136,6 +138,7 @@ def __call__(self, process,
onMiniAOD =None,
fixEE2017 =None,
fixEE2017Params =None,
extractDeepMETs =None,
postfix =None):
electronCollection = self.initializeInputTag(electronCollection, 'electronCollection')
photonCollection = self.initializeInputTag(photonCollection, 'photonCollection')
Expand Down Expand Up @@ -209,6 +212,8 @@ def __call__(self, process,
fixEE2017 = self._defaultParameters['fixEE2017'].value
if fixEE2017Params is None :
fixEE2017Params = self._defaultParameters['fixEE2017Params'].value
if extractDeepMETs is None :
extractDeepMETs = self._defaultParameters['extractDeepMETs'].value

self.setParameter('metType',metType),
self.setParameter('correctionLevel',correctionLevel),
Expand Down Expand Up @@ -242,6 +247,7 @@ def __call__(self, process,
self.setParameter('postfix',postfix),
self.setParameter('fixEE2017',fixEE2017),
self.setParameter('fixEE2017Params',fixEE2017Params),
self.setParameter('extractDeepMETs',extractDeepMETs),

#if mva/puppi MET, autoswitch to std jets
if metType == "MVA" or metType == "Puppi":
Expand Down Expand Up @@ -305,6 +311,7 @@ def toolCode(self, process):
postfix = self._parameters['postfix'].value
fixEE2017 = self._parameters['fixEE2017'].value
fixEE2017Params = self._parameters['fixEE2017Params'].value
extractDeepMETs = self._parameters['extractDeepMETs'].value

#prepare jet configuration
jetUncInfos = { "jCorrPayload":jetFlavor, "jCorLabelUpToL3":jetCorLabelUpToL3,
Expand Down Expand Up @@ -464,6 +471,11 @@ def toolCode(self, process):
#adding the slimmed MET
if hasattr(process, "patCaloMet"):
fullPatMetSequence +=getattr(process, "patCaloMet")
# include deepMETsResolutionTune and deepMETsResponseTune into fullPatMetSequence
if hasattr(process, "deepMETsResolutionTune"):
fullPatMetSequence +=getattr(process, "deepMETsResolutionTune")
if hasattr(process, "deepMETsResponseTune"):
fullPatMetSequence += getattr(process, "deepMETsResponseTune")
if hasattr(process, "slimmedMETs"+postfix):
fullPatMetSequence +=getattr(process, "slimmedMETs"+postfix)

Expand Down Expand Up @@ -1677,6 +1689,26 @@ def miniAODConfigurationPre(self, process, patMetModuleSequence, pfCandCollectio
)
getattr(process,"patCaloMet").addGenMET = False

# extract DeepMETs (ResponseTune and ResolutionTune) from miniAOD
if self._parameters["extractDeepMETs"].value:
self.extractMET(process, "rawDeepResponseTune", patMetModuleSequence, postfix)
deepMetResponseTuneName = "metrawDeepResponseTune" if hasattr(process, "metrawDeepResponseTune") else "metrawDeepResponseTune"+postfix
addMETCollection(process,
labelName = "deepMETsResponseTune",
metSource = deepMetResponseTuneName
)
getattr(process, "deepMETsResponseTune").addGenMET = False
getattr(process, "deepMETsResponseTune").computeMETSignificance = cms.bool(False)

self.extractMET(process, "rawDeepResolutionTune", patMetModuleSequence, postfix)
deepMetResolutionTuneName = "metrawDeepResolutionTune" if hasattr(process, "metrawDeepResolutionTune") else "metrawDeepResolutionTune"+postfix
addMETCollection(process,
labelName = "deepMETsResolutionTune",
metSource = deepMetResolutionTuneName
)
getattr(process, "deepMETsResolutionTune").addGenMET = False
getattr(process, "deepMETsResolutionTune").computeMETSignificance = cms.bool(False)

##adding the necessary chs and track met configuration
task = getPatAlgosToolsTask(process)

Expand Down Expand Up @@ -1762,6 +1794,10 @@ def miniAODConfiguration(self, process, pfCandCollection, jetCollection,
getattr(process,"slimmedMETs"+postfix).runningOnMiniAOD = True
getattr(process,"slimmedMETs"+postfix).t01Variation = cms.InputTag("slimmedMETs" if not self._parameters["Puppi"].value else "slimmedMETsPuppi",processName=cms.InputTag.skipCurrentProcess())

if hasattr(process, "deepMETsResolutionTune") and hasattr(process, "deepMETsResponseTune"):
# process includes producing/extracting deepMETsResolutionTune and deepMETsResponseTune
# add them to the slimmedMETs
getattr(process,"slimmedMETs"+postfix).addDeepMETs = True

#smearing and type0 variations not yet supported in reprocessing
#del getattr(process,"slimmedMETs"+postfix).t1SmearedVarsAndUncs
Expand Down Expand Up @@ -2033,6 +2069,7 @@ def runMetCorAndUncFromMiniAOD(process, metType="PF",
computeMETSignificance=True,
fixEE2017=False,
fixEE2017Params=None,
extractDeepMETs=False,
postfix=""):

runMETCorrectionsAndUncertainties = RunMETCorrectionsAndUncertainties()
Expand Down Expand Up @@ -2066,6 +2103,7 @@ def runMetCorAndUncFromMiniAOD(process, metType="PF",
postfix=postfix,
fixEE2017=fixEE2017,
fixEE2017Params=fixEE2017Params,
extractDeepMETs=extractDeepMETs,
)

#MET T1+Txy / Smear
Expand Down Expand Up @@ -2097,6 +2135,7 @@ def runMetCorAndUncFromMiniAOD(process, metType="PF",
postfix=postfix,
fixEE2017=fixEE2017,
fixEE2017Params=fixEE2017Params,
extractDeepMETs=extractDeepMETs,
)
#MET T1+Smear + uncertainties
runMETCorrectionsAndUncertainties(process, metType=metType,
Expand Down Expand Up @@ -2127,4 +2166,5 @@ def runMetCorAndUncFromMiniAOD(process, metType="PF",
postfix=postfix,
fixEE2017=fixEE2017,
fixEE2017Params=fixEE2017Params,
extractDeepMETs=extractDeepMETs,
)