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