CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
pfTools.py
Go to the documentation of this file.
2 
6 
7 from PhysicsTools.PatAlgos.tools.helpers import listModules, applyPostfix
8 
9 from copy import deepcopy
10 
11 #def applyPostfix(process, label, postfix):
12 # ''' If a module is in patDefaultSequence use the cloned module.
13 # Will crash if patDefaultSequence has not been cloned with 'postfix' beforehand'''
14 # result = None
15 # defaultLabels = [ m.label()[:-len(postfix)] for m in listModules( getattr(process,"patDefaultSequence"+postfix))]
16 # if label in defaultLabels:
17 # result = getattr(process, label+postfix)
18 # else:
19 # print "WARNING: called applyPostfix for module %s which is not in patDefaultSequence!"%label
20 # result = getattr(process, label)
21 # return result
22 
23 #def removeFromSequence(process, seq, postfix, baseSeq='patDefaultSequence'):
24 # defaultLabels = [ m.label()[:-len(postfix)] for m in listModules( getattr(process,baseSeq+postfix))]
25 # for module in listModules( seq ):
26 # if module.label() in defaultLabels:
27 # getattr(process,baseSeq+postfix).remove(getattr(process, module.label()+postfix))
28 
30  print "WARNING: particle based isolation must be studied"
31 
32 from CommonTools.ParticleFlow.Tools.pfIsolation import setupPFElectronIso, setupPFMuonIso
33 
34 def useGsfElectrons(process, postfix, dR = "04"):
35  print "using Gsf Electrons in PF2PAT"
36  print "WARNING: this will destory the feature of top projection which solves the ambiguity between leptons and jets because"
37  print "WARNING: there will be overlap between non-PF electrons and jets even though top projection is ON!"
38  print "********************* "
39  module = applyPostfix(process,"patElectrons",postfix)
40  module.useParticleFlow = False
41  print "Building particle-based isolation for GsfElectrons in PF2PAT(PFBRECO)"
42  print "********************* "
43  adaptPFIsoElectrons( process, module, postfix+"PFIso", dR )
44  getattr(process,'patDefaultSequence'+postfix).replace( getattr(process,"patElectrons"+postfix),
45  setupPFElectronIso(process, 'gsfElectrons', "PFIso", postfix, runPF2PAT=True) +
46  getattr(process,"patElectrons"+postfix) )
47 
48 def adaptPFIsoElectrons(process,module, postfix = "PFIso", dR = "04"):
49  #FIXME: adaptPFElectrons can use this function.
50  module.isoDeposits = cms.PSet(
51  pfChargedHadrons = cms.InputTag("elPFIsoDepositCharged" + postfix),
52  pfChargedAll = cms.InputTag("elPFIsoDepositChargedAll" + postfix),
53  pfPUChargedHadrons = cms.InputTag("elPFIsoDepositPU" + postfix),
54  pfNeutralHadrons = cms.InputTag("elPFIsoDepositNeutral" + postfix),
55  pfPhotons = cms.InputTag("elPFIsoDepositGamma" + postfix)
56  )
57  module.isolationValues = cms.PSet(
58  pfChargedHadrons = cms.InputTag("elPFIsoValueCharged"+dR+"PFId"+ postfix),
59  pfChargedAll = cms.InputTag("elPFIsoValueChargedAll"+dR+"PFId"+ postfix),
60  pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU"+dR+"PFId" + postfix),
61  pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral"+dR+"PFId" + postfix),
62  pfPhotons = cms.InputTag("elPFIsoValueGamma"+dR+"PFId" + postfix)
63  )
64  module.isolationValuesNoPFId = cms.PSet(
65  pfChargedHadrons = cms.InputTag("elPFIsoValueCharged"+dR+"NoPFId"+ postfix),
66  pfChargedAll = cms.InputTag("elPFIsoValueChargedAll"+dR+"NoPFId"+ postfix),
67  pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU"+dR+"NoPFId" + postfix),
68  pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral"+dR+"NoPFId" + postfix),
69  pfPhotons = cms.InputTag("elPFIsoValueGamma"+dR+"NoPFId" + postfix)
70  )
71 
72 def adaptPFIsoMuons(process,module, postfix = "PFIso", dR = "04"):
73  #FIXME: adaptPFMuons can use this function.
74  module.isoDeposits = cms.PSet(
75  pfChargedHadrons = cms.InputTag("muPFIsoDepositCharged" + postfix),
76  pfChargedAll = cms.InputTag("muPFIsoDepositChargedAll" + postfix),
77  pfPUChargedHadrons = cms.InputTag("muPFIsoDepositPU" + postfix),
78  pfNeutralHadrons = cms.InputTag("muPFIsoDepositNeutral" + postfix),
79  pfPhotons = cms.InputTag("muPFIsoDepositGamma" + postfix)
80  )
81  module.isolationValues = cms.PSet(
82  pfChargedHadrons = cms.InputTag("muPFIsoValueCharged" + dR + postfix),
83  pfChargedAll = cms.InputTag("muPFIsoValueChargedAll" + dR + postfix),
84  pfPUChargedHadrons = cms.InputTag("muPFIsoValuePU" + dR + postfix),
85  pfNeutralHadrons = cms.InputTag("muPFIsoValueNeutral" + dR + postfix),
86  pfPhotons = cms.InputTag("muPFIsoValueGamma" + dR + postfix)
87  )
88 
89 def usePFIso(process, postfix = "PFIso"):
90  print "Building particle-based isolation "
91  print "***************** "
92  process.eleIsoSequence = setupPFElectronIso(process, 'gsfElectrons', postfix)
93  process.muIsoSequence = setupPFMuonIso(process, 'muons', postfix)
94  adaptPFIsoMuons( process, applyPostfix(process,"patMuons",""), postfix)
95  adaptPFIsoElectrons( process, applyPostfix(process,"patElectrons",""), postfix)
96  getattr(process,'patDefaultSequence').replace( getattr(process,"patCandidates"),
97  process.pfParticleSelectionSequence +
98  process.eleIsoSequence +
99  process.muIsoSequence +
100  getattr(process,"patCandidates") )
101 
102 def adaptPFMuons(process,module,postfix="" ):
103  print "Adapting PF Muons "
104  print "***************** "
106  print
107  module.useParticleFlow = True
108  module.pfMuonSource = cms.InputTag("pfIsolatedMuons" + postfix)
109  module.userIsolation = cms.PSet()
110  module.isoDeposits = cms.PSet(
111  pfChargedHadrons = cms.InputTag("muPFIsoDepositCharged" + postfix),
112  pfChargedAll = cms.InputTag("muPFIsoDepositChargedAll" + postfix),
113  pfPUChargedHadrons = cms.InputTag("muPFIsoDepositPU" + postfix),
114  pfNeutralHadrons = cms.InputTag("muPFIsoDepositNeutral" + postfix),
115  pfPhotons = cms.InputTag("muPFIsoDepositGamma" + postfix)
116  )
117  module.isolationValues = cms.PSet(
118  pfChargedHadrons = cms.InputTag("muPFIsoValueCharged04"+ postfix),
119  pfChargedAll = cms.InputTag("muPFIsoValueChargedAll04"+ postfix),
120  pfPUChargedHadrons = cms.InputTag("muPFIsoValuePU04" + postfix),
121  pfNeutralHadrons = cms.InputTag("muPFIsoValueNeutral04" + postfix),
122  pfPhotons = cms.InputTag("muPFIsoValueGamma04" + postfix)
123  )
124  # matching the pfMuons, not the standard muons.
125  applyPostfix(process,"muonMatch",postfix).src = module.pfMuonSource
126 
127  print " muon source:", module.pfMuonSource
128  print " isolation :",
129  print module.isolationValues
130  print " isodeposits: "
131  print module.isoDeposits
132  print
133 
134 
135 def adaptPFElectrons(process,module, postfix):
136  # module.useParticleFlow = True
137  print "Adapting PF Electrons "
138  print "********************* "
140  print
141  module.useParticleFlow = True
142  module.pfElectronSource = cms.InputTag("pfIsolatedElectrons" + postfix)
143  module.userIsolation = cms.PSet()
144  module.isoDeposits = cms.PSet(
145  pfChargedHadrons = cms.InputTag("elPFIsoDepositCharged" + postfix),
146  pfChargedAll = cms.InputTag("elPFIsoDepositChargedAll" + postfix),
147  pfPUChargedHadrons = cms.InputTag("elPFIsoDepositPU" + postfix),
148  pfNeutralHadrons = cms.InputTag("elPFIsoDepositNeutral" + postfix),
149  pfPhotons = cms.InputTag("elPFIsoDepositGamma" + postfix)
150  )
151  module.isolationValues = cms.PSet(
152  pfChargedHadrons = cms.InputTag("elPFIsoValueCharged04PFId"+ postfix),
153  pfChargedAll = cms.InputTag("elPFIsoValueChargedAll04PFId"+ postfix),
154  pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU04PFId" + postfix),
155  pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral04PFId" + postfix),
156  pfPhotons = cms.InputTag("elPFIsoValueGamma04PFId" + postfix)
157  )
158 
159  # COLIN: since we take the egamma momentum for pat Electrons, we must
160  # match the egamma electron to the gen electrons, and not the PFElectron.
161  # -> do not uncomment the line below.
162  # process.electronMatch.src = module.pfElectronSource
163  # COLIN: how do we depend on this matching choice?
164 
165  print " PF electron source:", module.pfElectronSource
166  print " isolation :"
167  print module.isolationValues
168  print " isodeposits: "
169  print module.isoDeposits
170  print
171 
172  print "removing traditional isolation"
173 
174  removeIfInSequence(process, "patElectronIsolation", "patDefaultSequence", postfix)
175 
176 def adaptPFPhotons(process,module):
177  raise RuntimeError, "Photons are not supported yet"
178 
179 from RecoTauTag.RecoTau.TauDiscriminatorTools import adaptTauDiscriminator, producerIsTauTypeMapper
180 
181 def reconfigurePF2PATTaus(process,
182  tauType='shrinkingConePFTau',
183  pf2patSelection=["DiscriminationByIsolation", "DiscriminationByLeadingPionPtCut"],
184  selectionDependsOn=["DiscriminationByLeadingTrackFinding"],
185  producerFromType=lambda producer: producer+"Producer",
186  postfix = ""):
187  print "patTaus will be produced from taus of type: %s that pass %s" \
188  % (tauType, pf2patSelection)
189 
190  #get baseSequence
191  baseSequence = getattr(process,"pfTausBaseSequence"+postfix)
192  #clean baseSequence from old modules
193  for oldBaseModuleName in baseSequence.moduleNames():
194  oldBaseModule = getattr(process,oldBaseModuleName)
195  baseSequence.remove(oldBaseModule)
196 
197  # Get the prototype of tau producer to make, i.e. fixedConePFTauProducer
198  producerName = producerFromType(tauType)
199  # Set as the source for the pf2pat taus (pfTaus) selector
200  applyPostfix(process,"pfTaus", postfix).src = producerName+postfix
201  # Start our pf2pat taus base sequence
202  oldTauSansRefs = getattr(process,'pfTausProducerSansRefs'+postfix)
203  oldTau = getattr(process,'pfTausProducer'+postfix)
204  ## copy tau and setup it properly
205  newTauSansRefs = None
206  newTau = getattr(process,producerName).clone()
207  ## adapted to new structure in RecoTauProducers PLEASE CHECK!!!
208  if tauType=='shrinkingConePFTau':
209  newTauSansRefs = getattr(process,producerName+"SansRefs").clone()
210  newTauSansRefs.modifiers[1] = cms.PSet(
211  pfTauTagInfoSrc = cms.InputTag("pfTauTagInfoProducer"+postfix),
212  name = cms.string('pfTauTTIworkaround'+postfix),
213  plugin = cms.string('RecoTauTagInfoWorkaroundModifer')
214  )
215  newTau.modifiers[1] = newTauSansRefs.modifiers[1]
216  newTauSansRefs.piZeroSrc = "pfJetsLegacyTaNCPiZeros"+postfix
217  newTau.piZeroSrc = newTauSansRefs.piZeroSrc
218  newTauSansRefs.builders[0].pfCandSrc = oldTauSansRefs.builders[0].pfCandSrc
219  newTauSansRefs.jetRegionSrc = oldTauSansRefs.jetRegionSrc
220  newTauSansRefs.jetSrc = oldTauSansRefs.jetSrc
221  elif tauType=='fixedConePFTau':
222  newTau.piZeroSrc = "pfJetsLegacyTaNCPiZeros"+postfix
223  elif tauType=='hpsPFTau':
224  newTau = process.combinatoricRecoTaus.clone()
225  newTau.piZeroSrc="pfJetsLegacyHPSPiZeros"+postfix
226  newTau.modifiers[3] = cms.PSet(
227  pfTauTagInfoSrc = cms.InputTag("pfTauTagInfoProducer"+postfix),
228  name = cms.string('pfTauTTIworkaround'+postfix),
229  plugin = cms.string('RecoTauTagInfoWorkaroundModifer')
230  )
231  from PhysicsTools.PatAlgos.tools.helpers import cloneProcessingSnippet
232  cloneProcessingSnippet(process, process.produceHPSPFTaus, postfix)
233  massSearchReplaceParam(getattr(process,"produceHPSPFTaus"+postfix),
234  "PFTauProducer",
235  cms.InputTag("combinatoricRecoTaus"),
236  cms.InputTag("pfTausBase"+postfix) )
237  massSearchReplaceParam(getattr(process,"produceHPSPFTaus"+postfix),
238  "src",
239  cms.InputTag("combinatoricRecoTaus"),
240  cms.InputTag("pfTausBase"+postfix) )
241 
242  newTau.builders[0].pfCandSrc = oldTau.builders[0].pfCandSrc
243  newTau.jetRegionSrc = oldTau.jetRegionSrc
244  newTau.jetSrc = oldTau.jetSrc
245 
246  # replace old tau producer by new one put it into baseSequence
247  setattr(process,"pfTausBase"+postfix,newTau)
248  if tauType=='shrinkingConePFTau':
249  setattr(process,"pfTausBaseSansRefs"+postfix,newTauSansRefs)
250  getattr(process,"pfTausBase"+postfix).src = "pfTausBaseSansRefs"+postfix
251  baseSequence += getattr(process,"pfTausBaseSansRefs"+postfix)
252  baseSequence += getattr(process,"pfTausBase"+postfix)
253  if tauType=='hpsPFTau':
254  baseSequence += getattr(process,"produceHPSPFTaus"+postfix)
255  #make custom mapper to take postfix into account (could have gone with lambda of lambda but... )
256  def producerIsTauTypeMapperWithPostfix(tauProducer):
257  return lambda x: producerIsTauTypeMapper(tauProducer)+x.group(1)+postfix
258 
259  def recoTauTypeMapperWithGroup(tauProducer):
260  return "%s(.*)"%recoTauTypeMapper(tauProducer)
261 
262  # Get our prediscriminants
263  for predisc in selectionDependsOn:
264  # Get the prototype
265  originalName = tauType+predisc # i.e. fixedConePFTauProducerDiscriminationByLeadingTrackFinding
266  clonedName = "pfTausBase"+predisc+postfix
267  clonedDisc = getattr(process, originalName).clone()
268  # Register in our process
269  setattr(process, clonedName, clonedDisc)
270  baseSequence += getattr(process, clonedName)
271 
272  tauCollectionToSelect = None
273  if tauType != 'hpsPFTau' :
274  tauCollectionToSelect = "pfTausBase"+postfix
275  #cms.InputTag(clonedDisc.PFTauProducer.value()+postfix)
276  else:
277  tauCollectionToSelect = "hpsPFTauProducer"+postfix
278  # Adapt this discriminator for the cloned prediscriminators
279  adaptTauDiscriminator(clonedDisc, newTauProducer="pfTausBase",
280  oldTauTypeMapper=recoTauTypeMapperWithGroup,
281  newTauTypeMapper=producerIsTauTypeMapperWithPostfix,
282  preservePFTauProducer=True)
283  clonedDisc.PFTauProducer = tauCollectionToSelect
284 
285  # Reconfigure the pf2pat PFTau selector discrimination sources
286  applyPostfix(process,"pfTaus", postfix).discriminators = cms.VPSet()
287  for selection in pf2patSelection:
288  # Get our discriminator that will be used to select pfTaus
289  originalName = tauType+selection
290  clonedName = "pfTausBase"+selection+postfix
291  clonedDisc = getattr(process, originalName).clone()
292  # Register in our process
293  setattr(process, clonedName, clonedDisc)
294 
295  tauCollectionToSelect = None
296 
297  if tauType != 'hpsPFTau' :
298  tauCollectionToSelect = cms.InputTag("pfTausBase"+postfix)
299  #cms.InputTag(clonedDisc.PFTauProducer.value()+postfix)
300  else:
301  tauCollectionToSelect = cms.InputTag("hpsPFTauProducer"+postfix)
302  #Adapt our cloned discriminator to the new prediscriminants
303  adaptTauDiscriminator(clonedDisc, newTauProducer="pfTausBase",
304  oldTauTypeMapper=recoTauTypeMapperWithGroup,
305  newTauTypeMapper=producerIsTauTypeMapperWithPostfix,
306  preservePFTauProducer=True)
307  clonedDisc.PFTauProducer = tauCollectionToSelect
308  baseSequence += clonedDisc
309  # Add this selection to our pfTau selectors
310  applyPostfix(process,"pfTaus", postfix).discriminators.append(cms.PSet(
311  discriminator=cms.InputTag(clonedName), selectionCut=cms.double(0.5)))
312  # Set the input of the final selector.
313  if tauType != 'hpsPFTau':
314  applyPostfix(process,"pfTaus", postfix).src = "pfTausBase"+postfix
315  else:
316  # If we are using HPS taus, we need to take the output of the clenaed
317  # collection
318  applyPostfix(process,"pfTaus", postfix).src = "hpsPFTauProducer"+postfix
319 
320 
321 
322 def adaptPFTaus(process,tauType = 'shrinkingConePFTau', postfix = ""):
323  # Set up the collection used as a preselection to use this tau type
324  if tauType != 'hpsPFTau' :
325  reconfigurePF2PATTaus(process, tauType, postfix=postfix)
326  else:
327  reconfigurePF2PATTaus(process, tauType,
328  ["DiscriminationByLooseCombinedIsolationDBSumPtCorr"],
329  ["DiscriminationByDecayModeFinding"],
330  postfix=postfix)
331  # new default use unselected taus (selected only for jet cleaning)
332  if tauType != 'hpsPFTau' :
333  applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("pfTausBase"+postfix)
334  else:
335  applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("hpsPFTauProducer"+postfix)
336  # to use preselected collection (old default) uncomment line below
337  #applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("pfTaus"+postfix)
338 
339 
340  redoPFTauDiscriminators(process,
341  cms.InputTag(tauType+'Producer'),
342  applyPostfix(process,"patTaus", postfix).tauSource,
343  tauType, postfix=postfix)
344 
345  switchToPFTauByType(process, pfTauType=tauType,
346  pfTauLabelNew=applyPostfix(process,"patTaus", postfix).tauSource,
347  pfTauLabelOld=cms.InputTag(tauType+'Producer'),
348  postfix=postfix)
349 
350  applyPostfix(process,"makePatTaus", postfix).remove(
351  applyPostfix(process,"patPFCandidateIsoDepositSelection", postfix)
352  )
353 
354 #helper function for PAT on PF2PAT sample
355 def tauTypeInPF2PAT(process,tauType='shrinkingConePFTau', postfix = ""):
356  process.load("CommonTools.ParticleFlow.pfTaus_cff")
357  applyPostfix(process, "pfTaus",postfix).src = cms.InputTag(tauType+'Producer'+postfix)
358 
359 
360 def addPFCandidates(process,src,patLabel='PFParticles',cut="",postfix=""):
361  from PhysicsTools.PatAlgos.producersLayer1.pfParticleProducer_cfi import patPFParticles
362  # make modules
363  producer = patPFParticles.clone(pfCandidateSource = src)
364  filter = cms.EDFilter("PATPFParticleSelector",
365  src = cms.InputTag("pat" + patLabel),
366  cut = cms.string(cut))
367  counter = cms.EDFilter("PATCandViewCountFilter",
368  minNumber = cms.uint32(0),
369  maxNumber = cms.uint32(999999),
370  src = cms.InputTag("pat" + patLabel))
371  # add modules to process
372  setattr(process, "pat" + patLabel, producer)
373  setattr(process, "selectedPat" + patLabel, filter)
374  setattr(process, "countPat" + patLabel, counter)
375  # insert into sequence
376  getattr(process, "patDefaultSequence"+postfix).replace(
377  applyPostfix(process, "patCandidateSummary", postfix),
378  producer+applyPostfix(process, "patCandidateSummary", postfix)
379  )
380  getattr(process, "patDefaultSequence"+postfix).replace(
381  applyPostfix(process, "selectedPatCandidateSummary", postfix),
382  filter+applyPostfix(process, "selectedPatCandidateSummary", postfix)
383  )
384  index = len( applyPostfix( process, "patDefaultSequence", postfix ).moduleNames() )
385  applyPostfix( process, "patDefaultSequence", postfix ).insert( index, counter )
386  # summary tables
387  applyPostfix(process, "patCandidateSummary", postfix).candidates.append(cms.InputTag('pat' + patLabel))
388  applyPostfix(process, "selectedPatCandidateSummary", postfix).candidates.append(cms.InputTag('selectedPat' + patLabel))
389 
390 
391 def switchToPFMET(process,input=cms.InputTag('pfMET'), type1=False, postfix=""):
392  print 'MET: using ', input
393  if( not type1 ):
394  oldMETSource = applyPostfix(process, "patMETs",postfix).metSource
395  applyPostfix(process, "patMETs",postfix).metSource = input
396  applyPostfix(process, "patMETs",postfix).addMuonCorrections = False
397  getattr(process, "patDefaultSequence"+postfix).remove(applyPostfix(process, "patMETCorrections",postfix))
398  else:
399  # type1 corrected MET
400  # name of corrected MET hardcoded in PAT and meaningless
401  print 'Apply TypeI corrections for MET'
402  getattr(process, "patDefaultSequence"+postfix).remove(applyPostfix(process, "makePatMETs",postfix))
403  jecLabel = getattr(process,'patJetCorrFactors'+postfix).levels
404 
405  if not hasattr(process,'producePatPFMETCorrections'):
406  process.load("PhysicsTools.PatUtils.patPFMETCorrections_cff")
407  #here add to the current path and give proper postfix
408  if not hasattr(process,'producePatPFMETCorrections'+postfix):
409  cloneProcessingSnippet(process,process.producePatPFMETCorrections,postfix)
410 
411  getattr(process,'patPFMet'+postfix).metSource = cms.InputTag('pfMET'+postfix)
412 
413  getattr(process,'selectedPatJetsForMETtype1p2Corr'+postfix).src = cms.InputTag('selectedPatJets'+postfix)
414  getattr(process,'selectedPatJetsForMETtype2Corr'+postfix).src = cms.InputTag('selectedPatJets'+postfix)
415 
416  getattr(process,'pfCandMETcorr'+postfix).src = cms.InputTag('pfNoJet'+postfix)
417 
418  getattr(process,'patPFJetMETtype1p2Corr'+postfix).offsetCorrLabel = cms.string(jecLabel[0])
419  getattr(process,'patPFJetMETtype1p2Corr'+postfix).jetCorrLabel = cms.string(jecLabel[-1])
420  getattr(process,'patPFJetMETtype1p2Corr'+postfix).type1JetPtThreshold = cms.double(10.0)
421  getattr(process,'patPFJetMETtype1p2Corr'+postfix).skipEM = cms.bool(False)
422  getattr(process,'patPFJetMETtype1p2Corr'+postfix).skipMuons = cms.bool(False)
423 
424  getattr(process,'patPFJetMETtype2Corr'+postfix).offsetCorrLabel = cms.string(jecLabel[0])
425  getattr(process,'patPFJetMETtype2Corr'+postfix).jetCorrLabel = cms.string(jecLabel[-1])
426  getattr(process,'patPFJetMETtype2Corr'+postfix).type1JetPtThreshold = cms.double(10.0)
427  getattr(process,'patPFJetMETtype2Corr'+postfix).skipEM = cms.bool(False)
428  getattr(process,'patPFJetMETtype2Corr'+postfix).skipMuons = cms.bool(False)
429 
430  getattr(process,'patType1CorrectedPFMet'+postfix).srcType1Corrections = cms.VInputTag(
431  cms.InputTag("patPFJetMETtype1p2Corr"+postfix,"type1"),
432  #cms.InputTag("patPFMETtype0Corr"+postfix),
433  )
434  getattr(process,'patType1p2CorrectedPFMet'+postfix).srcType1Corrections = cms.VInputTag(
435  cms.InputTag("patPFJetMETtype1p2Corr"+postfix,"type1"),
436  #cms.InputTag("patPFMETtype0Corr"+postfix),
437  )
438 
439  getattr(process,'patMETs'+postfix).metSource = 'patType1CorrectedPFMet'+postfix
440 
441  getattr(process,"patDefaultSequence"+postfix).replace( getattr(process,'selectedPatJets'+postfix),
442  getattr(process,'selectedPatJets'+postfix)
443  *getattr(process,'producePatPFMETCorrections'+postfix)
444  *getattr(process,'patMETs'+postfix)
445  )
446 
447 def switchToPFJets(process, input=cms.InputTag('pfNoTau'), algo='AK5', postfix = "", jetCorrections=('AK5PFchs', ['L1FastJet','L2Relative', 'L3Absolute']), type1=False, outputModules=['out']):
448 
449  print "Switching to PFJets, ", algo
450  print "************************ "
451  print "input collection: ", input
452 
453  if( algo == 'IC5' ):
454  genJetCollection = cms.InputTag('iterativeCone5GenJetsNoNu')
455  elif algo == 'AK5':
456  genJetCollection = cms.InputTag('ak5GenJetsNoNu')
457  elif algo == 'AK7':
458  genJetCollection = cms.InputTag('ak7GenJetsNoNu')
459  else:
460  print 'bad jet algorithm:', algo, '! for now, only IC5, AK5 and AK7 are allowed. If you need other algorithms, please contact Colin'
461  sys.exit(1)
462 
463  # changing the jet collection in PF2PAT:
464  from CommonTools.ParticleFlow.Tools.jetTools import jetAlgo
465  inputCollection = getattr(process,"pfJets"+postfix).src
466  setattr(process,"pfJets"+postfix,jetAlgo(algo)) # problem for cfgBrowser
467  getattr(process,"pfJets"+postfix).src = inputCollection
468  inputJetCorrLabel=jetCorrections
469  switchJetCollection(process,
470  input,
471  jetIdLabel = algo,
472  doJTA=True,
473  doBTagging=True,
474  jetCorrLabel=inputJetCorrLabel,
475  doType1MET=type1,
476  genJetCollection = genJetCollection,
477  doJetID = True,
478  postfix = postfix,
479  outputModules = outputModules
480  )
481  # check whether L1FastJet is in the list of correction levels or not
482  applyPostfix(process, "patJetCorrFactors", postfix).useRho = False
483  for corr in inputJetCorrLabel[1]:
484  if corr == 'L1FastJet':
485  applyPostfix(process, "patJetCorrFactors", postfix).useRho = True
486  applyPostfix(process, "pfJets", postfix).doAreaFastjet = True
487  # do correct treatment for TypeI MET corrections
488  if type1:
489  for mod in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
490  if mod.startswith("kt6") and mod.endswith("Jets"+postfix):
491  prefix = mod.replace(postfix,'')
492  prefix = prefix.replace('kt6PFJets','')
493  prefix = prefix.replace('kt6CaloJets','')
494  prefix = getattr(process,'patJetCorrFactors'+prefix+postfix).payload.pythonValue().replace("'","")
495  for essource in process.es_sources_().keys():
496  if essource == prefix+'L1FastJet':
497  setattr(process,essource+postfix,getattr(process,essource).clone(srcRho=cms.InputTag(mod,'rho')))
498  setattr(process,prefix+'CombinedCorrector'+postfix,getattr(process,prefix+'CombinedCorrector').clone())
499  getattr(process,prefix+'CorMet'+postfix).corrector = prefix+'CombinedCorrector'+postfix
500  for cor in getattr(process,prefix+'CombinedCorrector'+postfix).correctors:
501  if cor == essource:
502  idx = getattr(process,prefix+'CombinedCorrector'+postfix).correctors.index(essource);
503  getattr(process,prefix+'CombinedCorrector'+postfix).correctors[idx] = essource+postfix
504 
505  applyPostfix(process, "patJets", postfix).embedCaloTowers = False
506  applyPostfix(process, "patJets", postfix).embedPFCandidates = True
507 
508 #-- Remove MC dependence ------------------------------------------------------
509 def removeMCMatchingPF2PAT( process, postfix="", outputModules=['out'] ):
510  from PhysicsTools.PatAlgos.tools.coreTools import removeMCMatching
511  removeIfInSequence(process, "genForPF2PATSequence", "patDefaultSequence", postfix)
512  removeMCMatching(process, names=['All'], postfix=postfix, outputModules=outputModules)
513 
514 
515 def adaptPVs(process, pvCollection=cms.InputTag('offlinePrimaryVertices'), postfix=''):
516 
517  print "Switching PV collection for PF2PAT:", pvCollection
518  print "***********************************"
519 
520  # PV sources to be exchanged:
521  pvExchange = ['Vertices','vertices','pvSrc','primaryVertices','srcPVs']
522  # PV sources NOT to be exchanged:
523  #noPvExchange = ['src','PVProducer','primaryVertexSrc','vertexSrc','primaryVertex']
524 
525  # find out all added jet collections (they don't belong to PF2PAT)
526  interPostfixes = []
527  for m in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
528  if m.startswith('patJets') and m.endswith(postfix) and not len(m)==len('patJets')+len(postfix):
529  interPostfix = m.replace('patJets','')
530  interPostfix = interPostfix.replace(postfix,'')
531  interPostfixes.append(interPostfix)
532 
533  # exchange the primary vertex source of all relevant modules
534  for m in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
535  modName = m.replace(postfix,'')
536  # only if the module has a source with a relevant name
537  for namePvSrc in pvExchange:
538  if hasattr(getattr(process,m),namePvSrc):
539  # only if the module is not coming from an added jet collection
540  interPostFixFlag = False
541  for pfix in interPostfixes:
542  if modName.endswith(pfix):
543  interPostFixFlag = True
544  break
545  if not interPostFixFlag:
546  setattr(getattr(process,m),namePvSrc,deepcopy(pvCollection))
547 
548 
549 def usePF2PAT(process, runPF2PAT=True, jetAlgo='AK5', runOnMC=True, postfix="", jetCorrections=('AK5PFchs', ['L1FastJet','L2Relative','L3Absolute']), pvCollection=cms.InputTag('offlinePrimaryVertices'), typeIMetCorrections=False, outputModules=['out']):
550  # PLEASE DO NOT CLOBBER THIS FUNCTION WITH CODE SPECIFIC TO A GIVEN PHYSICS OBJECT.
551  # CREATE ADDITIONAL FUNCTIONS IF NEEDED.
552 
553  """Switch PAT to use PF2PAT instead of AOD sources. if 'runPF2PAT' is true, we'll also add PF2PAT in front of the PAT sequence"""
554 
555  # -------- CORE ---------------
556  if runPF2PAT:
557  process.load("CommonTools.ParticleFlow.PF2PAT_cff")
558  #add Pf2PAT *before* cloning so that overlapping modules are cloned too
559  #process.patDefaultSequence.replace( process.patCandidates, process.PF2PAT+process.patCandidates)
560  process.patPF2PATSequence = cms.Sequence( process.PF2PAT + process.patDefaultSequence)
561  else:
562  process.patPF2PATSequence = cms.Sequence( process.patDefaultSequence )
563 
564  if not postfix == "":
565  from PhysicsTools.PatAlgos.tools.helpers import cloneProcessingSnippet
566  cloneProcessingSnippet(process, process.patPF2PATSequence, postfix)
567  #delete everything pat PF2PAT modules! if you want to test the postfixing for completeness
568  #from PhysicsTools.PatAlgos.tools.helpers import listModules,listSequences
569  #for module in listModules(process.patDefaultSequence):
570  # if not module.label() is None: process.__delattr__(module.label())
571  #for sequence in listSequences(process.patDefaultSequence):
572  # if not sequence.label() is None: process.__delattr__(sequence.label())
573  #del process.patDefaultSequence
574 
575  removeCleaning(process, postfix=postfix, outputModules=outputModules)
576 
577  # -------- OBJECTS ------------
578  # Muons
579  adaptPFMuons(process,
580  applyPostfix(process,"patMuons",postfix),
581  postfix)
582 
583  # Electrons
584  adaptPFElectrons(process,
585  applyPostfix(process,"patElectrons",postfix),
586  postfix)
587 
588  # Photons
589  print "Temporarily switching off photons completely"
590 
591  removeSpecificPATObjects(process,names=['Photons'],outputModules=outputModules,postfix=postfix)
592  removeIfInSequence(process,"patPhotonIsolation","patDefaultSequence",postfix)
593 
594  # Jets
595  if runOnMC :
596  switchToPFJets( process, cms.InputTag('pfNoTau'+postfix), jetAlgo, postfix=postfix,
597  jetCorrections=jetCorrections, type1=typeIMetCorrections, outputModules=outputModules )
598  applyPostfix(process,"patDefaultSequence",postfix).replace(
599  applyPostfix(process,"patJetGenJetMatch",postfix),
600  getattr(process,"genForPF2PATSequence") *
601  applyPostfix(process,"patJetGenJetMatch",postfix)
602  )
603  else :
604  if not 'L2L3Residual' in jetCorrections[1]:
605  print '#################################################'
606  print 'WARNING! Not using L2L3Residual but this is data.'
607  print 'If this is okay with you, disregard this message.'
608  print '#################################################'
609  switchToPFJets( process, cms.InputTag('pfNoTau'+postfix), jetAlgo, postfix=postfix,
610  jetCorrections=jetCorrections, type1=typeIMetCorrections, outputModules=outputModules )
611 
612  # Taus
613  #adaptPFTaus( process, tauType='shrinkingConePFTau', postfix=postfix )
614  #adaptPFTaus( process, tauType='fixedConePFTau', postfix=postfix )
615  adaptPFTaus( process, tauType='hpsPFTau', postfix=postfix )
616 
617  # MET
618  switchToPFMET(process, cms.InputTag('pfMET'+postfix), type1=typeIMetCorrections, postfix=postfix)
619  if not runOnMC :
620  if hasattr(process,'patPFMet'+postfix):
621  getattr(process,'patPFMet'+postfix).addGenMET = cms.bool(False)
622 
623  # Unmasked PFCandidates
624  addPFCandidates(process,cms.InputTag('pfNoJet'+postfix),patLabel='PFParticles'+postfix,cut="",postfix=postfix)
625 
626  # adapt primary vertex collection
627  adaptPVs(process, pvCollection=pvCollection, postfix=postfix)
628 
629  if runOnMC:
630  process.load("CommonTools.ParticleFlow.genForPF2PAT_cff")
631  getattr(process, "patDefaultSequence"+postfix).replace(
632  applyPostfix(process,"patCandidates",postfix),
633  process.genForPF2PATSequence+applyPostfix(process,"patCandidates",postfix)
634  )
635  else:
636  removeMCMatchingPF2PAT(process,postfix=postfix,outputModules=outputModules)
637 
638  print "Done: PF2PAT interfaced to PAT, postfix=", postfix
def setupPFMuonIso
Definition: pfIsolation.py:112
def adaptPFPhotons
Definition: pfTools.py:176
def switchToPFMET
Definition: pfTools.py:391
def adaptPFTaus
Definition: pfTools.py:322
def tauTypeInPF2PAT
Definition: pfTools.py:355
string jetAlgo
Jet configuration.
def adaptPFIsoMuons
Definition: pfTools.py:72
def replace
Definition: linker.py:10
def adaptPFMuons
Definition: pfTools.py:102
def cloneProcessingSnippet
Definition: helpers.py:262
def removeMCMatchingPF2PAT
Definition: pfTools.py:509
def redoPFTauDiscriminators
Definition: tauTools.py:12
def reconfigurePF2PATTaus
Definition: pfTools.py:186
def applyPostfix
Helpers to perform some technically boring tasks like looking for all modules with a given parameter ...
Definition: helpers.py:6
def usePF2PAT
Definition: pfTools.py:549
def massSearchReplaceParam
Definition: helpers.py:205
def addPFCandidates
Definition: pfTools.py:360
def adaptPVs
Definition: pfTools.py:515
def adaptPFElectrons
Definition: pfTools.py:135
def switchToPFJets
Definition: pfTools.py:447
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
def useGsfElectrons
Definition: pfTools.py:34
def warningIsolation
Definition: pfTools.py:29
perl if(1 lt scalar(@::datatypes))
Definition: edlooper.cc:31
def removeIfInSequence
Definition: helpers.py:20
def usePFIso
Definition: pfTools.py:89
def switchToPFTauByType
Definition: tauTools.py:404
def setupPFElectronIso
Definition: pfIsolation.py:121
bool insert(Storage &, ItemType *, const IdTag &)
def adaptPFIsoElectrons
Definition: pfTools.py:48