invisible_list = [12,14,16,18] invisible_list += [1000012,1000014,1000016,1000022,1000023,1000024,1000025,1000035] class Particle: def __init__(self,MG_num,pid,fuse=0): if fuse: self.MG=str(MG_num) else: self.MG=int(MG_num) self.pid=int(pid) self.mass=0 self.mother=0 self.level=0 self.twin=0 self.neutrino=0 self.external=0 def add_mother(self,obj): self.mother=obj def def_twin(self): #this routine is normaly not used any more# """ not use anymore: define the twin for the particle if not defined """ print 'WARNING: Particle.def_twin() is an old routine. This routine hasn\'t been updated since 1/2/08' #but perhaps no update are needed if self.twin!=0: return self.twin else: if self.mother: if self.mother.des[0].MG==self.MG: self.twin=self.mother.des[1] self.mother.des[1].twin=self else: self.twin=self.mother.des[0] self.mother.des[0].twin=self else: self.twin=0 return self.twin def def_mass(self,info): """definition of the mass of the particle""" try: #this is for unfixed data coming from param_card self.mass=float(info['mass'][str(abs(self.pid))]) except: self.mass=0 #O if not defined in param card def def_all_mother(self): "define list containing all mother of the particle" try: if self.all_mother_: return self.all_mother_ except: pass mother=self.mother if mother==0: self.all_mother_=[] else: self.all_mother_=[mother]+mother.def_all_mother() return self.all_mother_ def all_mother(self): """convinient alias""" return self.def_all_mother() def detect_neut_in_decay(self): """ detect the nearest neutrino in the decay branch return this neutrino and its level compare to this particle """ analyse_list=list(self.des) level_list=[1,1] while analyse_list: particle=analyse_list.pop(0) level=level_list.pop(0) if particle.neutrino: return particle,level elif particle.external==0: analyse_list.append(particle.des) level_list.append(level+1) level_list.append(level+1) return 0,0 #no neutrino detected def __str__(self): """ print routine """ text='particle: '+str(self.MG)+'\tpid : ' if self.pid<10 and self.pid>0: text+=' ' elif self.pid>9: text+=' ' text+=str(self.pid)+'\tlevel: '+str(self.level) try: text+='\tmother: '+str(self.mother.MG) except: pass try: text+='\ttwin: '+str(self.twin.MG) except: pass return text class external_part(Particle): def __init__(self,MG_num,pid): Particle.__init__(self,MG_num,pid) self.external=1 self.neutrino=self.is_invisible() self.width=0 #self.tf_width={} #self.tf_width['p']=-1 #self.tf_width['eta']=-1 #self.tf_width['phi']=-1 def is_invisible(self): "detect if the external particle is visible in the detector or not" if (abs(self.pid) in invisible_list): self.neutrino=1 else: self.neutrino=0 return self.neutrino def define_tf_width(self,W_p,W_eta,W_phi): tf_width={} tf_width['p']=float(W_p) tf_width['eta']=float(W_eta) tf_width['phi']=float(W_phi) self.tf_width=tf_width def unaligned_propa(self,part,total=1): """ compute the number of propa in common return the total number of propagator before the two particle (default) in addtion it can give the number of uncorelated propagator for the two particle (put total=0) """ not_defined_mother=[] if part.mother in self.all_mother(): if total: return self.level else: return self.level, self.level-part.level,0 if self.mother in part.all_mother(): if total: return part.level else: print part.level,self.level return part.level, 0, part.level-self.level #======================================================================= # try: # if part.mother in self.all_mother(): # return self.level # except: #self.all_mother not defined # not_defined_mother.append(self) # # try: # if self.mother in part.all_mother(): # return part.level # except: #part.all_mother not defined # not_defined_mother.append(part) # # #define all mother if needed # for ext_part in not_defined_mother: # ext_part.def_all_mother() #======================================================================= common=0 for propa in self.all_mother(): if propa in part.all_mother() and propa.channel[0]=='S': common+=1 # print 'propagator in front',self.MG,'-',part.MG,':',self.level,'+',part.level,'-',common,'=',self.level+part.level-common if total: return self.level+part.level-common else: return self.level+part.level-common,self.level-common,part.level-common class propagator(Particle): def __init__(self,MG_num,pid,channel): Particle.__init__(self,MG_num,pid) self.external=0 self.channel=channel self.mass=0 self.width=0 def def_desintegation(self,obj): "define mother/child/twin relation: the two entry are the child object" try: self.des.append(obj) #create twin relation obj.twin=self.des[0] self.des[0].twin=obj except: self.des=[obj] obj.mother=self def def_mass(self,info): "define mass and width of the particle" Particle.def_mass(self,info) #definition of the mass #definition of the width try: self.width=float(info['decay'][str(abs(self.pid))]) except: self.width=0 #O if not defined in param card def __str__(self): """ print lot of information """ text='particle: '+str(self.MG)+'\tpid : ' if self.pid<10 and self.pid>0: text+=' ' elif self.pid>9: text+=' ' text+=str(self.pid)+'\tlevel: '+str(self.level) text+='\tchannel: '+str(self.channel) try: text+='\tdes: '+str(self.des[0].MG)+' '+str(self.des[1].MG) except: try: text+='\tdes: '+str(self.des[0].MG) except: pass try: text+='\tmother: '+str(self.mother.MG) except: text+='\t\t' text+='\tmass/width: '+str(self.mass)+'/'+str(self.width) return text