File indexing completed on 2024-04-06 12:23:28
0001 from __future__ import print_function
0002
0003 class TauDecayModes( object ):
0004
0005 def __init__(self):
0006 self._decayModes()
0007
0008 def _decayModes(self):
0009 '''Builds the internal dictionaries from the enum defined in
0010 http://cmslxr.fnal.gov/lxr/source/DataFormats/TauReco/interface/PFTau.h'''
0011 tmp = [
0012 'kNull',
0013 'kOneProng0PiZero',
0014 'kOneProng1PiZero',
0015 'kOneProng2PiZero',
0016 'kOneProng3PiZero',
0017 'kOneProngNPiZero',
0018 'kTwoProng0PiZero',
0019 'kTwoProng1PiZero',
0020 'kTwoProng2PiZero',
0021 'kTwoProng3PiZero',
0022 'kTwoProngNPiZero',
0023 'kThreeProng0PiZero',
0024 'kThreeProng1PiZero',
0025 'kThreeProng2PiZero',
0026 'kThreeProng3PiZero',
0027 'kThreeProngNPiZero',
0028 'kRareDecayMode'
0029 ]
0030 self.decayModes = dict( (index-1, name) for index, name in enumerate( tmp ) )
0031 self.decayModeNames = dict( (value, key) for key, value \
0032 in self.decayModes.items() )
0033
0034 def intToName( self, anInt ):
0035 '''Returns the decay mode name corresponding to an int.'''
0036 return self.decayModes[ anInt ]
0037
0038 def nameToInt( self, aName ):
0039 '''Returns the decay mode int corresponding to a name.'''
0040 return self.decayModeNames[ aName ]
0041
0042 def __str__(self):
0043 return str( self.decayModes )
0044
0045 def genDecayModeInt(self, daughters):
0046 dm = self.genDecayMode(daughters)
0047 return self.translateGenModeToInt(dm)
0048
0049 def genDecayModeFromJetInt(self, c):
0050 dm = self.genDecayModeFromGenJet(c)
0051 return self.translateGenModeToInt(dm)
0052
0053 def translateGenModeToInt(self, dm):
0054 if dm in self.decayModeNames:
0055 return self.nameToInt(dm)
0056 elif dm == 'electron':
0057 return -11
0058 elif dm == 'muon':
0059 return -13
0060 elif dm == 'kOneProngOther':
0061 return 100
0062 elif dm == 'kThreeProngOther':
0063 return 110
0064 return -99
0065
0066 @staticmethod
0067 def genDecayModeFromGenJet(c):
0068 ''' Returns generated tau decay mode. Needs to be called on genJet
0069 as stored in pat::Tau, if available.
0070
0071 Translated from PhysicsTools/JetMCUtils/interface/JetMCTag.h,
0072 which is not available in FWlite.
0073 '''
0074
0075 daughters = c.daughterPtrVector()
0076
0077 return TauDecayModes.genDecayMode(daughters)
0078
0079 @staticmethod
0080 def genDecayMode(daughters):
0081 ''' Returns the generated tau decay mode based on a passed list of all
0082 final daughters before further decay (as contained in miniAOD).
0083 '''
0084 numElectrons = 0
0085 numMuons = 0
0086 numChargedHadrons = 0
0087 numNeutralHadrons = 0
0088 numPhotons = 0
0089
0090 for daughter in daughters:
0091 pdg_id = abs(daughter.pdgId())
0092 if pdg_id == 22:
0093 numPhotons += 1
0094 elif pdg_id == 11:
0095 numElectrons +=1
0096 elif pdg_id == 13:
0097 numMuons += 1
0098 else:
0099 if daughter.charge() != 0:
0100 numChargedHadrons += 1
0101 elif pdg_id not in [12, 14, 16]:
0102 numNeutralHadrons += 1
0103
0104 if numElectrons == 1:
0105 return "electron"
0106 if numMuons == 1:
0107 return "muon"
0108
0109 if numChargedHadrons == 1:
0110 if numNeutralHadrons != 0:
0111 return "kOneProngOther"
0112 if numPhotons == 0:
0113 return "kOneProng0PiZero"
0114 elif numPhotons == 2:
0115 return "kOneProng1PiZero"
0116 elif numPhotons == 4:
0117 return "kOneProng2PiZero"
0118 elif numPhotons == 6:
0119 return "kOneProng3PiZero"
0120 else:
0121 return "kOneProngNPiZero"
0122 elif numChargedHadrons == 3:
0123 if numNeutralHadrons != 0:
0124 return "kThreeProngOther"
0125 if numPhotons == 0:
0126 return "kThreeProng0PiZero"
0127 elif numPhotons == 2:
0128 return "kThreeProng1PiZero"
0129 elif numPhotons == 4:
0130 return "kThreeProng2PiZero"
0131 elif numPhotons == 6:
0132 return "kThreeProng3PiZero"
0133 else:
0134 return "kThreeProngNPiZero"
0135
0136 return "kRareDecayMode"
0137
0138 tauDecayModes = TauDecayModes()
0139
0140 if __name__ == '__main__':
0141
0142 dec = TauDecayModes()
0143 print(dec)
0144
0145 print(0, dec.intToName(0))
0146 print('kThreeProng0PiZero', dec.nameToInt('kThreeProng0PiZero'))
0147