Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-15 22:39:32

0001 import FWCore.ParameterSet.Config as cms
0002 
0003 ######
0004 # Tools to adapt Tau sequences to run tau ReReco+PAT at MiniAOD samples
0005 # M. Bluj, NCBJ Warsaw
0006 # based on work of J. Steggemann, CERN
0007 # Created: 9 Nov. 2017
0008 ######
0009 
0010 import PhysicsTools.PatAlgos.tools.helpers as configtools
0011 #####
0012 class adaptToRunAtMiniAOD(object):
0013     def __init__(self, process, runBoosted=False, postfix=""):
0014         self.process = process
0015         self.runBoosted = runBoosted
0016         self.postfix = postfix
0017         if runBoosted:
0018             self.postfix = 'Boosted'+postfix
0019             #print("Adapting boosted tau reconstruction to run at miniAOD; postfix = \"%s\"" % self.postfix)
0020         #else:
0021         #   print("Adapting tau reconstruction to run at miniAOD; postfix = \"%s\"" % self.postfix)
0022 
0023     #####
0024     def addTauReReco(self):
0025             #PAT
0026         self.process.load('PhysicsTools.PatAlgos.producersLayer1.tauProducer_cff')
0027         self.process.load('PhysicsTools.PatAlgos.selectionLayer1.tauSelector_cfi')
0028         self.process.selectedPatTaus.cut="pt > 18. && tauID(\'decayModeFindingNewDMs\')> 0.5" #Cut as in MiniAOD
0029             #Tau RECO
0030         self.process.load("RecoTauTag.Configuration.RecoPFTauTag_cff")
0031             #Task/Sequence for tau rereco
0032         self.process.miniAODTausTask = cms.Task(
0033             self.process.PFTauTask,
0034             self.process.makePatTausTask,
0035             self.process.selectedPatTaus
0036         )
0037         #Add Run-2 tauIDs for boostedTaus
0038         if self.runBoosted:
0039             self.process.PFTauMVAIsoTask = cms.Task(
0040                 self.process.hpsPFTauDiscriminationByIsolationMVArun2v1DBoldDMwLTraw,
0041                 self.process.hpsPFTauDiscriminationByIsolationMVArun2v1DBoldDMwLT,
0042                 self.process.hpsPFTauDiscriminationByIsolationMVArun2v1DBnewDMwLTraw,
0043                 self.process.hpsPFTauDiscriminationByIsolationMVArun2v1DBnewDMwLT
0044             )
0045             self.process.PFTauTask.add(self.process.PFTauMVAIsoTask)
0046         self.miniAODTausTask = configtools.cloneProcessingSnippetTask(
0047             self.process,self.process.miniAODTausTask,postfix=self.postfix)
0048         setattr(self.process,'miniAODTausSequence'+self.postfix,cms.Sequence(self.miniAODTausTask))
0049         if not self.postfix=="":
0050             del self.process.miniAODTausTask
0051 
0052     #####
0053     def convertModuleToMiniAODInput(self,name):
0054         module = getattr(self.process, name)
0055         if hasattr(module, 'particleFlowSrc'):
0056             module.particleFlowSrc = cms.InputTag("packedPFCandidates", "", "")
0057         if hasattr(module, 'vertexSrc'):
0058             module.vertexSrc = cms.InputTag('offlineSlimmedPrimaryVertices')
0059         if hasattr(module, 'qualityCuts') and hasattr(module.qualityCuts, 'primaryVertexSrc'):
0060             module.qualityCuts.primaryVertexSrc = cms.InputTag('offlineSlimmedPrimaryVertices')
0061 
0062     #####
0063     def adaptTauToMiniAODReReco(self,reclusterJets=True):
0064     # TRYING TO MAKE THINGS MINIAOD COMPATIBLE, FROM THE START, TO THE END, 1 BY 1
0065             #print '[adaptTauToMiniAODReReco]: Start'
0066         jetCollection = 'slimmedJets'
0067             # Add new jet collections if reclustering is demanded
0068         if self.runBoosted:
0069             jetCollection = 'boostedTauSeedsPAT'+self.postfix
0070             from RecoTauTag.Configuration.boostedHPSPFTaus_cff import ca8PFJetsCHSprunedForBoostedTaus
0071             setattr(self.process,'ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix,ca8PFJetsCHSprunedForBoostedTaus.clone(
0072                     src = 'packedPFCandidates',
0073                     jetCollInstanceName = 'subJetsForSeedingBoostedTausPAT'
0074             ))
0075             setattr(self.process,'boostedTauSeedsPAT'+self.postfix,
0076                 cms.EDProducer("PATBoostedTauSeedsProducer",
0077                            subjetSrc = cms.InputTag('ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix,'subJetsForSeedingBoostedTausPAT'),
0078                            pfCandidateSrc = cms.InputTag('packedPFCandidates'),
0079                            verbosity = cms.int32(0)
0080             ))
0081             self.miniAODTausTask.add(getattr(self.process,'ca8PFJetsCHSprunedForBoostedTausPAT'+self.postfix))
0082             self.miniAODTausTask.add(getattr(self.process,'boostedTauSeedsPAT'+self.postfix))
0083         elif reclusterJets:
0084             jetCollection = 'patJetsPAT'+self.postfix
0085             from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets
0086             setattr(self.process,'ak4PFJetsPAT'+self.postfix,ak4PFJets.clone(
0087                     src = "packedPFCandidates"
0088             ))
0089                 # trivial PATJets
0090             from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets
0091             setattr(self.process,'patJetsPAT'+self.postfix,_patJets.clone(
0092                     jetSource            = "ak4PFJetsPAT"+self.postfix,
0093                     addJetCorrFactors    = False,
0094                     jetCorrFactorsSource = [],
0095                     addBTagInfo          = False,
0096                     addDiscriminators    = False,
0097                     discriminatorSources = [],
0098                     addAssociatedTracks  = False,
0099                     addJetCharge         = False,
0100                     addGenPartonMatch    = False,
0101                     embedGenPartonMatch  = False,
0102                     addGenJetMatch       = False,
0103                     getJetMCFlavour      = False,
0104                     addJetFlavourInfo    = False,
0105             ))
0106             self.miniAODTausTask.add(getattr(self.process,'ak4PFJetsPAT'+self.postfix))
0107             self.miniAODTausTask.add(getattr(self.process,'patJetsPAT'+self.postfix))
0108  
0109         # so this adds all tracks to jet in some deltaR region. we don't have tracks so don't need it :D
0110         # self.process.ak4PFJetTracksAssociatorAtVertex.jets = cms.InputTag(jetCollection)
0111     
0112         # Remove ak4PFJetTracksAssociatorAtVertex from recoTauCommonSequence
0113         # Remove pfRecoTauTagInfoProducer from recoTauCommonSequence since it uses the jet-track association
0114         # HOWEVER, may use https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookMiniAOD2017#Isolated_Tracks
0115         # probably needs recovery of the two modules above
0116         self.miniAODTausTask.remove(getattr(self.process,'ak4PFJetTracksAssociatorAtVertex'+self.postfix))
0117         self.miniAODTausTask.remove(getattr(self.process,'pfRecoTauTagInfoProducer'+self.postfix))
0118 
0119         self.miniAODTausTask.remove(getattr(self.process,'recoTauAK4PFJets08Region'+self.postfix))
0120         setattr(self.process,'recoTauAK4Jets08RegionPAT'+self.postfix,
0121             cms.EDProducer("RecoTauPatJetRegionProducer",
0122                        deltaR = self.process.recoTauAK4PFJets08Region.deltaR,
0123                        maxJetAbsEta = self.process.recoTauAK4PFJets08Region.maxJetAbsEta,
0124                        minJetPt = self.process.recoTauAK4PFJets08Region.minJetPt,
0125                        pfCandAssocMapSrc = cms.InputTag(""),
0126                        pfCandSrc = cms.InputTag("packedPFCandidates"),
0127                        src = cms.InputTag(jetCollection)
0128         ))
0129         _jetRegionProducer = getattr(self.process,'recoTauAK4Jets08RegionPAT'+self.postfix)
0130         self.miniAODTausTask.add(_jetRegionProducer)
0131         if self.runBoosted:
0132             _jetRegionProducer.pfCandAssocMapSrc = cms.InputTag(jetCollection, 'pfCandAssocMapForIsolation')
0133 
0134         getattr(self.process,'recoTauPileUpVertices'+self.postfix).src = "offlineSlimmedPrimaryVertices"
0135 
0136         for moduleName in self.miniAODTausTask.moduleNames():
0137             self.convertModuleToMiniAODInput(moduleName)
0138 
0139 
0140         # Adapt TauPiZeros producer
0141         _piZeroProducer = getattr(self.process,'ak4PFJetsLegacyHPSPiZeros'+self.postfix)
0142         for builder in _piZeroProducer.builders:
0143             builder.qualityCuts.primaryVertexSrc = "offlineSlimmedPrimaryVertices"
0144         _piZeroProducer.jetSrc = jetCollection
0145 
0146         # Adapt TauChargedHadrons producer
0147         _chargedHadronProducer = getattr(self.process,'ak4PFJetsRecoTauChargedHadrons'+self.postfix)
0148         for builder in _chargedHadronProducer.builders:
0149             builder.qualityCuts.primaryVertexSrc = "offlineSlimmedPrimaryVertices"
0150             if builder.name.value() == 'tracks': #replace plugin based on generalTracks by one based on lostTracks
0151                 builder.name = 'lostTracks'
0152                 builder.plugin = 'PFRecoTauChargedHadronFromLostTrackPlugin'
0153                 builder.srcTracks = "lostTracks"
0154                 if self.runBoosted:
0155                     builder.dRcone = 0.3
0156                     builder.dRconeLimitedToJetArea = True
0157         _chargedHadronProducer.jetSrc = jetCollection
0158 
0159         # Adapt combinatoricRecoTau producer
0160         _combinatoricRecoTauProducer = getattr(self.process,'combinatoricRecoTaus'+self.postfix)
0161         _combinatoricRecoTauProducer.jetRegionSrc = 'recoTauAK4Jets08RegionPAT'+self.postfix
0162         _combinatoricRecoTauProducer.jetSrc = jetCollection
0163         # Adapt builders
0164         for builder in _combinatoricRecoTauProducer.builders:
0165             for name,value in builder.parameters_().items():
0166                 if name == 'qualityCuts':
0167                     builder.qualityCuts.primaryVertexSrc = 'offlineSlimmedPrimaryVertices'
0168                 elif name == 'pfCandSrc':
0169                     builder.pfCandSrc = 'packedPFCandidates'
0170         # Adapt supported modifiers and remove unsupported ones
0171         _modifiersToRemove = cms.VPSet()
0172         for mod in _combinatoricRecoTauProducer.modifiers:
0173             if mod.name.value() == 'elec_rej':
0174                 _modifiersToRemove.append(mod)
0175                 continue
0176             elif mod.name.value() == 'TTIworkaround':
0177                 _modifiersToRemove.append(mod)
0178                 continue
0179             elif mod.name.value() == 'tau_lost_tracks':
0180                 _modifiersToRemove.append(mod)
0181                 continue
0182             for name,value in mod.parameters_().items():
0183                 if name == 'qualityCuts':
0184                     mod.qualityCuts.primaryVertexSrc = 'offlineSlimmedPrimaryVertices'
0185         for mod in _modifiersToRemove:
0186             _combinatoricRecoTauProducer.modifiers.remove(mod)
0187                 #print "\t\t Removing '%s' modifier from 'combinatoricRecoTaus'" %mod.name.value()
0188 
0189         # Redefine tau PV producer
0190         _tauPVProducer =  getattr(self.process,'hpsPFTauPrimaryVertexProducer'+self.postfix)
0191         _tauPVProducer.__dict__['_TypedParameterizable__type'] = 'PFTauMiniAODPrimaryVertexProducer'
0192         _tauPVProducer.PVTag = 'offlineSlimmedPrimaryVertices'
0193         _tauPVProducer.packedCandidatesTag = cms.InputTag("packedPFCandidates")
0194         _tauPVProducer.lostCandidatesTag = cms.InputTag("lostTracks")
0195 
0196         # Redefine tau SV producer
0197         setattr(self.process,'hpsPFTauSecondaryVertexProducer'+self.postfix,
0198             cms.EDProducer("PFTauSecondaryVertexProducer",
0199                        PFTauTag = cms.InputTag("hpsPFTauProducer"+self.postfix)
0200         ))
0201     
0202         # Remove RecoTau producers which are not supported (yet?), i.e. against-e/mu discriminats
0203         for moduleName in self.miniAODTausTask.moduleNames():
0204             if 'ElectronRejection' in moduleName or 'MuonRejection' in moduleName:
0205                 if 'ByDeadECALElectronRejection' in moduleName: continue
0206                 self.miniAODTausTask.remove(getattr(self.process, moduleName))
0207 
0208         # Instead add against-mu discriminants which are MiniAOD compatible
0209         from RecoTauTag.RecoTau.hpsPFTauDiscriminationByMuonRejectionSimple_cff import hpsPFTauDiscriminationByMuonRejectionSimple
0210     
0211         setattr(self.process,'hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix,
0212         hpsPFTauDiscriminationByMuonRejectionSimple.clone(
0213             PFTauProducer = "hpsPFTauProducer"+self.postfix))
0214         _tauIDAntiMuSimple = getattr(self.process,'hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix)
0215         if self.runBoosted:
0216             _tauIDAntiMuSimple.dRmuonMatch = 0.1
0217         self.miniAODTausTask.add(_tauIDAntiMuSimple)
0218 
0219             #####
0220         # PAT part in the following
0221 
0222         getattr(self.process,'tauGenJets'+self.postfix).GenParticles = "prunedGenParticles"
0223         getattr(self.process,'tauMatch'+self.postfix).matched = "prunedGenParticles"
0224 
0225         # Remove unsupported tauIDs
0226         _patTauProducer = getattr(self.process,'patTaus'+self.postfix)
0227         for name,src in _patTauProducer.tauIDSources.parameters_().items():
0228             if name.find('againstElectron') > -1 or name.find('againstMuon') > -1:
0229                 if name.find('againstElectronDeadECAL') > -1: continue
0230                 delattr(_patTauProducer.tauIDSources,name)
0231         # Add MiniAOD specific ones
0232         setattr(_patTauProducer.tauIDSources,'againstMuonLooseSimple',
0233             cms.PSet(inputTag = cms.InputTag('hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix),
0234                  provenanceConfigLabel = cms.string('IDWPdefinitions'),
0235                  idLabel = cms.string('ByLooseMuonRejectionSimple')
0236                  ))
0237         setattr(_patTauProducer.tauIDSources,'againstMuonTightSimple',
0238             cms.PSet(inputTag = cms.InputTag('hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix),
0239                  provenanceConfigLabel = cms.string('IDWPdefinitions'),
0240                  idLabel = cms.string('ByTightMuonRejectionSimple')
0241                  ))
0242         #Add Run-2 tauIDs still used for boostedTaus
0243         if self.runBoosted:
0244             from PhysicsTools.PatAlgos.producersLayer1.tauProducer_cfi import containerID
0245             containerID(_patTauProducer.tauIDSources,
0246                 "hpsPFTauDiscriminationByIsolationMVArun2v1DBoldDMwLT"+self.postfix,
0247                 "rawValues", [
0248                 ["byIsolationMVArun2DBoldDMwLTraw", "discriminator"]
0249             ])
0250             containerID(_patTauProducer.tauIDSources,
0251                 "hpsPFTauDiscriminationByIsolationMVArun2v1DBoldDMwLT"+self.postfix,
0252                 "workingPoints", [
0253                 ["byVVLooseIsolationMVArun2DBoldDMwLT", "_VVLoose"],
0254                 ["byVLooseIsolationMVArun2DBoldDMwLT", "_VLoose"],
0255                 ["byLooseIsolationMVArun2DBoldDMwLT", "_Loose"],
0256                 ["byMediumIsolationMVArun2DBoldDMwLT", "_Medium"],
0257                 ["byTightIsolationMVArun2DBoldDMwLT", "_Tight"],
0258                 ["byVTightIsolationMVArun2DBoldDMwLT", "_VTight"],
0259                 ["byVVTightIsolationMVArun2DBoldDMwLT", "_VVTight"]
0260             ])
0261             containerID(_patTauProducer.tauIDSources,
0262                 "hpsPFTauDiscriminationByIsolationMVArun2v1DBnewDMwLT"+self.postfix,
0263                 "rawValues", [
0264                 ["byIsolationMVArun2DBnewDMwLTraw", "discriminator"]
0265             ])
0266             containerID(_patTauProducer.tauIDSources,
0267                 "hpsPFTauDiscriminationByIsolationMVArun2v1DBnewDMwLT"+self.postfix,
0268                 "workingPoints", [
0269                 ["byVVLooseIsolationMVArun2DBnewDMwLT", "_VVLoose"],
0270                 ["byVLooseIsolationMVArun2DBnewDMwLT", "_VLoose"],
0271                 ["byLooseIsolationMVArun2DBnewDMwLT", "_Loose"],
0272                 ["byMediumIsolationMVArun2DBnewDMwLT", "_Medium"],
0273                 ["byTightIsolationMVArun2DBnewDMwLT", "_Tight"],
0274                 ["byVTightIsolationMVArun2DBnewDMwLT", "_VTight"],
0275                 ["byVVTightIsolationMVArun2DBnewDMwLT", "_VVTight"]
0276             ])
0277 
0278         # Run TauIDs (anti-e && deepTau) on top of selectedPatTaus
0279         _updatedTauName = 'selectedPatTausNewIDs'+self.postfix
0280         _noUpdatedTauName = 'selectedPatTausNoNewIDs'+self.postfix
0281         toKeep = ['deepTau2017v2p1']
0282         #For boosted do not run deepTauIDs, but add still used Run-2 anti-e MVA
0283         if self.runBoosted:
0284             toKeep = ['againstEle']
0285         import RecoTauTag.RecoTau.tools.runTauIdMVA as tauIdConfig
0286         tauIdEmbedder = tauIdConfig.TauIDEmbedder(
0287             self.process, debug = False,
0288             originalTauName = _noUpdatedTauName,
0289             updatedTauName = _updatedTauName,
0290             postfix = "MiniAODTaus"+self.postfix,
0291             toKeep = toKeep
0292         )
0293         tauIdEmbedder.runTauID()
0294         setattr(self.process, _noUpdatedTauName, getattr(self.process,'selectedPatTaus'+self.postfix).clone())
0295         self.miniAODTausTask.add(getattr(self.process,_noUpdatedTauName))
0296         delattr(self.process, 'selectedPatTaus'+self.postfix)
0297         setattr(self.process,'selectedPatTaus'+self.postfix,getattr(self.process, _updatedTauName).clone())
0298         delattr(self.process, _updatedTauName)
0299         setattr(self.process,'newTauIDsTask'+self.postfix,cms.Task(
0300                 getattr(self.process,'rerunMvaIsolationTaskMiniAODTaus'+self.postfix),
0301                 getattr(self.process,'selectedPatTaus'+self.postfix)
0302         ))
0303         self.miniAODTausTask.add(getattr(self.process,'newTauIDsTask'+self.postfix))
0304 
0305         #print '[adaptTauToMiniAODReReco]: Done!'
0306 
0307     #####
0308     def setOutputModule(self,mode=0):
0309     #mode = 0: store original MiniAOD and new selectedPatTaus 
0310     #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)
0311 
0312         import Configuration.EventContent.EventContent_cff as evtContent
0313         output = cms.OutputModule(
0314             'PoolOutputModule',
0315             fileName=cms.untracked.string('miniAOD_TauReco.root'),
0316             fastCloning=cms.untracked.bool(False),
0317             dataset=cms.untracked.PSet(
0318                 dataTier=cms.untracked.string('MINIAODSIM'),
0319                 filterName=cms.untracked.string('')
0320             ),
0321             outputCommands = evtContent.MINIAODSIMEventContent.outputCommands,
0322             SelectEvents=cms.untracked.PSet(
0323                 SelectEvents=cms.vstring('*',)
0324             )
0325             )
0326         output.outputCommands.append('keep *_selectedPatTaus'+self.postfix+'_*_*')
0327         if mode==1:
0328             import re
0329             for prod in evtContent.RecoTauTagAOD.outputCommands:
0330                 if prod.find('ElectronRejection') > -1 and prod.find('DeadECAL') == -1:
0331                     continue
0332                 if prod.find('MuonRejection') > -1:
0333                     continue
0334                 if prod.find("_*_*")>-1: # products w/o instance
0335                     output.outputCommands.append(prod.replace("_*_*",self.postfix+"_*_*"))
0336                 else: # check if there are prods with instance
0337                     m = re.search(r'_[A-Za-z0-9]+_\*', prod)
0338                     if m!=None:
0339                         inst = m.group(0)
0340                         output.outputCommands.append(prod.replace(inst,self.postfix+inst))
0341                     else:
0342                         print("Warning: \"%s\" do not match known name patterns; trying to keep w/o postfix" % prod)
0343                         output.outputCommands.append(prod)
0344 
0345             output.outputCommands.append('keep *_hpsPFTauDiscriminationByMuonRejectionSimple'+self.postfix+'_*_*')
0346             output.outputCommands.append('keep *_combinatoricReco*_*_*')
0347             output.outputCommands.append('keep *_ak4PFJetsRecoTauChargedHadrons'+self.postfix+'_*_*')
0348             output.outputCommands.append('keep *_ak4PFJetsLegacyHPSPiZeros'+self.postfix+'_*_*')
0349             output.outputCommands.append('keep *_patJetsPAT'+self.postfix+'_*_*')
0350             output.outputCommands.append('keep *_boostedTauSeedsPAT'+self.postfix+'_*_*')
0351 
0352         return output
0353 
0354 #####