CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
adaptToRunAtMiniAOD.py
Go to the documentation of this file.
1 import FWCore.ParameterSet.Config as cms
2 
3 ######
4 # Tools to adapt Tau sequences to run tau ReReco+PAT at MiniAOD samples
5 # M. Bluj, NCBJ Warsaw
6 # based on work of J. Steggemann, CERN
7 # Created: 9 Nov. 2017
8 ######
9 
10 import PhysicsTools.PatAlgos.tools.helpers as configtools
11 #####
12 class adaptToRunAtMiniAOD(object):
13  def __init__(self, process, runBoosted=False, postfix=""):
14  self.process = process
15  self.runBoosted = runBoosted
16  self.postfix = postfix
17  if runBoosted:
18  self.postfix = 'Boosted'+postfix
19  #print("Adapting boosted tau reconstruction to run at miniAOD; postfix = \"%s\"" % self.postfix)
20  #else:
21  # print("Adapting tau reconstruction to run at miniAOD; postfix = \"%s\"" % self.postfix)
22 
23  #####
24  def addTauReReco(self):
25  #PAT
26  self.process.load('PhysicsTools.PatAlgos.producersLayer1.tauProducer_cff')
27  self.process.load('PhysicsTools.PatAlgos.selectionLayer1.tauSelector_cfi')
28  self.process.selectedPatTaus.cut="pt > 18. && tauID(\'decayModeFindingNewDMs\')> 0.5" #Cut as in MiniAOD
29  #Tau RECO
30  self.process.load("RecoTauTag.Configuration.RecoPFTauTag_cff")
31  #Task/Sequence for tau rereco
32  self.process.miniAODTausTask = cms.Task(
33  self.process.PFTauTask,
34  self.process.makePatTausTask,
35  self.process.selectedPatTaus
36  )
37  self.miniAODTausTask = configtools.cloneProcessingSnippetTask(
38  self.process,self.process.miniAODTausTask,postfix=self.postfix)
39  setattr(self.process,'miniAODTausSequence'+self.postfix,cms.Sequence(self.miniAODTausTask))
40  if not self.postfix=="":
41  del self.process.miniAODTausTask
42 
43  #####
45  module = getattr(self.process, name)
46  if hasattr(module, 'particleFlowSrc'):
47  module.particleFlowSrc = cms.InputTag("packedPFCandidates", "", "")
48  if hasattr(module, 'vertexSrc'):
49  module.vertexSrc = cms.InputTag('offlineSlimmedPrimaryVertices')
50  if hasattr(module, 'qualityCuts') and hasattr(module.qualityCuts, 'primaryVertexSrc'):
51  module.qualityCuts.primaryVertexSrc = cms.InputTag('offlineSlimmedPrimaryVertices')
52 
53  #####
54  def adaptTauToMiniAODReReco(self,reclusterJets=True):
55  # TRYING TO MAKE THINGS MINIAOD COMPATIBLE, FROM THE START, TO THE END, 1 BY 1
56  #print '[adaptTauToMiniAODReReco]: Start'
57  jetCollection = 'slimmedJets'
58  # Add new jet collections if reclustering is demanded
59  if self.runBoosted:
60  jetCollection = 'boostedTauSeedsPAT'+self.postfix
61  from RecoTauTag.Configuration.boostedHPSPFTaus_cff import ca8PFJetsCHSprunedForBoostedTaus
62  setattr(self.process,'ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix,ca8PFJetsCHSprunedForBoostedTaus.clone(
63  src = 'packedPFCandidates',
64  jetCollInstanceName = 'subJetsForSeedingBoostedTausPAT'
65  ))
66  setattr(self.process,'boostedTauSeedsPAT'+self.postfix,
67  cms.EDProducer("PATBoostedTauSeedsProducer",
68  subjetSrc = cms.InputTag('ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix,'subJetsForSeedingBoostedTausPAT'),
69  pfCandidateSrc = cms.InputTag('packedPFCandidates'),
70  verbosity = cms.int32(0)
71  ))
72  self.miniAODTausTask.add(getattr(self.process,'ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix))
73  self.miniAODTausTask.add(getattr(self.process,'boostedTauSeedsPAT'+self.postfix))
74  elif reclusterJets:
75  jetCollection = 'patJetsPAT'+self.postfix
76  from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets
77  setattr(self.process,'ak4PFJetsPAT'+self.postfix,ak4PFJets.clone(
78  src = "packedPFCandidates"
79  ))
80  # trivial PATJets
82  setattr(self.process,'patJetsPAT'+self.postfix,_patJets.clone(
83  jetSource = "ak4PFJetsPAT"+self.postfix,
84  addJetCorrFactors = False,
85  jetCorrFactorsSource = [],
86  addBTagInfo = False,
87  addDiscriminators = False,
88  discriminatorSources = [],
89  addAssociatedTracks = False,
90  addJetCharge = False,
91  addGenPartonMatch = False,
92  embedGenPartonMatch = False,
93  addGenJetMatch = False,
94  getJetMCFlavour = False,
95  addJetFlavourInfo = False,
96  ))
97  self.miniAODTausTask.add(getattr(self.process,'ak4PFJetsPAT'+self.postfix))
98  self.miniAODTausTask.add(getattr(self.process,'patJetsPAT'+self.postfix))
99 
100  # so this adds all tracks to jet in some deltaR region. we don't have tracks so don't need it :D
101  # self.process.ak4PFJetTracksAssociatorAtVertex.jets = cms.InputTag(jetCollection)
102 
103  # Remove ak4PFJetTracksAssociatorAtVertex from recoTauCommonSequence
104  # Remove pfRecoTauTagInfoProducer from recoTauCommonSequence since it uses the jet-track association
105  # HOWEVER, may use https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookMiniAOD2017#Isolated_Tracks
106  # probably needs recovery of the two modules above
107  self.miniAODTausTask.remove(getattr(self.process,'ak4PFJetTracksAssociatorAtVertex'+self.postfix))
108  self.miniAODTausTask.remove(getattr(self.process,'pfRecoTauTagInfoProducer'+self.postfix))
109 
110  self.miniAODTausTask.remove(getattr(self.process,'recoTauAK4PFJets08Region'+self.postfix))
111  setattr(self.process,'recoTauAK4Jets08RegionPAT'+self.postfix,
112  cms.EDProducer("RecoTauPatJetRegionProducer",
113  deltaR = self.process.recoTauAK4PFJets08Region.deltaR,
114  maxJetAbsEta = self.process.recoTauAK4PFJets08Region.maxJetAbsEta,
115  minJetPt = self.process.recoTauAK4PFJets08Region.minJetPt,
116  pfCandAssocMapSrc = cms.InputTag(""),
117  pfCandSrc = cms.InputTag("packedPFCandidates"),
118  src = cms.InputTag(jetCollection)
119  ))
120  _jetRegionProducer = getattr(self.process,'recoTauAK4Jets08RegionPAT'+self.postfix)
121  self.miniAODTausTask.add(_jetRegionProducer)
122  if self.runBoosted:
123  _jetRegionProducer.pfCandAssocMapSrc = cms.InputTag(jetCollection, 'pfCandAssocMapForIsolation')
124 
125  getattr(self.process,'recoTauPileUpVertices'+self.postfix).src = "offlineSlimmedPrimaryVertices"
126 
127  for moduleName in self.miniAODTausTask.moduleNames():
128  self.convertModuleToMiniAODInput(moduleName)
129 
130 
131  # Adapt TauPiZeros producer
132  _piZeroProducer = getattr(self.process,'ak4PFJetsLegacyHPSPiZeros'+self.postfix)
133  for builder in _piZeroProducer.builders:
134  builder.qualityCuts.primaryVertexSrc = "offlineSlimmedPrimaryVertices"
135  _piZeroProducer.jetSrc = jetCollection
136 
137  # Adapt TauChargedHadrons producer
138  _chargedHadronProducer = getattr(self.process,'ak4PFJetsRecoTauChargedHadrons'+self.postfix)
139  for builder in _chargedHadronProducer.builders:
140  builder.qualityCuts.primaryVertexSrc = "offlineSlimmedPrimaryVertices"
141  if builder.name.value() == 'tracks': #replace plugin based on generalTracks by one based on lostTracks
142  builder.name = 'lostTracks'
143  builder.plugin = 'PFRecoTauChargedHadronFromLostTrackPlugin'
144  builder.srcTracks = "lostTracks"
145  if self.runBoosted:
146  builder.dRcone = 0.3
147  builder.dRconeLimitedToJetArea = True
148  _chargedHadronProducer.jetSrc = jetCollection
149 
150  # Adapt combinatoricRecoTau producer
151  _combinatoricRecoTauProducer = getattr(self.process,'combinatoricRecoTaus'+self.postfix)
152  _combinatoricRecoTauProducer.jetRegionSrc = 'recoTauAK4Jets08RegionPAT'+self.postfix
153  _combinatoricRecoTauProducer.jetSrc = jetCollection
154  # Adapt builders
155  for builder in _combinatoricRecoTauProducer.builders:
156  for name,value in builder.parameters_().items():
157  if name == 'qualityCuts':
158  builder.qualityCuts.primaryVertexSrc = 'offlineSlimmedPrimaryVertices'
159  elif name == 'pfCandSrc':
160  builder.pfCandSrc = 'packedPFCandidates'
161  # Adapt supported modifiers and remove unsupported ones
162  _modifiersToRemove = cms.VPSet()
163  for mod in _combinatoricRecoTauProducer.modifiers:
164  if mod.name.value() == 'elec_rej':
165  _modifiersToRemove.append(mod)
166  continue
167  elif mod.name.value() == 'TTIworkaround':
168  _modifiersToRemove.append(mod)
169  continue
170  for name,value in mod.parameters_().items():
171  if name == 'qualityCuts':
172  mod.qualityCuts.primaryVertexSrc = 'offlineSlimmedPrimaryVertices'
173  for mod in _modifiersToRemove:
174  _combinatoricRecoTauProducer.modifiers.remove(mod)
175  #print "\t\t Removing '%s' modifier from 'combinatoricRecoTaus'" %mod.name.value()
176 
177  # Redefine tau PV producer
178  _tauPVProducer = getattr(self.process,'hpsPFTauPrimaryVertexProducer'+self.postfix)
179  _tauPVProducer.__dict__['_TypedParameterizable__type'] = 'PFTauMiniAODPrimaryVertexProducer'
180  _tauPVProducer.PVTag = 'offlineSlimmedPrimaryVertices'
181  _tauPVProducer.packedCandidatesTag = cms.InputTag("packedPFCandidates")
182  _tauPVProducer.lostCandidatesTag = cms.InputTag("lostTracks")
183 
184  # Redefine tau SV producer
185  setattr(self.process,'hpsPFTauSecondaryVertexProducer'+self.postfix,
186  cms.EDProducer("PFTauSecondaryVertexProducer",
187  PFTauTag = cms.InputTag("hpsPFTauProducer"+self.postfix)
188  ))
189 
190  # Remove RecoTau producers which are not supported (yet?), i.e. against-e/mu discriminats
191  for moduleName in self.miniAODTausTask.moduleNames():
192  if 'ElectronRejection' in moduleName or 'MuonRejection' in moduleName:
193  if 'ByDeadECALElectronRejection' in moduleName: continue
194  self.miniAODTausTask.remove(getattr(self.process, moduleName))
195 
196  # Instead add against-mu discriminants which are MiniAOD compatible
197  from RecoTauTag.RecoTau.hpsPFTauDiscriminationByMuonRejectionSimple_cff import hpsPFTauDiscriminationByMuonRejectionSimple
198 
199  setattr(self.process,'hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix,
200  hpsPFTauDiscriminationByMuonRejectionSimple.clone(
201  PFTauProducer = "hpsPFTauProducer"+self.postfix))
202  _tauIDAntiMuSimple = getattr(self.process,'hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix)
203  if self.runBoosted:
204  _tauIDAntiMuSimple.dRmuonMatch = 0.1
205  self.miniAODTausTask.add(_tauIDAntiMuSimple)
206 
207  #####
208  # PAT part in the following
209 
210  getattr(self.process,'tauGenJets'+self.postfix).GenParticles = "prunedGenParticles"
211  getattr(self.process,'tauMatch'+self.postfix).matched = "prunedGenParticles"
212 
213  # Remove unsupported tauIDs
214  _patTauProducer = getattr(self.process,'patTaus'+self.postfix)
215  for name,src in _patTauProducer.tauIDSources.parameters_().items():
216  if name.find('againstElectron') > -1 or name.find('againstMuon') > -1:
217  if name.find('againstElectronDeadECAL') > -1: continue
218  delattr(_patTauProducer.tauIDSources,name)
219  # Add MiniAOD specific ones
220  setattr(_patTauProducer.tauIDSources,'againstMuonLooseSimple',
221  cms.PSet(inputTag = cms.InputTag('hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix),
222  provenanceConfigLabel = cms.string('IDWPdefinitions'),
223  idLabel = cms.string('ByLooseMuonRejectionSimple')
224  ))
225  setattr(_patTauProducer.tauIDSources,'againstMuonTightSimple',
226  cms.PSet(inputTag = cms.InputTag('hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix),
227  provenanceConfigLabel = cms.string('IDWPdefinitions'),
228  idLabel = cms.string('ByTightMuonRejectionSimple')
229  ))
230 
231  # Run TauIDs (anti-e && deepTau) on top of selectedPatTaus
232  _updatedTauName = 'selectedPatTausNewIDs'+self.postfix
233  _noUpdatedTauName = 'selectedPatTausNoNewIDs'+self.postfix
234  toKeep = ['againstEle2018']
235  if not self.runBoosted:
236  toKeep.append('deepTau2017v2p1')
237  import RecoTauTag.RecoTau.tools.runTauIdMVA as tauIdConfig
238  tauIdEmbedder = tauIdConfig.TauIDEmbedder(
239  self.process, debug = False,
240  originalTauName = _noUpdatedTauName,
241  updatedTauName = _updatedTauName,
242  postfix = "MiniAODTaus"+self.postfix,
243  toKeep = toKeep
244  )
245  tauIdEmbedder.runTauID()
246  setattr(self.process, _noUpdatedTauName, getattr(self.process,'selectedPatTaus'+self.postfix).clone())
247  self.miniAODTausTask.add(getattr(self.process,_noUpdatedTauName))
248  delattr(self.process, 'selectedPatTaus'+self.postfix)
249  setattr(self.process,'selectedPatTaus'+self.postfix,getattr(self.process, _updatedTauName).clone())
250  delattr(self.process, _updatedTauName)
251  setattr(self.process,'newTauIDsTask'+self.postfix,cms.Task(
252  getattr(self.process,'rerunMvaIsolationTaskMiniAODTaus'+self.postfix),
253  getattr(self.process,'selectedPatTaus'+self.postfix)
254  ))
255  self.miniAODTausTask.add(getattr(self.process,'newTauIDsTask'+self.postfix))
256 
257  #print '[adaptTauToMiniAODReReco]: Done!'
258 
259  #####
260  def setOutputModule(self,mode=0):
261  #mode = 0: store original MiniAOD and new selectedPatTaus
262  #mode = 1: store original MiniAOD, new selectedPatTaus, and all PFTau products as in AOD (except of unsuported ones), plus a few additional collections (charged hadrons, pi zeros, combinatoric reco taus)
263 
265  output = cms.OutputModule(
266  'PoolOutputModule',
267  fileName=cms.untracked.string('miniAOD_TauReco.root'),
268  fastCloning=cms.untracked.bool(False),
269  dataset=cms.untracked.PSet(
270  dataTier=cms.untracked.string('MINIAODSIM'),
271  filterName=cms.untracked.string('')
272  ),
273  outputCommands = evtContent.MINIAODSIMEventContent.outputCommands,
274  SelectEvents=cms.untracked.PSet(
275  SelectEvents=cms.vstring('*',)
276  )
277  )
278  output.outputCommands.append('keep *_selectedPatTaus'+self.postfix+'_*_*')
279  if mode==1:
280  import re
281  for prod in evtContent.RecoTauTagAOD.outputCommands:
282  if prod.find('ElectronRejection') > -1 and prod.find('DeadECAL') == -1:
283  continue
284  if prod.find('MuonRejection') > -1:
285  continue
286  if prod.find("_*_*")>-1: # products w/o instance
287  output.outputCommands.append(prod.replace("_*_*",self.postfix+"_*_*"))
288  else: # check if there are prods with instance
289  m = re.search(r'_[A-Za-z0-9]+_\*', prod)
290  if m!=None:
291  inst = m.group(0)
292  output.outputCommands.append(prod.replace(inst,self.postfix+inst))
293  else:
294  print("Warning: \"%s\" do not match known name patterns; trying to keep w/o postfix" % prod)
295  output.outputCommands.append(prod)
296 
297  output.outputCommands.append('keep *_hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix+'_*_*')
298  output.outputCommands.append('keep *_combinatoricReco*_*_*')
299  output.outputCommands.append('keep *_ak4PFJetsRecoTauChargedHadrons'+self.postfix+'_*_*')
300  output.outputCommands.append('keep *_ak4PFJetsLegacyHPSPiZeros'+self.postfix+'_*_*')
301  output.outputCommands.append('keep *_patJetsPAT'+self.postfix+'_*_*')
302  output.outputCommands.append('keep *_boostedTauSeedsPAT'+self.postfix+'_*_*')
303 
304  return output
305 
306 #####
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135