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
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
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
47
48 self.decay_diag=self.decay_structure(topology,mglabel2pid_dic)
49
50 if ParticlesFile is not None:
51 self.ParticlesFile=ParticlesFile
52
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
69 pid_d2=int(res_patern.search(buff).group('pid_d2'))
70
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
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
101
102
103
104
105
106
107
108
109 particles_from_HI=[]
110 list_external=[]
111 for leg in range(-len(list(decay_item.keys())),0):
112
113
114
115
116
117
118
119
120
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
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
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
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
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
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
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
195
196 decay_rule=[]
197
198 for letter in ['$','/','\\','@','#','\n']:
199 if letter in process_line:
200 process_line=process_line[:process_line.index(letter)]
201
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)
238 current_part=part
239 else:
240 current_part.add_desint(pid_content)
241
242
243 return decay_diag
244
245
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
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
283 """ little class to store information of decay from the proc card """
284
285
287 """ init particle saying from which proc_decay the particle is coming"""
288 self.mother=mother
289 self.pid=pid
290 self.des=[]
291
296
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