Package madgraph :: Package madweight :: Module proc_info
[hide private]
[frames] | no frames]

Source Code for Module madgraph.madweight.proc_info

  1   
  2   
  3  from __future__ import absolute_import 
  4  from __future__ import print_function 
  5  import re 
  6  import sys 
  7  import string 
  8  from six.moves import range 
  9   
 10   
 11  try:  
 12      from . import Cards 
 13      import madgraph.various.misc as misc 
 14  except ImportError: 
 15      import internal.madweight.Cards as Cards 
 16      import internal.misc as misc 
 17       
18 -class Decay_info:
19 """ all routine linked to the reconaissance of the topology from the proc card 20 21 The proc-card has two information: 22 1) the process decay pp>(t>blvl~)(t~>(W->l~vl)b) 23 2) the MultiParticle content 24 25 The diagram is treated as follow: 26 1) We don't consider production part (i.e. how the first on-shell particle are produced) 27 2) We will check mass shell possibility for all 1->2 decay 28 3) We will not consider possibility of mass shell for 1->3,4,... 29 even if they are only one possibility or one possibility is dominant 30 """ 31 32
33 - def __init__(self,current_dir,cond='',ParticlesFile=''):
34 """we need to read information from leshouche.inc and from configs.inc""" 35 36 mglabel2pid_list=Cards.read_leshouches_file(current_dir+'/leshouche.inc') 37 # create a dict: 38 39 mglabel2pid_dic={} 40 for index, pid in enumerate(mglabel2pid_list): 41 mglabel2pid_dic[index+1]=pid 42 43 44 topology=self.read_config(current_dir+'/configs.inc', mglabel2pid_dic) 45 46 #process_line,multi=self.read_proc_card(proc_card,cond) 47 #self.decay_diag=self.pass_in_pid(process_line,multi) 48 self.decay_diag=self.decay_structure(topology,mglabel2pid_dic) 49 50 if ParticlesFile is not None: 51 self.ParticlesFile=ParticlesFile #avoid multiple load of this file
52
53 - def read_config(self, file_name, mglabel2pid_dic):
54 print(file_name) 55 trappe=open(file_name, 'r') 56 buff=trappe.readline() 57 res_patern=re.compile(r'''^\s*(?P<mg_id>[\-,\d*]*)\s*(?P<pid_d1>[\-,\d*]*)\s*(?P<pid_d2>[\-,\d*]*)\s*(?P<mass>[\_a-zA-Z0-9]*)\s*(?P<width>[\_a-zA-Z0-9]*)\s*(?P<SorT>[a-zA-Z]*)\s*(?P<pid_m>[\-,\d*]*)''',re.I) 58 59 topo={} 60 while 1: 61 buff=trappe.readline() 62 if buff.find('*')>-1: 63 return topo 64 elif buff!="": 65 if res_patern.search(buff): 66 mg_id=res_patern.search(buff).group('mg_id') 67 pid_d1=int(res_patern.search(buff).group('pid_d1')) 68 # if pid_d1>0: pid_d1=mglabel2pid_dic[pid_d1] 69 pid_d2=int(res_patern.search(buff).group('pid_d2')) 70 # if pid_d2>0: pid_d2=mglabel2pid_dic[pid_d2] 71 mass=res_patern.search(buff).group('mass') 72 width= res_patern.search(buff).group('width') 73 SorT= res_patern.search(buff).group('SorT') 74 pid_m= res_patern.search(buff).group('pid_m') 75 topo[int(mg_id)]={} 76 topo[int(mg_id)]['daughters']=[int(pid_d1),int(pid_d2)] 77 topo[int(mg_id)]['mass']=mass 78 topo[int(mg_id)]['width']=width 79 topo[int(mg_id)]['channel']=SorT 80 topo[int(mg_id)]['pid']=int(pid_m) 81 else: 82 print("error: unexpected format in configs.inc ")
83 84
85 - def decay_structure(self,topo,mglabel2pid_dic):
86 """translate topological info in 'topo' and in 'mglabel2pid' into the object decay_diag """ 87 88 decay_diag=[] 89 res_nb=len(topo) 90 91 decay_item={} 92 for res_label in range(-1,-len(topo)-1,-1): 93 decay_item[res_label]=Proc_decay([topo[res_label]['pid']]) 94 for daughter_id in topo[res_label]['daughters']: 95 if daughter_id>0 : decay_item[res_label].des.append(Proc_decay([int(mglabel2pid_dic[daughter_id])],res_label)) 96 else: 97 decay_item[daughter_id].mother=res_label 98 decay_item[res_label].des.append(decay_item[daughter_id]) 99 100 # now decay item is a dictionnary with 101 # each key = one of the legs in the diagrams 102 # associated value = decay chain initiated by this leg 103 104 # the list "decay_diag" should contains the values associated with the legs 105 # originating from the production part 106 107 # here I use the criteria written by Olivier, so that "proc_list"="decay_list" later on in the code 108 109 particles_from_HI=[] 110 list_external=[] 111 for leg in range(-len(list(decay_item.keys())),0): 112 #print " " 113 #print "leg " 114 #print leg 115 #print "pid " 116 #print decay_item[leg].pid 117 #print "mother" 118 #print decay_item[leg].mother 119 #print "channel" 120 #print topo[leg]['mass'] 121 122 if topo[leg]['daughters'][0]>2 and topo[leg]['daughters'][0] not in list_external: 123 list_external.append(topo[leg]['daughters'][0]) 124 if topo[leg]['daughters'][1]>2 and topo[leg]['daughters'][1] not in list_external: 125 list_external.append(topo[leg]['daughters'][1]) 126 127 if topo[leg]['mass']=='ZERO': 128 decay_item[leg].mother=0 # off-shell gluons/photons/quarks should not be part of the decay chain 129 decay_item[leg].des[0].mother=0 130 decay_item[leg].des[1].mother=0 131 if topo[leg]['daughters'][0]>2 and topo[leg]['daughters'][0] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][0]) 132 if topo[leg]['daughters'][1]>2 and topo[leg]['daughters'][1] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][1]) 133 continue 134 135 # consider T-channel here 136 if topo[leg]['channel']=='T': 137 if topo[leg]['daughters'][0]>2 and topo[leg]['daughters'][0] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][0]) 138 if topo[leg]['daughters'][1]>2 and topo[leg]['daughters'][1] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][1]) 139 # I also need to check if we have A(virtual) > A(real) + B 140 if decay_item[leg].pid[0]==decay_item[leg].des[0].pid[0] or decay_item[leg].pid[0]==decay_item[leg].des[1].pid[0]: 141 decay_item[leg].des[0].mother=0 142 decay_item[leg].des[1].mother=0 143 if topo[leg]['daughters'][0]>2 and topo[leg]['daughters'][0] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][0]) 144 if topo[leg]['daughters'][1]>2 and topo[leg]['daughters'][1] not in particles_from_HI :particles_from_HI.append(topo[leg]['daughters'][1]) 145 continue 146 if decay_item[leg].mother==0 and topo[leg]['channel']=='S': 147 particles_from_HI.append(leg) 148 elif topo[leg]['channel']=='S': 149 if topo[decay_item[leg].mother]['channel']=='T' or decay_item[decay_item[leg].mother].pid[0]==21: 150 particles_from_HI.append(leg) 151 152 # now check if all external particles have been scanned: 153 for index in mglabel2pid_dic.keys(): 154 if index >2 and index not in list_external: 155 particles_from_HI.append(index) 156 157 158 for leg in particles_from_HI: 159 if leg<0: 160 decay_diag.append(decay_item[leg]) 161 else: 162 temp=Proc_decay(pid=[int(mglabel2pid_dic[leg])], mother=0) 163 decay_diag.append(temp) 164 return decay_diag
165 166
167 - def pass_in_pid(self,process_line,multi):
168 """ convert information in pid information """ 169 170 if hasattr(self,'ParticlesFile'): 171 ParticlesFile=self.ParticlesFile 172 else: 173 ParticlesFile=Cards.Particles_file('./Source/MODEL/particles.dat') 174 pid=ParticlesFile.give_pid_dict() 175 176 # 177 # Update information with multi_particle tag 178 # 179 for couple in multi.items(): 180 text=couple[1] 181 tag=couple[0] 182 pid_list=[] 183 len_max=3 184 key_list=list(pid.keys()) 185 while text: 186 text,add=self.first_part_pid(text,pid) 187 pid_list+=add 188 189 pid.update({tag:pid_list}) 190 191 192 193 # 194 # pid list is now complete 195 # convert line in decay pid information 196 decay_rule=[] 197 #1) take only the decay part: 198 for letter in ['$','/','\\','@','#','\n']: 199 if letter in process_line: 200 process_line=process_line[:process_line.index(letter)] 201 #break # only one such symbol to signify the end of the decay part 202 process_line=process_line[process_line.index('>')+1:] 203 204 205 decay_diag=[] 206 level_decay=0 207 while process_line: 208 if process_line[0] in [' ', '\t']: 209 process_line=process_line[1:] 210 continue 211 if process_line[0]=='>': 212 process_line=process_line[1:] 213 continue 214 215 if process_line[0]=='(': 216 process_line=process_line[1:] 217 level_decay+=1 218 new_decay=1 219 continue 220 221 if process_line[0]==')': 222 level_decay-=1 223 current_part=current_part.mother 224 process_line=process_line[1:] 225 continue 226 227 228 process_line,pid_content=self.first_part_pid(process_line,pid) 229 230 if level_decay==0 or (level_decay==1 and new_decay): 231 new_decay=0 232 part=Proc_decay(pid_content) 233 decay_diag.append(part) 234 current_part=part 235 elif new_decay: 236 new_decay=0 237 part=current_part.add_desint(pid_content) #return new part 238 current_part=part 239 else: 240 current_part.add_desint(pid_content) 241 242 243 return decay_diag
244 245
246 - def first_part_pid(self,text,pid):
247 """find the pid(s) of the fist tag in text. 248 return the text without this tag and the pid. 249 pid is a dictonary 250 """ 251 252 len_max=4 253 key_list=list(pid.keys()) 254 while 1: 255 num=min(len_max,len(text)) 256 if len_max==0: 257 sys.exit('error pid dico not complete or invalid input :'+str([text[:min(3,len(text))]])+'\ 258 \n Complete proc_info.py') 259 260 if text[:num].lower() in key_list: 261 tag=text[:num].lower() 262 text=text[num:] 263 return text, pid[tag] 264 else: 265 len_max+=-1
266 267
268 - def __str__(self):
269 """ print information """ 270 271 text="" 272 for particle in self.decay_diag: 273 text+=str(particle) 274 text+='\n' 275 276 277 return text
278 279 280 281
282 -class Proc_decay:
283 """ little class to store information of decay from the proc card """ 284 285
286 - def __init__(self,pid,mother=0):
287 """ init particle saying from which proc_decay the particle is coming""" 288 self.mother=mother 289 self.pid=pid 290 self.des=[]
291
292 - def add_desint(self,pid):
293 new=Proc_decay(pid,self) 294 self.des.append(new) 295 return new
296
297 - def __str__(self):
298 """ print """ 299 300 text='('+str(self.pid)+',[' 301 for particle in self.des: 302 text+=str(particle) 303 text+='])' 304 305 306 return text
307 308 309 if __name__=='__main__': 310 "test" 311 Decay_info('../Cards/proc_card_mg5.dat') 312