CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
runMVAMEtUncertainties.py
Go to the documentation of this file.
2 
4 
5 import PhysicsTools.PatAlgos.tools.helpers as configtools
6 from PhysicsTools.PatAlgos.tools.trigTools import _addEventContent
7 from PhysicsTools.PatUtils.tools.jmeUncertaintyTools import JetMEtUncertaintyTools
8 from PhysicsTools.PatUtils.tools.objectsUncertaintyTools import isValidInputTag,addSmearedJets
9 
10 import RecoMET.METProducers.METSigParams_cfi as jetResolutions
11 
12 
13 
14 class RunMVAMEtUncertainties(JetMEtUncertaintyTools):
15 
16  """ Shift energy of electrons, photons, muons, tau-jets and other jets
17  reconstructed in the event up/down,
18  in order to estimate effect of energy scale uncertainties on MVA MET
19  """
20  _label = 'runMVAMEtUncertainties'
21  _defaultParameters = dicttypes.SortedKeysDict()
22  def __init__(self):
23  JetMEtUncertaintyTools.__init__(self)
24  self.addParameter(self._defaultParameters, 'pfCandCollection', cms.InputTag('particleFlow'),
25  "Input PFCandidate collection", Type = cms.InputTag)
26  self._parameters = copy.deepcopy(self._defaultParameters)
27  self._comment = ""
28 
29  def _addPFMVAMEt(self, process, metUncertaintySequence,
30  shiftedParticleCollections, pfCandCollection,
31  collectionsToKeep,
32  doSmearJets,
33  jecUncertaintyFile, jecUncertaintyTag,
34  varyByNsigmas,
35  postfix):
36 
37  # loading default files
38 
39  if not hasattr(process, "pfMEtMVA"):
40  process.load("RecoMET.METPUSubtraction.mvaPFMET_cff")
41 
42  pfCandCollectionUnsmeared = pfCandCollection
43  lastUncorrectedJetCollection = 'ak4PFJets'
44  lastCorrectedJetCollection = 'calibratedAK4PFJetsForPFMVAMEt'
45 
46  #set postfix if not empty value
47  if postfix != "":
48  configtools.cloneProcessingSnippet(process, process.pfMVAMEtSequence, postfix)
49  lastCorrectedJetCollection += postfix
50 
51  if doSmearJets:
52  self._createUncorrectedJetsModules(process, jetResolutions, pfCandCollection, metUncertaintySequence, postfix)
53  else:
54  metUncertaintySequence += getattr(process, "pfMVAMEtSequence" + postfix)
55  self._addPATMEtProducer(process, metUncertaintySequence,
56  'pfMVAMEt' + postfix, 'patPFMVAMEt', collectionsToKeep, postfix)
57 
58 
59  variations=['Up','Down']
60  varDir= { 'Up':1., 'Down':-1. }
61 
62  #=====================================================
63  # Leptons
64  #=====================================================
65  for leptonCollection in [ [ 'Electron', 'En', 'electronCollection', 0.3 ],
66  [ 'Photon', 'En', 'photonCollection', 0.3 ],
67  [ 'Muon', 'En', 'muonCollection', 0.3 ],
68  [ 'Tau', 'En', 'tauCollection', 0.3 ] ]:
69 
70 
71 
72  # pfCandCollectionLeptonShift= { 'Up':None, 'Down':None }
73 
74  if ( leptonCollection[2] in shiftedParticleCollections ) and isValidInputTag(shiftedParticleCollections[leptonCollection[2]]):
75  pfCandCollectionLeptonShift = \
76  self._addPFCandidatesForPFMEtInput(
77  process, metUncertaintySequence,
78  shiftedParticleCollections['%s' % leptonCollection[2]], leptonCollection[0], leptonCollection[1],
79  shiftedParticleCollections['%s%sUp' % (leptonCollection[2], leptonCollection[1])],
80  shiftedParticleCollections['%s%sDown' % (leptonCollection[2], leptonCollection[1])],
81  leptonCollection[3],
82  pfCandCollection, postfix)
83 
84 
85  for var in variations:
86 
87  modulePFMEtLeptonShift = getattr(process, "pfMVAMEt" + postfix).clone(
88  srcPFCandidates = cms.InputTag(pfCandCollectionLeptonShift[var]),
89  srcLeptons = cms.VInputTag(self._getLeptonsForPFMEtInput(
90  shiftedParticleCollections, leptonCollection[2], '%s%s%s' % (leptonCollection[2], leptonCollection[1], var), postfix = postfix))
91  )
92  modulePFMEtLeptonShiftName = "pfMVAMEt%s%s%s" % (leptonCollection[0], leptonCollection[1],var)
93  modulePFMEtLeptonShiftName += postfix
94  setattr(process, modulePFMEtLeptonShiftName, modulePFMEtLeptonShift)
95  metUncertaintySequence += modulePFMEtLeptonShift
96  self._addPATMEtProducer(process, metUncertaintySequence,
97  modulePFMEtLeptonShiftName, 'patPFMVAMet%s%s%s' % (leptonCollection[0], leptonCollection[1],var), collectionsToKeep, postfix)
98 
99  #=====================================================
100  # Jets
101  #=====================================================
102 
103  # energy shift =======================
104  for var in variations:
105 
106  if isValidInputTag(shiftedParticleCollections['jetCollection']):
107  setattr(process, "uncorrectedJetsEn%sForPFMVAMEt%s" % (var, postfix), cms.EDProducer("ShiftedPFJetProducer",
108  src = cms.InputTag(lastUncorrectedJetCollection),
109  jetCorrInputFileName = cms.FileInPath(jecUncertaintyFile),
110  jetCorrUncertaintyTag = cms.string(jecUncertaintyTag),
111  addResidualJES = cms.bool(False),
112  jetCorrLabelUpToL3 = cms.InputTag("ak4PFL1FastL2L3Corrector"),
113  jetCorrLabelUpToL3Res = cms.InputTag("ak4PFL1FastL2L3ResidualCorrector"),
114  shiftBy = cms.double( varDir[var] *varyByNsigmas)
115  ))
116  metUncertaintySequence += getattr(process, "uncorrectedJetsEn%sForPFMVAMEt%s" % (var, postfix) )
117 
118  setattr(process, "correctedJetsEn%sForPFMVAMEt%s" %(var, postfix), getattr(process, "uncorrectedJetsEn%sForPFMVAMEt%s" % (var, postfix) ).clone(
119  src = cms.InputTag(lastCorrectedJetCollection),
120  ))
121  metUncertaintySequence += getattr(process, "correctedJetsEn%sForPFMVAMEt%s" % (var, postfix) )
122 
123  # pfCandCollectionJetEnShift= { 'Up':None, 'Down':None }
124  # pfCandCollectionJetResShift= { 'Up':None, 'Down':None }
125  pfCandCollectionJetEnShift = \
126  self._addPFCandidatesForPFMEtInput(
127  process, metUncertaintySequence,
128  shiftedParticleCollections['lastJetCollection'], "Jet", "En",
129  shiftedParticleCollections['jetCollectionEnUp'], shiftedParticleCollections['jetCollectionEnDown'],
130  0.5,
131  pfCandCollection, postfix)
132 
133 
134  # energy resolution shift =======================
135  if hasattr(process, "smearedUncorrectedJetsForPFMVAMEt" + postfix):
136  # pfCandCollectionJetResShift[ 'Up' ], pfCandCollectionJetResShift[ 'Down' ] = \
137  # self._addPFCandidatesForPFMEtInput(
138  # process, metUncertaintySequence,
139  # shiftedParticleCollections['jetCollection'], "Jet", "Res",
140  # shiftedParticleCollections['jetCollectionResUp'], shiftedParticleCollections['jetCollectionResDown'],
141  # 0.5,
142  # pfCandCollectionUnsmeared, postfix)
143 
144  for var in variations:
145  setattr(process, "pfMVAMEtJetEn" + var + postfix, getattr(process, "pfMVAMEt").clone(
146  srcCorrJets = cms.InputTag('correctedJetsEn%sForPFMVAMEt%s' % (var, postfix) ),
147  srcUncorrJets = cms.InputTag('uncorrectedJetsEn%sForPFMVAMEt%s' %(var, postfix) ),
148  srcLeptons = cms.VInputTag(self._getLeptonsForPFMEtInput(shiftedParticleCollections, postfix = postfix))
149  ))
150  metUncertaintySequence += getattr(process, "pfMVAMEtJetEn" + var + postfix)
151  self._addPATMEtProducer(process, metUncertaintySequence,
152  'pfMVAMEtJetEn' + var + postfix, 'patMVAPFMetJetEn' + var, collectionsToKeep, postfix)
153 
154 
155  setattr(process, "uncorrectedJetsRes%sForPFMVAMEt%s"% (var, postfix), getattr(process, "smearedUncorrectedJetsForPFMVAMEt" + postfix).clone(
156  shiftBy = cms.double(varDir[var]*varyByNsigmas)
157  ))
158  metUncertaintySequence += getattr(process, "uncorrectedJetsRes%sForPFMVAMEt%s" % (var, postfix) )
159  setattr(process, "smearedPFCandidatesJetRes%sForPFMVAMEt%s" % (var, postfix), getattr(process, "smearedPFCandidatesForPFMVAMEt" + postfix).clone(
160  srcShiftedObjects = cms.InputTag("uncorrectedJetsRes%sForPFMVAMEt%s" % (var, postfix) ),
161  ))
162  metUncertaintySequence += getattr(process, "smearedPFCandidatesJetRes%sForPFMVAMEt%s" % (var, postfix))
163 
164  setattr(process, "correctedJetsRes%sForPFMVAMEt%s" % (var, postfix), getattr(process, "calibratedAK4PFJetsForPFMVAMEt" + postfix).clone(
165  src = cms.InputTag("uncorrectedJetsRes%sForPFMVAMEt%s" % (var, postfix) )
166  ))
167  metUncertaintySequence += getattr(process, "correctedJetsRes%sForPFMVAMEt%s" % (var, postfix) )
168 
169 
170  setattr(process, "pfMVAMEtJetRes" + var + postfix, getattr(process, "pfMVAMEt" + postfix).clone(
171  srcCorrJets = cms.InputTag('correctedJetsRes%sForPFMVAMEt%s' % (var, postfix)),
172  srcUncorrJets = cms.InputTag('uncorrectedJetsRes%sForPFMVAMEt%s' % (var, postfix)),
173  ##srcPFCandidates = cms.InputTag(pfCandCollectionJetResShift[ var ]),
174  srcPFCandidates = cms.InputTag("smearedPFCandidatesJetRes%sForPFMVAMEt%s" %(var, postfix) ),
175  srcLeptons = cms.VInputTag(self._getLeptonsForPFMEtInput(shiftedParticleCollections, postfix = postfix))
176  ))
177  metUncertaintySequence += getattr(process, "pfMVAMEtJetRes" + var + postfix)
178  self._addPATMEtProducer(process, metUncertaintySequence,
179  'pfMVAMEtJetRes' + var + postfix, 'patPFMVAMetJetRes' + var, collectionsToKeep, postfix)
180 
181 
182  #=====================================================
183  #unclustered energy
184  #=====================================================
185 
186  # check existence of pfCandsNotInJet collection => no need of postfix, they are the same everywhere
187  if not hasattr(process, "pfCandsNotInJetsForMetCorr"):
188  from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import pfJetsPtrForMetCorr, pfCandsNotInJetsPtrForMetCorr, pfCandsNotInJetsForMetCorr
189  metUncertaintySequence += pfJetsPtrForMetCorr
190  metUncertaintySequence += pfCandsNotInJetsPtrForMetCorr
191  metUncertaintySequence += pfCandsNotInJetsForMetCorr
192 
193 
194  # pfCandCollectionUnclusteredEnShift= { 'Up':None, 'Down':None }
195  for var in variations:
196  setattr(process, "pfCandsNotInJetsUnclusteredEn%sForPFMVAMEt%s" % (var, postfix), cms.EDProducer("ShiftedPFCandidateProducer",
197  src = cms.InputTag('pfCandsNotInJetsForMetCorr'),
198  shiftBy = cms.double(varDir[var]*varyByNsigmas),
199  uncertainty = cms.double(0.10)
200  ))
201  metUncertaintySequence += getattr(process, "pfCandsNotInJetsUnclusteredEn%sForPFMVAMEt%s" % (var, postfix))
202 
203  pfCandCollectionUnclusteredEnShift = \
204  self._addPFCandidatesForPFMEtInput(
205  process, metUncertaintySequence,
206  pfCandCollection, "Unclustered", "En",
207  'pfCandsNotInJetsUnclusteredEnUpForPFMVAMEt' + postfix, 'pfCandsNotInJetsUnclusteredEnDownForPFMVAMEt' + postfix,
208  0.01,
209  pfCandCollection, postfix)
210 
211  for var in variations:
212  setattr(process, "pfMVAMEtUnclusteredEn" + var + postfix, getattr(process, "pfMVAMEt" + postfix).clone(
213  srcPFCandidates = cms.InputTag(pfCandCollectionUnclusteredEnShift[var]),
214  srcLeptons = cms.VInputTag(self._getLeptonsForPFMEtInput(shiftedParticleCollections, postfix = postfix))
215  ))
216  metUncertaintySequence += getattr(process, "pfMVAMEtUnclusteredEn" + var + postfix)
217  self._addPATMEtProducer(process, metUncertaintySequence,
218  'pfMVAMEtUnclusteredEn' + var + postfix, 'patPFMVAMetUnclusteredEn'+var, collectionsToKeep, postfix)
219 
220 
221 
222 
223 
224  def _createUncorrectedJetsModules(self,process, jetResolutions, pfCandCollection, metUncertaintySequence, postfix):
225 
226  process.load("RecoJets.Configuration.GenJetParticles_cff")
227  metUncertaintySequence += process.genParticlesForJetsNoNu
228  process.load("RecoJets.Configuration.RecoGenJets_cff")
229  metUncertaintySequence += process.ak4GenJetsNoNu
230  setattr(process, "smearedUncorrectedJetsForPFMVAMEt" + postfix, cms.EDProducer("SmearedPFJetProducer",
231  src = cms.InputTag('ak4PFJets'),
232  jetCorrLabel = cms.InputTag("ak4PFL1FastL2L3Corrector"),
233  dRmaxGenJetMatch = cms.string('min(0.5, 0.1 + 0.3*exp(-0.05*(genJetPt - 10.)))'),
234  sigmaMaxGenJetMatch = cms.double(3.),
235  inputFileName = cms.FileInPath('PhysicsTools/PatUtils/data/pfJetResolutionMCtoDataCorrLUT.root'),
236  lutName = cms.string('pfJetResolutionMCtoDataCorrLUT'),
237  jetResolutions = jetResolutions.METSignificance_params,
238  skipRawJetPtThreshold = cms.double(10.), # GeV
239  skipCorrJetPtThreshold = cms.double(1.e-2),
240  srcGenJets = cms.InputTag('ak4GenJetsNoNu'),
241  #verbosity = cms.int32(1)
242  ))
243  setattr(process, "smearedPFCandidatesForPFMVAMEt" + postfix, cms.EDProducer("ShiftedPFCandidateProducerForPFMVAMEt",
244  srcPFCandidates = pfCandCollection,
245  srcUnshiftedObjects = cms.InputTag("ak4PFJets"),
246  srcShiftedObjects = cms.InputTag("smearedUncorrectedJetsForPFMVAMEt" + postfix),
247  dRmatch_PFCandidate = cms.double(0.5)
248  ))
249  pfCandCollection = cms.InputTag("smearedPFCandidatesForPFMVAMEt" + postfix)
250  metUncertaintySequence += getattr(process, "smearedUncorrectedJetsForPFMVAMEt" + postfix)
251  metUncertaintySequence += getattr(process, "smearedPFCandidatesForPFMVAMEt" + postfix)
252  getattr(process, "calibratedAK4PFJetsForPFMVAMEt" + postfix).src = cms.InputTag('smearedUncorrectedJetsForPFMVAMEt' + postfix)
253  getattr(process, "pfMVAMEt" + postfix).srcUncorrJets = cms.InputTag('smearedUncorrectedJetsForPFMVAMEt' + postfix)
254  getattr(process, "pfMVAMEt" + postfix).srcPFCandidates = cms.InputTag('smearedPFCandidatesForPFMVAMEt' + postfix)
255  metUncertaintySequence += getattr(process, "calibratedAK4PFJetsForPFMVAMEt" + postfix)
256  metUncertaintySequence += getattr(process, "pfMVAMEt" + postfix)
257  lastUncorrectedJetCollection = 'smearedUncorrectedJetsForPFMVAMEt' + postfix
258 
259 
260  def __call__(self, process,
261  electronCollection = None,
262  photonCollection = None,
263  muonCollection = None,
264  tauCollection = None,
265  jetCollection = None,
266  dRjetCleaning = None,
267  jetCorrLabel = None,
268  doSmearJets = None,
269  jetSmearFileName = None,
270  jetSmearHistogram = None,
271  pfCandCollection = None,
272  jetCorrPayloadName = None,
273  jetCorrLabelUpToL3 = None,
274  jetCorrLabelUpToL3Res = None,
275  jecUncertaintyFile = None,
276  jecUncertaintyTag = None,
277  varyByNsigmas = None,
278  addToPatDefaultSequence = None,
279  outputModule = None,
280  postfix = None):
281  JetMEtUncertaintyTools.__call__(
282  self, process,
283  electronCollection = electronCollection,
284  photonCollection = photonCollection,
285  muonCollection = muonCollection,
286  tauCollection = tauCollection,
287  jetCollection = jetCollection,
288  jetCorrLabel = jetCorrLabel,
289  doSmearJets = doSmearJets,
290  jetSmearFileName = jetSmearFileName,
291  jetSmearHistogram = jetSmearHistogram,
292  jetCorrPayloadName = jetCorrPayloadName,
293  jetCorrLabelUpToL3 = jetCorrLabelUpToL3,
294  jetCorrLabelUpToL3Res = jetCorrLabelUpToL3Res,
295  jecUncertaintyFile = jecUncertaintyFile,
296  jecUncertaintyTag = jecUncertaintyTag,
297  varyByNsigmas = varyByNsigmas,
298  addToPatDefaultSequence = addToPatDefaultSequence,
299  outputModule = outputModule,
300  postfix = postfix)
301  pfCandCollection = self._initializeInputTag(pfCandCollection, 'pfCandCollection')
302 
303  self.setParameter('pfCandCollection', pfCandCollection)
304 
305  self.apply(process)
306 
307  def toolCode(self, process):
308  electronCollection = self._parameters['electronCollection'].value
309  photonCollection = self._parameters['photonCollection'].value
310  muonCollection = self._parameters['muonCollection'].value
311  tauCollection = self._parameters['tauCollection'].value
312  jetCollection = self._parameters['jetCollection'].value
313  jetCorrLabel = self._parameters['jetCorrLabel'].value
314  doSmearJets = self._parameters['doSmearJets'].value
315  jetSmearFileName = self._parameters['jetSmearFileName'].value
316  jetSmearHistogram = self._parameters['jetSmearHistogram'].value
317  pfCandCollection = self._parameters['pfCandCollection'].value
318  jetCorrPayloadName = self._parameters['jetCorrPayloadName'].value
319  jetCorrLabelUpToL3 = self._parameters['jetCorrLabelUpToL3'].value
320  jetCorrLabelUpToL3Res = self._parameters['jetCorrLabelUpToL3Res'].value
321  jecUncertaintyFile = self._parameters['jecUncertaintyFile'].value
322  jecUncertaintyTag = self._parameters['jecUncertaintyTag'].value
323  varyByNsigmas = self._parameters['varyByNsigmas'].value
324  addToPatDefaultSequence = self._parameters['addToPatDefaultSequence'].value
325  outputModule = self._parameters['outputModule'].value
326  postfix = self._parameters['postfix'].value
327 
328  if not hasattr(process, "pfMVAMEtUncertaintySequence" + postfix):
329  metUncertaintySequence = cms.Sequence()
330  setattr(process, "pfMVAMEtUncertaintySequence" + postfix, metUncertaintySequence)
331  metUncertaintySequence = getattr(process, "pfMVAMEtUncertaintySequence" + postfix)
332 
333  collectionsToKeep = []
334 
335  lastJetCollection = jetCollection.value()
336 
337  # smear jet energies to account for difference in jet resolutions between MC and Data
338  # (cf. JME-10-014 PAS)
339  if isValidInputTag(jetCollection):
340  if doSmearJets:
341  lastJetCollection = \
342  addSmearedJets(process, lastJetCollection, [ "smeared", jetCollection.value(), "ForPFMVAMEt" ],
343  jetSmearFileName, jetSmearHistogram, jetResolutions, varyByNsigmas, None,
344  sequence = metUncertaintySequence, postfix = postfix)
345 # jetCollectionResUp = \
346 # self._addSmearedJets(process, lastJetCollection, [ "smeared", jetCollection.value(), "ForPFMVAMEtResUp" ],
347 # jetSmearFileName, jetSmearHistogram, varyByNsigmas, -1.,
348 # uncertaintySequence = metUncertaintySequence, postfix = postfix)
349 # collectionsToKeep.append(jetCollectionResUp)
350 # jetCollectionResDown = \
351 # self._addSmearedJets(process, lastJetCollection, [ "smeared", jetCollection.value(), "ForPFMVAMEtResDown" ],
352 # jetSmearFileName, jetSmearHistogram, varyByNsigmas, +1.,
353 # uncertaintySequence = metUncertaintySequence, postfix = postfix)
354 # collectionsToKeep.append(jetCollectionResDown)
355 
356  collectionsToKeep.append(lastJetCollection)
357 
358  #--------------------------------------------------------------------------------------------
359  # produce collection of electrons/photons, muons, tau-jet candidates and jets
360  # shifted up/down in energy by their respective energy uncertainties
361  #--------------------------------------------------------------------------------------------
362  shiftedParticleSequence, shiftedParticleCollections, addCollectionsToKeep = \
363  self._addShiftedParticleCollections(process,
364  electronCollection.value(),
365  photonCollection.value(),
366  muonCollection.value(),
367  tauCollection.value(),
368  jetCollection.value(), lastJetCollection, lastJetCollection,
369  doSmearJets,
370  jetCorrLabelUpToL3, jetCorrLabelUpToL3Res,
371  jecUncertaintyFile, jecUncertaintyTag,
372  jetSmearFileName, jetSmearHistogram,
373  varyByNsigmas,
374  "ForPFMVAMEt" + postfix)
375  setattr(process, "shiftedParticlesForPFMVAMEtUncertainties" + postfix, shiftedParticleSequence)
376  metUncertaintySequence += getattr(process, "shiftedParticlesForPFMVAMEtUncertainties" + postfix)
377  collectionsToKeep.extend(addCollectionsToKeep)
378 
379  #--------------------------------------------------------------------------------------------
380  # propagate shifted particle energies to MVA MET
381  #--------------------------------------------------------------------------------------------
382 
383  self._addPFMVAMEt(process, metUncertaintySequence,
384  shiftedParticleCollections, pfCandCollection,
385  collectionsToKeep,
386  doSmearJets,
387  jecUncertaintyFile, jecUncertaintyTag,
388  varyByNsigmas,
389  postfix)
390 
391  # insert metUncertaintySequence into patDefaultSequence
392  if addToPatDefaultSequence:
393  if not hasattr(process, "patDefaultSequence"):
394  raise ValueError("PAT default sequence is not defined !!")
395  process.patDefaultSequence += metUncertaintySequence
396 
397  # add shifted + unshifted collections pf pat::Electrons/Photons,
398  # Muons, Taus, Jets and MET to PAT-tuple event content
399  if outputModule is not None and hasattr(process, outputModule):
400  getattr(process, outputModule).outputCommands = _addEventContent(
401  getattr(process, outputModule).outputCommands,
402  [ 'keep *_%s_*_%s' % (collectionToKeep, process.name_()) for collectionToKeep in collectionsToKeep ])
403 
404 runMVAMEtUncertainties = RunMVAMEtUncertainties()
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
def _addEventContent
Definition: trigTools.py:29