CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
jmeUncertaintyTools.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 
8 #from PhysicsTools.PatUtils.patPFMETCorrections_cff import *
9 import RecoMET.METProducers.METSigParams_cfi as jetResolutions
11 
13 
14 ##MM
15 #from PhysicsTools.PatAlgos.patSequences_cff import *
16 
18 
19  """ Base class for estimating systematic uncertainties on MET """
20  _label='JetMEtUncertaintyTools'
21  _defaultParameters=dicttypes.SortedKeysDict()
22  def __init__(self):
23  ConfigToolBase.__init__(self)
24  self.addParameter(self._defaultParameters, 'electronCollection', cms.InputTag('cleanPatElectrons'),
25  "Input electron collection", Type=cms.InputTag, acceptNoneValue=True)
26  self.addParameter(self._defaultParameters, 'photonCollection', None, # CV: set to empty InputTag to avoid double-counting wrt. cleanPatElectrons collection
27  "Input photon collection", Type=cms.InputTag, acceptNoneValue=True)
28  self.addParameter(self._defaultParameters, 'muonCollection', cms.InputTag('cleanPatMuons'),
29  "Input muon collection", Type=cms.InputTag, acceptNoneValue=True)
30  self.addParameter(self._defaultParameters, 'tauCollection', cms.InputTag('cleanPatTaus'),
31  "Input tau collection", Type=cms.InputTag, acceptNoneValue=True)
32  self.addParameter(self._defaultParameters, 'jetCollection', cms.InputTag('cleanPatJets'),
33  "Input jet collection", Type=cms.InputTag)
34  self.addParameter(self._defaultParameters, 'jetCorrLabel', cms.InputTag("L3Absolute"),
35  "NOTE: use 'L3Absolute' for MC/'L2L3Residual' for Data", Type=cms.InputTag)
36  self.addParameter(self._defaultParameters, 'doSmearJets', True,
37  "Flag to enable/disable jet smearing to better match MC to Data", Type=bool)
38  self.addParameter(self._defaultParameters, 'jetSmearFileName', 'PhysicsTools/PatUtils/data/pfJetResolutionMCtoDataCorrLUT.root',
39  "Name of ROOT file containing histogram with jet smearing factors", Type=str)
40  self.addParameter(self._defaultParameters, 'jetSmearHistogram', 'pfJetResolutionMCtoDataCorrLUT',
41  "Name of histogram with jet smearing factors", Type=str)
42  self.addParameter(self._defaultParameters, 'jetCorrPayloadName', 'AK4PF',
43  "Use AK4PF for PFJets, AK4Calo for CaloJets", Type=str)
44  self.addParameter(self._defaultParameters, 'jetCorrLabelUpToL3', cms.InputTag('ak4PFL1FastL2L3Corrector'),
45  "Use ak4PFL1FastL2L3Corrector (ak4PFchsL1FastL2L3Corrector) for PFJets with (without) charged hadron subtraction, ak4CaloL1FastL2L3Corrector for CaloJets", Type=cms.InputTag)
46  self.addParameter(self._defaultParameters, 'jetCorrLabelUpToL3Res', cms.InputTag('ak4PFL1FastL2L3ResidualCorrector'),
47  "Use ak4PFL1FastL2L3ResidualCorrector (ak4PFchsL1FastL2L3ResiduaCorrectorl) for PFJets with (without) charged hadron subtraction, ak4CaloL1FastL2L3ResidualCorrector for CaloJets", Type=cms.InputTag)
48  self.addParameter(self._defaultParameters, 'jecUncertaintyFile', "PhysicsTools/PatUtils/data/Summer13_V1_DATA_UncertaintySources_AK5PF.txt",
49  "Name of file containing jet energy uncertainty parameters", Type=str)
50  self.addParameter(self._defaultParameters, 'jecUncertaintyTag', 'SubTotalMC',
51  "Name of tag for Data/MC jet energy uncertainties", Type=str)
52  self.addParameter(self._defaultParameters, 'varyByNsigmas', 1.0,
53  "Number of standard deviations by which energies are varied", Type=float)
54  self.addParameter(self._defaultParameters, 'addToPatDefaultSequence', True,
55  "Flag to enable/disable that metUncertaintySequence is inserted into patDefaultSequence", Type=bool)
56  self.addParameter(self._defaultParameters, 'outputModule', 'out',
57  "Module label of PoolOutputModule (empty label indicates no PoolOutputModule is to be configured)", Type=str)
58  self.addParameter(self._defaultParameters, 'postfix', '',
59  "Technical parameter to identify the resulting sequence and its modules (allows multiple calls in a job)", Type=str)
60  self._parameters = copy.deepcopy(self._defaultParameters)
61  self._comment = ""
62 
64  return self._defaultParameters
65 
66 
67  def _initializeInputTag(self, input, default):
68  retVal = None
69  if input is None:
70  retVal = self._defaultParameters[default].value
71  elif type(input) == str:
72  retVal = cms.InputTag(input)
73  else:
74  retVal = input
75  return retVal
76 
77 
78  def _addCleanedJets(self, process, jetCollection,
79  electronCollection, photonCollection,
80  muonCollection, tauCollection,
81  uncertaintySequence, postfix = ""):
82 
83  # produce collection of jets not overlapping with reconstructed
84  # electrons/photons, muons and tau-jet candidates
85  jetsNotOverlappingWithLeptons = cms.EDProducer("PATJetCleaner",
86  src = jetCollection,
87  preselection = cms.string(''),
88  checkOverlaps = cms.PSet(),
89  finalCut = cms.string('')
90  )
91  numOverlapCollections = 0
92  radius = 0.5
93  if "ak4" in jetCollection.moduleLabel.lower(): radius=0.4
94  for collection in [
95  [ 'electrons', electronCollection ],
96  [ 'photons', photonCollection ],
97  [ 'muons', muonCollection ],
98  [ 'taus', tauCollection ] ]:
99  if isValidInputTag(collection[1]):
100  setattr(jetsNotOverlappingWithLeptons.checkOverlaps, collection[0], cms.PSet(
101  src = collection[1],
102  algorithm = cms.string("byDeltaR"),
103  preselection = cms.string(""),
104  deltaR = cms.double(radius),
105  checkRecoComponents = cms.bool(False),
106  pairCut = cms.string(""),
107  requireNoOverlaps = cms.bool(True),
108  ))
109  numOverlapCollections = numOverlapCollections + 1
110  lastJetCollection = jetCollection.value()
111  if numOverlapCollections >= 1:
112  lastJetCollection = \
113  addModuleToSequence(process, jetsNotOverlappingWithLeptons,
114  [ jetCollection.value(), "NotOverlappingWithLeptonsForJetMEtUncertainty" ],
115  uncertaintySequence, postfix)
116  cleanedJetCollection = lastJetCollection
117 
118  return ( lastJetCollection, cleanedJetCollection )
119 
120 
121  def _addShiftedParticleCollections(self, process,
122  electronCollection = None,
123  photonCollection = None,
124  muonCollection = None,
125  tauCollection = None,
126  jetCollection = None, cleanedJetCollection = None,
127  lastJetCollection = None, addShiftedResJetCollections = False,
128  jetCorrLabelUpToL3 = None, jetCorrLabelUpToL3Res = None,
129  jecUncertaintyFile = None, jecUncertaintyTag = None,
130  jetSmearFileName=None, jetSmearHistogram=None,
131  varyByNsigmas = None,
132  postfix = ""):
133 
134  shiftedParticleSequence = cms.Sequence()
135  shiftedParticleCollections = {}
136  collectionsToKeep = []
137 
138  # standard jet collections
139  shiftedParticleCollections[ 'cleanedJetCollection' ] = cleanedJetCollection
140 
141  #--------------------------------------------------------------------------------------------
142  # store collection of jets shifted up/down in energy resolution
143  #--------------------------------------------------------------------------------------------
144  if not isValidInputTag(jetCollection) or jetCollection=="":
145  print "INFO : jet collection %s does not exists, no energy resolution shifting will be performed in MET uncertainty tools" % jetCollection
146  else:
147  if addShiftedResJetCollections:
148  variations = { "ResUp":-1., "ResDown":1. }
149  for var in variations.keys():
150  jetCollectionToKeep = \
151  addSmearedJets(process, cleanedJetCollection,
152  [ "smeared", jetCollection, var ],
153  jetSmearFileName,jetSmearHistogram,jetResolutions,
154  varyByNsigmas, variations[ var ],
155  shiftedParticleSequence, postfix)
156  jetCol={'jetCollection%s'%var:jetCollectionToKeep}
157  shiftedParticleCollections.update( jetCol )
158  collectionsToKeep.append( jetCollectionToKeep )
159 
160  #--------------------------------------------------------------------------------------------
161  # produce collection of jets shifted up/down in energy
162  #--------------------------------------------------------------------------------------------
163  if not isValidInputTag(jetCollection) or jetCollection=="":
164  print "INFO : jet collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % jetCollection
165  else:
166  shiftedJetsCollections, jetsCollectionsToKeep = addShiftedJetCollections(
167  process,jetCollection,lastJetCollection,
168  jetCorrLabelUpToL3, jetCorrLabelUpToL3Res,
169  jecUncertaintyFile, jecUncertaintyTag,
170  varyByNsigmas, shiftedParticleSequence,
171  postfix)
172  shiftedParticleCollections.update( shiftedJetsCollections )
173  collectionsToKeep.extend( jetsCollectionsToKeep )
174 
175  #--------------------------------------------------------------------------------------------
176  # produce collection of electrons shifted up/down in energy
177  #--------------------------------------------------------------------------------------------
178  if not isValidInputTag(electronCollection) or electronCollection=="":
179  print "INFO : electron collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % electronCollection
180  else:
181  shiftedElectronsCollections, electronsCollectionsToKeep = addShiftedSingleParticleCollection(
182  process, "electron", electronCollection,
183  varyByNsigmas,shiftedParticleSequence,
184  postfix)
185 
186  shiftedParticleCollections.update( shiftedElectronsCollections )
187  collectionsToKeep.extend( electronsCollectionsToKeep )
188 
189  #--------------------------------------------------------------------------------------------
190  # produce collection of (high Pt) photon candidates shifted up/down in energy
191  #--------------------------------------------------------------------------------------------
192  if not isValidInputTag(photonCollection) or photonCollection=="":
193  print "INFO : photon collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % photonCollection
194  else:
195  shiftedPhotonsCollections, photonsCollectionsToKeep = addShiftedSingleParticleCollection(
196  process, "photon", photonCollection,
197  varyByNsigmas,shiftedParticleSequence,
198  postfix)
199  shiftedParticleCollections.update( shiftedPhotonsCollections )
200  collectionsToKeep.extend( photonsCollectionsToKeep )
201 
202  #--------------------------------------------------------------------------------------------
203  # produce collection of muons shifted up/down in energy/momentum
204  #--------------------------------------------------------------------------------------------
205  if not isValidInputTag(muonCollection) or muonCollection=="":
206  print "INFO : muon collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % muonCollection
207  else:
208  shiftedMuonsCollections, muonsCollectionsToKeep = addShiftedSingleParticleCollection(process, "muon", muonCollection,
209  varyByNsigmas,shiftedParticleSequence,
210  postfix)
211  shiftedParticleCollections.update( shiftedMuonsCollections )
212  collectionsToKeep.extend( muonsCollectionsToKeep )
213 
214  #--------------------------------------------------------------------------------------------
215  # produce collection of tau-jets shifted up/down in energy
216  #--------------------------------------------------------------------------------------------
217  if not isValidInputTag(tauCollection) or tauCollection=="":
218  print "INFO : tau collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % tauCollection
219  else:
220  shiftedTausCollections, tausCollectionsToKeep = addShiftedSingleParticleCollection(process, "tau", tauCollection,
221  varyByNsigmas,shiftedParticleSequence,
222  postfix)
223  shiftedParticleCollections.update( shiftedTausCollections )
224  collectionsToKeep.extend( tausCollectionsToKeep )
225 
226 
227  return ( shiftedParticleSequence, shiftedParticleCollections, collectionsToKeep )
228 
229 
230 
231 
232 
233  def _addPFCandidatesForPFMEtInput(self, process, metUncertaintySequence,
234  particleCollection, particleType, shiftType, particleCollectionShiftUp, particleCollectionShiftDown,
235  dRmatch,
236  pfCandCollection, postfix):
237 
238  srcUnshiftedObjects = particleCollection
239  if isinstance(srcUnshiftedObjects, cms.InputTag):
240  srcUnshiftedObjects = srcUnshiftedObjects.value()
241  moduleShiftUp = cms.EDProducer("ShiftedPFCandidateProducerByMatchedObject",
242  srcPFCandidates = pfCandCollection,
243  srcUnshiftedObjects = cms.InputTag(srcUnshiftedObjects),
244  srcShiftedObjects = cms.InputTag(particleCollectionShiftUp),
245  dRmatch_PFCandidate = cms.double(dRmatch)
246  )
247  moduleNameShiftUp = "pfCandidates%s%sUp%s" % (particleType, shiftType, postfix)
248  setattr(process, moduleNameShiftUp, moduleShiftUp)
249  metUncertaintySequence += moduleShiftUp
250 
251  moduleShiftDown = moduleShiftUp.clone(
252  srcShiftedObjects = cms.InputTag(particleCollectionShiftDown)
253  )
254  moduleNameShiftDown = "pfCandidates%s%sDown%s" % (particleType, shiftType, postfix)
255  setattr(process, moduleNameShiftDown, moduleShiftDown)
256  metUncertaintySequence += moduleShiftDown
257 
258  moduleNameShifts = { 'Up':moduleNameShiftUp , 'Down':moduleNameShiftDown }
259  return moduleNameShifts
260  # return ( moduleNameShiftUp, moduleNameShiftDown )
261 
262  def _getLeptonsForPFMEtInput(self, shiftedParticleCollections, substituteKeyUnshifted = None, substituteKeyShifted = None, postfix=""):
263  retVal = []
264  for particleCol in shiftedParticleCollections.keys():
265  if not (particleCol.find("Jet") or particleCol.find("jet") ) and isValidInputTag(shiftedParticleCollections[collectionName]):
266  print collectionName,"==>:"+shiftedParticleCollections[collectionName]
267  if substituteKeyUnshifted is not None and substituteKeyUnshifted in shiftedParticleCollections.keys() and \
268  substituteKeyShifted is not None and substituteKeyShifted in shiftedParticleCollections.keys() and \
269  shiftedParticleCollections[collectionName] == shiftedParticleCollections[substituteKeyUnshifted]:
270  retVal.append(cms.InputTag(shiftedParticleCollections[substituteKeyShifted]))
271  else:
272  retVal.append(shiftedParticleCollections[collectionName])
273  return retVal
274 
275  def _addPATMEtProducer(self, process, metUncertaintySequence,
276  metCollection, patMEtCollection,
277  collectionsToKeep, postfix):
278 
279  module = patMETs.clone(
280  metSource = cms.InputTag(metCollection),
281  addMuonCorrections = cms.bool(False),
282  genMETSource = cms.InputTag('genMetTrue')
283  )
284  patMEtCollectionName = patMEtCollection+postfix
285  setattr(process, patMEtCollectionName, module)
286  metUncertaintySequence += module
287  collectionsToKeep.append(patMEtCollectionName)
288 
289 
290  def __call__(self, process,
291  electronCollection = None,
292  photonCollection = None,
293  muonCollection = None,
294  tauCollection = None,
295  jetCollection = None,
296  jetCorrLabel = None,
297  doSmearJets = None,
298  jetSmearFileName = None,
299  jetSmearHistogram = None,
300  jetCorrPayloadName = None,
301  jetCorrLabelUpToL3 = None,
302  jetCorrLabelUpToL3Res = None,
303  jecUncertaintyFile = None,
304  jecUncertaintyTag = None,
305  varyByNsigmas = None,
306  addToPatDefaultSequence = None,
307  outputModule = None,
308  postfix = None):
309  electronCollection = self._initializeInputTag(electronCollection, 'electronCollection')
310  photonCollection = self._initializeInputTag(photonCollection, 'photonCollection')
311  muonCollection = self._initializeInputTag(muonCollection, 'muonCollection')
312  tauCollection = self._initializeInputTag(tauCollection, 'tauCollection')
313  jetCollection = self._initializeInputTag(jetCollection, 'jetCollection')
314  if jetCorrLabel is None:
315  jetCorrLabel = self._defaultParameters['jetCorrLabel'].value
316  if doSmearJets is None:
317  doSmearJets = self._defaultParameters['doSmearJets'].value
318  if jetSmearFileName is None:
319  jetSmearFileName = self._defaultParameters['jetSmearFileName'].value
320  if jetSmearHistogram is None:
321  jetSmearHistogram = self._defaultParameters['jetSmearHistogram'].value
322  if jetCorrPayloadName is None:
323  jetCorrPayloadName = self._defaultParameters['jetCorrPayloadName'].value
324  if jetCorrLabelUpToL3 is None:
325  jetCorrLabelUpToL3 = self._defaultParameters['jetCorrLabelUpToL3'].value
326  if jetCorrLabelUpToL3Res is None:
327  jetCorrLabelUpToL3Res = self._defaultParameters['jetCorrLabelUpToL3Res'].value
328  if jecUncertaintyFile is None:
329  jecUncertaintyFile = self._defaultParameters['jecUncertaintyFile'].value
330  if jecUncertaintyTag is None:
331  jecUncertaintyTag = self._defaultParameters['jecUncertaintyTag'].value
332  if varyByNsigmas is None:
333  varyByNsigmas = self._defaultParameters['varyByNsigmas'].value
334  if addToPatDefaultSequence is None:
335  addToPatDefaultSequence = self._defaultParameters['addToPatDefaultSequence'].value
336  if outputModule is None:
337  outputModule = self._defaultParameters['outputModule'].value
338  if postfix is None:
339  postfix = self._defaultParameters['postfix'].value
340 
341  self.setParameter('electronCollection', electronCollection)
342  self.setParameter('photonCollection', photonCollection)
343  self.setParameter('muonCollection', muonCollection)
344  self.setParameter('tauCollection', tauCollection)
345  self.setParameter('jetCollection', jetCollection)
346  self.setParameter('jetCorrLabel', jetCorrLabel)
347  self.setParameter('doSmearJets', doSmearJets)
348  self.setParameter('jetSmearFileName', jetSmearFileName)
349  self.setParameter('jetSmearHistogram', jetSmearHistogram)
350  self.setParameter('jetCorrPayloadName', jetCorrPayloadName)
351  self.setParameter('jetCorrLabelUpToL3', jetCorrLabelUpToL3)
352  self.setParameter('jetCorrLabelUpToL3Res', jetCorrLabelUpToL3Res)
353  self.setParameter('jecUncertaintyFile', jecUncertaintyFile)
354  self.setParameter('jecUncertaintyTag', jecUncertaintyTag)
355  self.setParameter('varyByNsigmas', varyByNsigmas)
356  self.setParameter('addToPatDefaultSequence', addToPatDefaultSequence)
357  self.setParameter('outputModule', outputModule)
358  self.setParameter('postfix', postfix)
359 
MM from PhysicsTools.PatAlgos.patSequences_cff import *.
def addShiftedJetCollections
Now, jet variation for corrected METs, the default collection to use.
def addShiftedSingleParticleCollection
Up variation.