File indexing completed on 2024-04-06 12:23:28
0001 from builtins import range
0002 from PhysicsTools.Heppy.physicsobjects.PhysicsObjects import printOut
0003 from PhysicsTools.Heppy.physicsobjects.PhysicsObjects import GenParticle
0004
0005 def findStatus1Leptons(particle):
0006 '''Returns status 1 e and mu among the particle daughters'''
0007 leptons = []
0008 for i in range( particle.numberOfDaughters() ):
0009 dau = particle.daughter(i)
0010 if dau.status() == 1:
0011 if abs(dau.pdgId())==11 or abs(dau.pdgId())==13:
0012 leptons.append( dau )
0013 else:
0014 continue
0015 else:
0016 leptons = findStatus1Leptons( dau, leptons )
0017 return leptons
0018
0019
0020 def allDaughters(particle, daughters, rank ):
0021 '''Fills daughters with all the daughters of particle.
0022 Recursive function.'''
0023 rank += 1
0024 for i in range( particle.numberOfDaughters() ):
0025 dau = GenParticle(particle.daughter(i))
0026 dau.rank = rank
0027 daughters.append( dau )
0028 daughters = allDaughters( dau, daughters, rank )
0029 return daughters
0030
0031
0032 def bosonToX(particles, bosonType, xType):
0033 bosons = [x for x in particles if x.status()==3 and x.pdgId()==bosonType]
0034 daughters = []
0035 if len(bosons)==0:
0036 return [], False
0037 boson = bosons[0]
0038 daus = []
0039 allDaughters( boson, daus, 0)
0040 xDaus = [x for x in daus if x.status()==3 and abs(x.pdgId())==xType]
0041
0042 return xDaus, True
0043
0044 def isNotHadronicId(pdgId,includeSMLeptons=True):
0045 if abs(pdgId) in [11,12,13,14,15,16]:
0046 return includeSMLeptons
0047 i = (abs(pdgId) % 1000)
0048 return i > 10 and i != 21 and i < 100
0049
0050 def isPromptLepton(lepton, beforeFSR, includeMotherless=True, includeTauDecays=False):
0051 if abs(lepton.pdgId()) not in [11,13,15]:
0052 return False
0053 if lepton.numberOfMothers() == 0:
0054 return includeMotherless;
0055 mom = lepton.mother()
0056 if mom.pdgId() == lepton.pdgId():
0057 if beforeFSR: return False
0058 return isPromptLepton(mom, beforeFSR, includeMotherless, includeTauDecays)
0059 elif abs(mom.pdgId()) == 15:
0060 if not includeTauDecays: return False
0061 return isPromptLepton(mom, beforeFSR, includeMotherless, includeTauDecays)
0062 else:
0063 return isNotHadronicId(mom.pdgId(), includeSMLeptons=False)
0064
0065
0066 def isNotFromHadronicShower(l):
0067 for x in range(l.numberOfMothers()):
0068 mom = l.mother(x)
0069 if mom.status() > 2: return True
0070 id = abs(mom.pdgId())
0071 if id > 1000000: return True
0072 if id > 100: return False
0073 if id < 6: return False
0074 if id == 21: return False
0075 if id in [11,12,13,14,15,16]:
0076 if l.status() > 2: return True
0077 return isNotFromHadronicShower(mom)
0078 if id >= 22 and id <= 39: return True
0079 return True
0080
0081 def realGenDaughters(gp,excludeRadiation=True):
0082 """Get the daughters of a particle, going through radiative X -> X' + a
0083 decays, either including or excluding the radiation among the daughters
0084 e.g. for
0085 X -> X' + a, X' -> b c
0086 realGenDaughters(X, excludeRadiation=True) = { b, c }
0087 realGenDaughters(X, excludeRadiation=False) = { a, b, c }"""
0088 ret = []
0089 for i in range(gp.numberOfDaughters()):
0090 dau = gp.daughter(i)
0091 if dau.pdgId() == gp.pdgId():
0092 if excludeRadiation:
0093 return realGenDaughters(dau)
0094 else:
0095 ret += realGenDaughters(dau)
0096 else:
0097 ret.append(dau)
0098 return ret
0099
0100 def realGenMothers(gp):
0101 """Get the mothers of a particle X going through intermediate X -> X' chains.
0102 e.g. if Y -> X, X -> X' realGenMothers(X') = Y"""
0103 ret = []
0104 for i in range(gp.numberOfMothers()):
0105 mom = gp.mother(i)
0106 if mom.pdgId() == gp.pdgId():
0107 ret += realGenMothers(mom)
0108 else:
0109 ret.append(mom)
0110 return ret
0111
0112 def lastGenCopy(gp):
0113 me = gp.pdgId();
0114 for i in range(gp.numberOfDaughters()):
0115 if gp.daughter(i).pdgId() == me:
0116 return False
0117 return True
0118
0119