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  for collection in [
93  [ 'electrons', electronCollection ],
94  [ 'photons', photonCollection ],
95  [ 'muons', muonCollection ],
96  [ 'taus', tauCollection ] ]:
97  if isValidInputTag(collection[1]):
98  setattr(jetsNotOverlappingWithLeptons.checkOverlaps, collection[0], cms.PSet(
99  src = collection[1],
100  algorithm = cms.string("byDeltaR"),
101  preselection = cms.string(""),
102  deltaR = cms.double(0.5),
103  checkRecoComponents = cms.bool(False),
104  pairCut = cms.string(""),
105  requireNoOverlaps = cms.bool(True),
106  ))
107  numOverlapCollections = numOverlapCollections + 1
108  lastJetCollection = jetCollection.value()
109  if numOverlapCollections >= 1:
110  lastJetCollection = \
111  addModuleToSequence(process, jetsNotOverlappingWithLeptons,
112  [ jetCollection.value(), "NotOverlappingWithLeptonsForJetMEtUncertainty" ],
113  uncertaintySequence, postfix)
114  cleanedJetCollection = lastJetCollection
115 
116  return ( lastJetCollection, cleanedJetCollection )
117 
118 
119  def _addShiftedParticleCollections(self, process,
120  electronCollection = None,
121  photonCollection = None,
122  muonCollection = None,
123  tauCollection = None,
124  jetCollection = None, cleanedJetCollection = None,
125  lastJetCollection = None, addShiftedResJetCollections = False,
126  jetCorrLabelUpToL3 = None, jetCorrLabelUpToL3Res = None,
127  jecUncertaintyFile = None, jecUncertaintyTag = None,
128  jetSmearFileName=None, jetSmearHistogram=None,
129  varyByNsigmas = None,
130  postfix = ""):
131 
132  shiftedParticleSequence = cms.Sequence()
133  shiftedParticleCollections = {}
134  collectionsToKeep = []
135 
136  # standard jet collections
137  shiftedParticleCollections[ 'cleanedJetCollection' ] = cleanedJetCollection
138 
139  #--------------------------------------------------------------------------------------------
140  # store collection of jets shifted up/down in energy resolution
141  #--------------------------------------------------------------------------------------------
142  if not isValidInputTag(jetCollection) or jetCollection=="":
143  print "INFO : jet collection %s does not exists, no energy resolution shifting will be performed in MET uncertainty tools" % jetCollection
144  else:
145  if addShiftedResJetCollections:
146  variations = { "ResUp":-1., "ResDown":1. }
147  for var in variations.keys():
148  jetCollectionToKeep = \
149  addSmearedJets(process, cleanedJetCollection,
150  [ "smeared", jetCollection, var ],
151  jetSmearFileName,jetSmearHistogram,jetResolutions,
152  varyByNsigmas, variations[ var ],
153  shiftedParticleSequence, postfix)
154  jetCol={'jetCollection%s'%var:jetCollectionToKeep}
155  shiftedParticleCollections.update( jetCol )
156  collectionsToKeep.append( jetCollectionToKeep )
157 
158  #--------------------------------------------------------------------------------------------
159  # produce collection of jets shifted up/down in energy
160  #--------------------------------------------------------------------------------------------
161  if not isValidInputTag(jetCollection) or jetCollection=="":
162  print "INFO : jet collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % jetCollection
163  else:
164  shiftedJetsCollections, jetsCollectionsToKeep = addShiftedJetCollections(
165  process,jetCollection,lastJetCollection,
166  jetCorrLabelUpToL3, jetCorrLabelUpToL3Res,
167  jecUncertaintyFile, jecUncertaintyTag,
168  varyByNsigmas, shiftedParticleSequence,
169  postfix)
170  shiftedParticleCollections.update( shiftedJetsCollections )
171  collectionsToKeep.extend( jetsCollectionsToKeep )
172 
173  #--------------------------------------------------------------------------------------------
174  # produce collection of electrons shifted up/down in energy
175  #--------------------------------------------------------------------------------------------
176  if not isValidInputTag(electronCollection) or electronCollection=="":
177  print "INFO : electron collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % electronCollection
178  else:
179  shiftedElectronsCollections, electronsCollectionsToKeep = addShiftedSingleParticleCollection(
180  process, "electron", electronCollection,
181  varyByNsigmas,shiftedParticleSequence,
182  postfix)
183 
184  shiftedParticleCollections.update( shiftedElectronsCollections )
185  collectionsToKeep.extend( electronsCollectionsToKeep )
186 
187  #--------------------------------------------------------------------------------------------
188  # produce collection of (high Pt) photon candidates shifted up/down in energy
189  #--------------------------------------------------------------------------------------------
190  if not isValidInputTag(photonCollection) or photonCollection=="":
191  print "INFO : photon collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % photonCollection
192  else:
193  shiftedPhotonsCollections, photonsCollectionsToKeep = addShiftedSingleParticleCollection(
194  process, "photon", photonCollection,
195  varyByNsigmas,shiftedParticleSequence,
196  postfix)
197  shiftedParticleCollections.update( shiftedPhotonsCollections )
198  collectionsToKeep.extend( photonsCollectionsToKeep )
199 
200  #--------------------------------------------------------------------------------------------
201  # produce collection of muons shifted up/down in energy/momentum
202  #--------------------------------------------------------------------------------------------
203  if not isValidInputTag(muonCollection) or muonCollection=="":
204  print "INFO : muon collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % muonCollection
205  else:
206  shiftedMuonsCollections, muonsCollectionsToKeep = addShiftedSingleParticleCollection(process, "muon", muonCollection,
207  varyByNsigmas,shiftedParticleSequence,
208  postfix)
209  shiftedParticleCollections.update( shiftedMuonsCollections )
210  collectionsToKeep.extend( muonsCollectionsToKeep )
211 
212  #--------------------------------------------------------------------------------------------
213  # produce collection of tau-jets shifted up/down in energy
214  #--------------------------------------------------------------------------------------------
215  if not isValidInputTag(tauCollection) or tauCollection=="":
216  print "INFO : tau collection %s does not exists, no energy shifting will be performed in MET uncertainty tools" % tauCollection
217  else:
218  shiftedTausCollections, tausCollectionsToKeep = addShiftedSingleParticleCollection(process, "tau", tauCollection,
219  varyByNsigmas,shiftedParticleSequence,
220  postfix)
221  shiftedParticleCollections.update( shiftedTausCollections )
222  collectionsToKeep.extend( tausCollectionsToKeep )
223 
224 
225  return ( shiftedParticleSequence, shiftedParticleCollections, collectionsToKeep )
226 
227 
228 
229 
230 
231  def _addPFCandidatesForPFMEtInput(self, process, metUncertaintySequence,
232  particleCollection, particleType, shiftType, particleCollectionShiftUp, particleCollectionShiftDown,
233  dRmatch,
234  pfCandCollection, postfix):
235 
236  srcUnshiftedObjects = particleCollection
237  if isinstance(srcUnshiftedObjects, cms.InputTag):
238  srcUnshiftedObjects = srcUnshiftedObjects.value()
239  moduleShiftUp = cms.EDProducer("ShiftedPFCandidateProducerByMatchedObject",
240  srcPFCandidates = pfCandCollection,
241  srcUnshiftedObjects = cms.InputTag(srcUnshiftedObjects),
242  srcShiftedObjects = cms.InputTag(particleCollectionShiftUp),
243  dRmatch_PFCandidate = cms.double(dRmatch)
244  )
245  moduleNameShiftUp = "pfCandidates%s%sUp%s" % (particleType, shiftType, postfix)
246  setattr(process, moduleNameShiftUp, moduleShiftUp)
247  metUncertaintySequence += moduleShiftUp
248 
249  moduleShiftDown = moduleShiftUp.clone(
250  srcShiftedObjects = cms.InputTag(particleCollectionShiftDown)
251  )
252  moduleNameShiftDown = "pfCandidates%s%sDown%s" % (particleType, shiftType, postfix)
253  setattr(process, moduleNameShiftDown, moduleShiftDown)
254  metUncertaintySequence += moduleShiftDown
255 
256  moduleNameShifts = { 'Up':moduleNameShiftUp , 'Down':moduleNameShiftDown }
257  return moduleNameShifts
258  # return ( moduleNameShiftUp, moduleNameShiftDown )
259 
260  def _getLeptonsForPFMEtInput(self, shiftedParticleCollections, substituteKeyUnshifted = None, substituteKeyShifted = None, postfix=""):
261  retVal = []
262  for particleCol in shiftedParticleCollections.keys():
263  if not (particleCol.find("Jet") or particleCol.find("jet") ) and isValidInputTag(shiftedParticleCollections[collectionName]):
264  print collectionName,"==>:"+shiftedParticleCollections[collectionName]
265  if substituteKeyUnshifted is not None and substituteKeyUnshifted in shiftedParticleCollections.keys() and \
266  substituteKeyShifted is not None and substituteKeyShifted in shiftedParticleCollections.keys() and \
267  shiftedParticleCollections[collectionName] == shiftedParticleCollections[substituteKeyUnshifted]:
268  retVal.append(cms.InputTag(shiftedParticleCollections[substituteKeyShifted]))
269  else:
270  retVal.append(shiftedParticleCollections[collectionName])
271  return retVal
272 
273  def _addPATMEtProducer(self, process, metUncertaintySequence,
274  metCollection, patMEtCollection,
275  collectionsToKeep, postfix):
276 
277  module = patMETs.clone(
278  metSource = cms.InputTag(metCollection),
279  addMuonCorrections = cms.bool(False),
280  genMETSource = cms.InputTag('genMetTrue')
281  )
282  patMEtCollectionName = patMEtCollection+postfix
283  setattr(process, patMEtCollectionName, module)
284  metUncertaintySequence += module
285  collectionsToKeep.append(patMEtCollectionName)
286 
287 
288  def __call__(self, process,
289  electronCollection = None,
290  photonCollection = None,
291  muonCollection = None,
292  tauCollection = None,
293  jetCollection = None,
294  jetCorrLabel = None,
295  doSmearJets = None,
296  jetSmearFileName = None,
297  jetSmearHistogram = None,
298  jetCorrPayloadName = None,
299  jetCorrLabelUpToL3 = None,
300  jetCorrLabelUpToL3Res = None,
301  jecUncertaintyFile = None,
302  jecUncertaintyTag = None,
303  varyByNsigmas = None,
304  addToPatDefaultSequence = None,
305  outputModule = None,
306  postfix = None):
307  electronCollection = self._initializeInputTag(electronCollection, 'electronCollection')
308  photonCollection = self._initializeInputTag(photonCollection, 'photonCollection')
309  muonCollection = self._initializeInputTag(muonCollection, 'muonCollection')
310  tauCollection = self._initializeInputTag(tauCollection, 'tauCollection')
311  jetCollection = self._initializeInputTag(jetCollection, 'jetCollection')
312  if jetCorrLabel is None:
313  jetCorrLabel = self._defaultParameters['jetCorrLabel'].value
314  if doSmearJets is None:
315  doSmearJets = self._defaultParameters['doSmearJets'].value
316  if jetSmearFileName is None:
317  jetSmearFileName = self._defaultParameters['jetSmearFileName'].value
318  if jetSmearHistogram is None:
319  jetSmearHistogram = self._defaultParameters['jetSmearHistogram'].value
320  if jetCorrPayloadName is None:
321  jetCorrPayloadName = self._defaultParameters['jetCorrPayloadName'].value
322  if jetCorrLabelUpToL3 is None:
323  jetCorrLabelUpToL3 = self._defaultParameters['jetCorrLabelUpToL3'].value
324  if jetCorrLabelUpToL3Res is None:
325  jetCorrLabelUpToL3Res = self._defaultParameters['jetCorrLabelUpToL3Res'].value
326  if jecUncertaintyFile is None:
327  jecUncertaintyFile = self._defaultParameters['jecUncertaintyFile'].value
328  if jecUncertaintyTag is None:
329  jecUncertaintyTag = self._defaultParameters['jecUncertaintyTag'].value
330  if varyByNsigmas is None:
331  varyByNsigmas = self._defaultParameters['varyByNsigmas'].value
332  if addToPatDefaultSequence is None:
333  addToPatDefaultSequence = self._defaultParameters['addToPatDefaultSequence'].value
334  if outputModule is None:
335  outputModule = self._defaultParameters['outputModule'].value
336  if postfix is None:
337  postfix = self._defaultParameters['postfix'].value
338 
339  self.setParameter('electronCollection', electronCollection)
340  self.setParameter('photonCollection', photonCollection)
341  self.setParameter('muonCollection', muonCollection)
342  self.setParameter('tauCollection', tauCollection)
343  self.setParameter('jetCollection', jetCollection)
344  self.setParameter('jetCorrLabel', jetCorrLabel)
345  self.setParameter('doSmearJets', doSmearJets)
346  self.setParameter('jetSmearFileName', jetSmearFileName)
347  self.setParameter('jetSmearHistogram', jetSmearHistogram)
348  self.setParameter('jetCorrPayloadName', jetCorrPayloadName)
349  self.setParameter('jetCorrLabelUpToL3', jetCorrLabelUpToL3)
350  self.setParameter('jetCorrLabelUpToL3Res', jetCorrLabelUpToL3Res)
351  self.setParameter('jecUncertaintyFile', jecUncertaintyFile)
352  self.setParameter('jecUncertaintyTag', jecUncertaintyTag)
353  self.setParameter('varyByNsigmas', varyByNsigmas)
354  self.setParameter('addToPatDefaultSequence', addToPatDefaultSequence)
355  self.setParameter('outputModule', outputModule)
356  self.setParameter('postfix', postfix)
357 
MM from PhysicsTools.PatAlgos.patSequences_cff import *.
def addShiftedJetCollections
Now, jet variation for corrected METs, the default collection to use.
def addShiftedSingleParticleCollection
Up variation.