CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/PhysicsTools/PatAlgos/python/tools/tauTools.py

Go to the documentation of this file.
00001 import FWCore.ParameterSet.Config as cms
00002 
00003 from FWCore.GuiBrowsers.ConfigToolBase import *
00004 from PhysicsTools.PatAlgos.tools.helpers import cloneProcessingSnippet
00005 from RecoTauTag.RecoTau.TauDiscriminatorTools import *
00006 
00007 # applyPostFix function adapted to unscheduled mode
00008 def applyPostfix(process, label, postfix):
00009     result = None
00010     if hasattr(process, label+postfix):
00011         result = getattr(process, label + postfix)
00012     else:
00013         raise ValueError("Error in <applyPostfix>: No module of name = %s attached to process !!" % (label + postfix))
00014     return result
00015 
00016 # switch to CaloTau collection
00017 def switchToCaloTau(process,
00018                     tauSource = cms.InputTag('caloRecoTauProducer'),
00019                     patTauLabel = "",
00020                     postfix = ""):
00021     print ' switching PAT Tau input to: ', tauSource
00022 
00023     applyPostfix(process, "tauMatch" + patTauLabel, postfix).src = tauSource
00024     applyPostfix(process, "tauGenJetMatch"+ patTauLabel, postfix).src = tauSource
00025     
00026     applyPostfix(process, "patTaus" + patTauLabel, postfix).tauSource = tauSource
00027     applyPostfix(process, "patTaus" + patTauLabel, postfix).tauIDSources = _buildIDSourcePSet('caloRecoTau', classicTauIDSources, postfix)
00028 
00029     ## Isolation is somewhat an issue, so we start just by turning it off
00030     print "NO PF Isolation will be computed for CaloTau (this could be improved later)"
00031     applyPostfix(process, "patTaus" + patTauLabel, postfix).isolation   = cms.PSet()
00032     applyPostfix(process, "patTaus" + patTauLabel, postfix).isoDeposits = cms.PSet()
00033     applyPostfix(process, "patTaus" + patTauLabel, postfix).userIsolation = cms.PSet()
00034 
00035     ## adapt cleanPatTaus
00036     if hasattr(process, "cleanPatTaus" + patTauLabel + postfix):
00037         getattr(process, "cleanPatTaus" + patTauLabel + postfix).preselection = \
00038       'tauID("leadingTrackFinding") > 0.5 & tauID("leadingTrackPtCut") > 0.5' \
00039      + ' & tauID("byIsolation") > 0.5 & tauID("againstElectron") > 0.5 & (signalTracks.size() = 1 | signalTracks.size() = 3)'
00040 
00041 def _buildIDSourcePSet(tauType, idSources, postfix =""):
00042     """ Build a PSet defining the tau ID sources to embed into the pat::Tau """
00043     output = cms.PSet()
00044     for label, discriminator in idSources:
00045         if ":" in discriminator:
00046           discr = discriminator.split(":")
00047           setattr(output, label, cms.InputTag(tauType + discr[0] + postfix + ":" + discr[1]))
00048         else:  
00049           setattr(output, label, cms.InputTag(tauType + discriminator + postfix))
00050     return output
00051 
00052 def _switchToPFTau(process,
00053                    tauSource,
00054                    pfTauType,
00055                    idSources,
00056                    patTauLabel = "",
00057                    postfix = ""):
00058     """internal auxiliary function to switch to **any** PFTau collection"""
00059     print ' switching PAT Tau input to: ', tauSource
00060 
00061     applyPostfix(process, "tauMatch" + patTauLabel, postfix).src = tauSource
00062     applyPostfix(process, "tauGenJetMatch" + patTauLabel, postfix).src = tauSource
00063     
00064     applyPostfix(process, "tauIsoDepositPFCandidates" + patTauLabel, postfix).src = tauSource
00065     applyPostfix(process, "tauIsoDepositPFCandidates" + patTauLabel, postfix).ExtractorPSet.tauSource = tauSource
00066     applyPostfix(process, "tauIsoDepositPFChargedHadrons" + patTauLabel, postfix).src = tauSource
00067     applyPostfix(process, "tauIsoDepositPFChargedHadrons" + patTauLabel, postfix).ExtractorPSet.tauSource = tauSource
00068     applyPostfix(process, "tauIsoDepositPFNeutralHadrons" + patTauLabel, postfix).src = tauSource
00069     applyPostfix(process, "tauIsoDepositPFNeutralHadrons" + patTauLabel, postfix).ExtractorPSet.tauSource = tauSource
00070     applyPostfix(process, "tauIsoDepositPFGammas" + patTauLabel, postfix).src = tauSource
00071     applyPostfix(process, "tauIsoDepositPFGammas" + patTauLabel, postfix).ExtractorPSet.tauSource = tauSource
00072     
00073     applyPostfix(process, "patTaus" + patTauLabel, postfix).tauSource = tauSource
00074     applyPostfix(process, "patTaus" + patTauLabel, postfix).tauIDSources = _buildIDSourcePSet(pfTauType, idSources, postfix)
00075 
00076     if hasattr(process, "cleanPatTaus" + patTauLabel + postfix):
00077         getattr(process, "cleanPatTaus" + patTauLabel + postfix).preselection = \
00078           'tauID("leadingTrackFinding") > 0.5 & tauID("leadingPionPtCut") > 0.5 & tauID("byIsolationUsingLeadingPion") > 0.5' \
00079          + ' & tauID("againstMuon") > 0.5 & tauID("againstElectron") > 0.5' \
00080          + ' & (signalPFChargedHadrCands.size() = 1 | signalPFChargedHadrCands.size() = 3)'
00081 
00082 # Name mapping for classic tau ID sources (present for fixed and shrinkingCones)
00083 classicTauIDSources = [
00084     ("leadingTrackFinding", "DiscriminationByLeadingTrackFinding"),
00085     ("leadingTrackPtCut", "DiscriminationByLeadingTrackPtCut"),
00086     ("trackIsolation", "DiscriminationByTrackIsolation"),
00087     ("ecalIsolation", "DiscriminationByECALIsolation"),
00088     ("byIsolation", "DiscriminationByIsolation"),
00089     ("againstElectron", "DiscriminationAgainstElectron"),
00090     ("againstMuon", "DiscriminationAgainstMuon") ]
00091 
00092 classicPFTauIDSources = [
00093     ("leadingPionPtCut", "DiscriminationByLeadingPionPtCut"),
00094     ("trackIsolationUsingLeadingPion", "DiscriminationByTrackIsolationUsingLeadingPion"),
00095     ("ecalIsolationUsingLeadingPion", "DiscriminationByECALIsolationUsingLeadingPion"),
00096     ("byIsolationUsingLeadingPion", "DiscriminationByIsolationUsingLeadingPion")]
00097 
00098 # Hadron-plus-strip(s) (HPS) Tau Discriminators
00099 hpsTauIDSources = [
00100     ("decayModeFinding", "DiscriminationByDecayModeFinding"),
00101     ("byLooseIsolation", "DiscriminationByLooseIsolation"),
00102     ("byVLooseCombinedIsolationDeltaBetaCorr", "DiscriminationByVLooseCombinedIsolationDBSumPtCorr"),
00103     ("byLooseCombinedIsolationDeltaBetaCorr", "DiscriminationByLooseCombinedIsolationDBSumPtCorr"),
00104     ("byMediumCombinedIsolationDeltaBetaCorr", "DiscriminationByMediumCombinedIsolationDBSumPtCorr"),
00105     ("byTightCombinedIsolationDeltaBetaCorr", "DiscriminationByTightCombinedIsolationDBSumPtCorr"),
00106     ("byCombinedIsolationDeltaBetaCorrRaw", "DiscriminationByRawCombinedIsolationDBSumPtCorr"),
00107 ##     ("byLooseCombinedIsolationDeltaBetaCorr3Hits", "DiscriminationByLooseCombinedIsolationDBSumPtCorr3Hits"),
00108 ##     ("byMediumCombinedIsolationDeltaBetaCorr3Hits", "DiscriminationByMediumCombinedIsolationDBSumPtCorr3Hits"),
00109 ##     ("byTightCombinedIsolationDeltaBetaCorr3Hits", "DiscriminationByTightCombinedIsolationDBSumPtCorr3Hits"),    
00110     ("byIsolationMVAraw", "DiscriminationByIsolationMVAraw"),
00111     ("byLooseIsolationMVA", "DiscriminationByLooseIsolationMVA"),
00112     ("byMediumIsolationMVA", "DiscriminationByMediumIsolationMVA"),
00113     ("byTightIsolationMVA", "DiscriminationByTightIsolationMVA"),
00114     ("againstElectronLoose", "DiscriminationByLooseElectronRejection"),
00115     ("againstElectronMedium", "DiscriminationByMediumElectronRejection"),
00116     ("againstElectronTight", "DiscriminationByTightElectronRejection"),
00117     ("againstElectronMVA", "DiscriminationByMVAElectronRejection"),
00118 ##     ("againstElectronMVA2raw", "DiscriminationByMVA2rawElectronRejection"),
00119 ##     ("againstElectronMVA2category", "DiscriminationByMVA2rawElectronRejection:category"),
00120 ##     ("againstElectronVLooseMVA2", "DiscriminationByMVA2VLooseElectronRejection"),
00121 ##     ("againstElectronLooseMVA2", "DiscriminationByMVA2LooseElectronRejection"),
00122 ##     ("againstElectronMediumMVA2", "DiscriminationByMVA2MediumElectronRejection"),
00123 ##     ("againstElectronTightMVA2", "DiscriminationByMVA2TightElectronRejection"),
00124 ##     ("againstElectronMVA3raw", "DiscriminationByMVA3rawElectronRejection"),
00125 ##     ("againstElectronMVA3category", "DiscriminationByMVA3rawElectronRejection:category"),
00126 ##     ("againstElectronLooseMVA3", "DiscriminationByMVA3LooseElectronRejection"),
00127 ##     ("againstElectronMediumMVA3", "DiscriminationByMVA3MediumElectronRejection"),
00128 ##     ("againstElectronTightMVA3", "DiscriminationByMVA3TightElectronRejection"),
00129 ##     ("againstElectronDeadECAL", "DiscriminationByDeadECALElectronRejection"),
00130     ("againstMuonLoose", "DiscriminationByLooseMuonRejection"),
00131     ("againstMuonMedium", "DiscriminationByMediumMuonRejection"),
00132     ("againstMuonTight", "DiscriminationByTightMuonRejection") ]
00133 
00134 # switch to PFTau collection produced for fixed dR = 0.07 signal cone size
00135 def switchToPFTauFixedCone(process,
00136                            tauSource = cms.InputTag('fixedConePFTauProducer'),
00137                            patTauLabel = "",
00138                            postfix = ""):
00139     fixedConeIDSources = copy.copy(classicTauIDSources)
00140     fixedConeIDSources.extend(classicPFTauIDSources)
00141 
00142     _switchToPFTau(process, tauSource, 'fixedConePFTau', fixedConeIDSources,
00143                    patTauLabel = patTauLabel, postfix = postfix)
00144 
00145 # switch to PFTau collection produced for shrinking signal cone of size dR = 5.0/Et(PFTau)
00146 def switchToPFTauShrinkingCone(process,
00147                                tauSource = cms.InputTag('shrinkingConePFTauProducer'),
00148                                patTauLabel = "",
00149                                postfix = ""):
00150     shrinkingIDSources = copy.copy(classicTauIDSources)
00151     shrinkingIDSources.extend(classicPFTauIDSources)
00152 
00153     _switchToPFTau(process, tauSource, 'shrinkingConePFTau', shrinkingIDSources,
00154                    patTauLabel = patTauLabel, postfix = postfix)
00155 
00156 # switch to hadron-plus-strip(s) (HPS) PFTau collection
00157 def switchToPFTauHPS(process,
00158                      tauSource = cms.InputTag('hpsPFTauProducer'),
00159                      patTauLabel = "",
00160                      jecLevels = [],
00161                      postfix = ""):
00162 
00163     _switchToPFTau(process, tauSource, 'hpsPFTau', hpsTauIDSources,
00164                    patTauLabel = patTauLabel, postfix = postfix)
00165 
00166     ## adapt cleanPatTaus
00167     if hasattr(process, "cleanPatTaus" + patTauLabel + postfix):
00168         getattr(process, "cleanPatTaus" + patTauLabel + postfix).preselection = \
00169       'pt > 15 & abs(eta) < 2.3 & tauID("decayModeFinding") > 0.5 & tauID("byLooseIsolation") > 0.5' \
00170      + ' & tauID("againstMuonTight") > 0.5 & tauID("againstElectronLoose") > 0.5'
00171 
00172 # Select switcher by string
00173 def switchToPFTauByType(process,
00174                         pfTauType = None,
00175                         tauSource = cms.InputTag('hpsPFTauProducer'),
00176                         patTauLabel = "",
00177                         postfix = "" ):
00178     mapping = {
00179         'shrinkingConePFTau' : switchToPFTauShrinkingCone,
00180         'fixedConePFTau'     : switchToPFTauFixedCone,
00181         'hpsPFTau'           : switchToPFTauHPS,
00182         'caloRecoTau'        : switchToCaloTau
00183     }
00184     if not pfTauType in mapping.keys():
00185         raise ValueError("Error in <switchToPFTauByType>: Undefined pfTauType = %s !!" % pfTauType)
00186     
00187     mapping[pfTauType](process, tauSource = tauSource,
00188                        patTauLabel = patTauLabel, postfix = postfix)
00189 
00190 class AddTauCollection(ConfigToolBase):
00191 
00192     """ Add a new collection of taus. Takes the configuration from the
00193     already configured standard tau collection as starting point;
00194     replaces before calling addTauCollection will also affect the
00195     new tau collections
00196     """
00197     _label='addTauCollection'
00198     _defaultParameters=dicttypes.SortedKeysDict()
00199     def __init__(self):
00200         ConfigToolBase.__init__(self)
00201         self.addParameter(self._defaultParameters, 'tauCollection',
00202                           self._defaultValue, 'Input tau collection', cms.InputTag)
00203         self.addParameter(self._defaultParameters, 'algoLabel',
00204                           self._defaultValue, "label to indicate the tau algorithm (e.g.'hps')", str)
00205         self.addParameter(self._defaultParameters, 'typeLabel',
00206                           self._defaultValue, "label to indicate the type of constituents (either 'PFTau' or 'Tau')", str)
00207         self.addParameter(self._defaultParameters, 'doPFIsoDeposits',
00208                           True, "run sequence for computing particle-flow based IsoDeposits")
00209         self.addParameter(self._defaultParameters, 'standardAlgo',
00210                           "hps", "standard algorithm label of the collection from which the clones " \
00211                          + "for the new tau collection will be taken from " \
00212                          + "(note that this tau collection has to be available in the event before hand)")
00213         self.addParameter(self._defaultParameters, 'standardType',
00214                           "PFTau", "standard constituent type label of the collection from which the clones " \
00215                          + " for the new tau collection will be taken from "\
00216                          + "(note that this tau collection has to be available in the event before hand)")
00217 
00218         self._parameters=copy.deepcopy(self._defaultParameters)
00219         self._comment = ""
00220 
00221     def getDefaultParameters(self):
00222         return self._defaultParameters
00223 
00224     def __call__(self,process,
00225                  tauCollection      = None,
00226                  algoLabel          = None,
00227                  typeLabel          = None,
00228                  doPFIsoDeposits    = None,
00229                  jetCorrLabel       = None,
00230                  standardAlgo       = None,
00231                  standardType       = None):
00232 
00233         if tauCollection is None:
00234             tauCollection = self._defaultParameters['tauCollection'].value
00235         if algoLabel is None:
00236             algoLabel = self._defaultParameters['algoLabel'].value
00237         if typeLabel is None:
00238             typeLabel = self._defaultParameters['typeLabel'].value
00239         if doPFIsoDeposits is None:
00240             doPFIsoDeposits = self._defaultParameters['doPFIsoDeposits'].value
00241         if standardAlgo is None:
00242             standardAlgo = self._defaultParameters['standardAlgo'].value
00243         if standardType is None:
00244             standardType = self._defaultParameters['standardType'].value
00245 
00246         self.setParameter('tauCollection', tauCollection)
00247         self.setParameter('algoLabel', algoLabel)
00248         self.setParameter('typeLabel', typeLabel)
00249         self.setParameter('doPFIsoDeposits', doPFIsoDeposits)
00250         self.setParameter('standardAlgo', standardAlgo)
00251         self.setParameter('standardType', standardType)
00252 
00253         self.apply(process)
00254 
00255     def toolCode(self, process):
00256         tauCollection = self._parameters['tauCollection'].value
00257         algoLabel = self._parameters['algoLabel'].value
00258         typeLabel = self._parameters['typeLabel'].value
00259         doPFIsoDeposits = self._parameters['doPFIsoDeposits'].value
00260         standardAlgo = self._parameters['standardAlgo'].value
00261         standardType = self._parameters['standardType'].value
00262 
00263         ## disable computation of particle-flow based IsoDeposits
00264         ## in case tau is of CaloTau type
00265         if typeLabel == 'Tau':
00266             print "NO PF Isolation will be computed for CaloTau (this could be improved later)"
00267             doPFIsoDeposits = False
00268 
00269         ## create old module label from standardAlgo
00270         ## and standardType and return
00271         def oldLabel(prefix = ''):
00272             if prefix == '':
00273                 return "patTaus"
00274             else:
00275                 return prefix + "PatTaus"
00276 
00277         ## capitalize first character of appended part
00278         ## when creating new module label
00279         ## (giving e.g. "patTausCaloRecoTau")
00280         def capitalize(label):
00281             return label[0].capitalize() + label[1:]
00282 
00283         ## create new module label from old module
00284         ## label and return
00285         def newLabel(oldLabel):
00286             newLabel = oldLabel
00287             if ( oldLabel.find(standardAlgo) >= 0 and oldLabel.find(standardType) >= 0 ):
00288                 oldLabel = oldLabel.replace(standardAlgo, algoLabel).replace(standardType, typeLabel)
00289             else:
00290                 oldLabel = oldLabel + capitalize(algoLabel + typeLabel)
00291             return oldLabel
00292 
00293         ## clone module and add it to the patDefaultSequence
00294         def addClone(hook, **replaceStatements):
00295             ## create a clone of the hook with corresponding
00296             ## parameter replacements
00297             newModule = getattr(process, hook).clone(**replaceStatements)
00298 
00299         ## clone module for computing particle-flow IsoDeposits
00300         def addPFIsoDepositClone(hook, **replaceStatements):
00301             newModule = getattr(process, hook).clone(**replaceStatements)
00302             newModuleIsoDepositExtractor = getattr(newModule, "ExtractorPSet")
00303             setattr(newModuleIsoDepositExtractor, "tauSource", getattr(newModule, "src"))
00304 
00305         ## add a clone of patTaus
00306         addClone(oldLabel(), tauSource = tauCollection)
00307 
00308         ## add a clone of selectedPatTaus
00309         addClone(oldLabel('selected'), src = cms.InputTag(newLabel(oldLabel())))
00310 
00311         ## add a clone of cleanPatTaus
00312         addClone(oldLabel('clean'), src=cms.InputTag(newLabel(oldLabel('selected'))))
00313 
00314         ## get attributes of new module
00315         newTaus = getattr(process, newLabel(oldLabel()))
00316 
00317         ## add a clone of gen tau matching
00318         addClone('tauMatch', src = tauCollection)
00319         addClone('tauGenJetMatch', src = tauCollection)
00320 
00321         ## add a clone of IsoDeposits computed based on particle-flow
00322         if doPFIsoDeposits:
00323             addPFIsoDepositClone('tauIsoDepositPFCandidates', src = tauCollection)
00324             addPFIsoDepositClone('tauIsoDepositPFChargedHadrons', src = tauCollection)
00325             addPFIsoDepositClone('tauIsoDepositPFNeutralHadrons', src = tauCollection)
00326             addPFIsoDepositClone('tauIsoDepositPFGammas', src = tauCollection)
00327 
00328         ## fix label for input tag
00329         def fixInputTag(x):
00330             x.setModuleLabel(newLabel(x.moduleLabel))
00331 
00332         ## provide patTau inputs with individual labels
00333         fixInputTag(newTaus.genParticleMatch)
00334         fixInputTag(newTaus.genJetMatch)
00335         fixInputTag(newTaus.isoDeposits.pfAllParticles)
00336         fixInputTag(newTaus.isoDeposits.pfNeutralHadron)
00337         fixInputTag(newTaus.isoDeposits.pfChargedHadron)
00338         fixInputTag(newTaus.isoDeposits.pfGamma)
00339         fixInputTag(newTaus.userIsolation.pfAllParticles.src)
00340         fixInputTag(newTaus.userIsolation.pfNeutralHadron.src)
00341         fixInputTag(newTaus.userIsolation.pfChargedHadron.src)
00342         fixInputTag(newTaus.userIsolation.pfGamma.src)
00343 
00344         ## set discriminators
00345         ## (using switchTauCollection functions)
00346         oldTaus = getattr(process, oldLabel())
00347         if typeLabel == 'Tau':
00348             switchToCaloTau(process,
00349                             tauSource = getattr(newTaus, "tauSource"),
00350                             patTauLabel = capitalize(algoLabel + typeLabel))
00351         else:
00352             switchToPFTauByType(process, pfTauType = algoLabel + typeLabel,
00353                                 tauSource = getattr(newTaus, "tauSource"),
00354                                 patTauLabel = capitalize(algoLabel + typeLabel))
00355 
00356 addTauCollection=AddTauCollection()