1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 from __future__ import absolute_import
36 from __future__ import print_function
37 import re
38 import os
39 import math
40 import sys
41 import logging
42 from six.moves import map
43 from six.moves import range
44
45 logger = logging.getLogger('madgraph.madweight')
46 pjoin = os.path.join
47
49
50
52 """ create all the include file and make all the link """
53
54
55
56 ident=Card('./Cards/ident_mw_card.dat')
57 if MWparam: madweight=MWparam.mw_card
58 else: madweight=Card('./Cards/MadWeight_card.dat')
59 transfer=Card('./Cards/transfer_card.dat')
60
61
62 madweight.create_include_file(ident,'./Source/madweight_card.inc')
63 transfer.create_include_file_tf(ident,'./Source/MadWeight/transfer_function/')
64
65
66 for dir in MWparam.MW_listdir:
67 os.system('ln -sf ../../Source/madweight_card.inc ./SubProcesses/'+dir+'/madweight_card.inc')
68 os.system('ln -sf ../../Source/MadWeight/transfer_function/transfer_card.inc ./SubProcesses/'+dir+'/transfer_card.inc')
69
70
71
72
74 """ The routine to read and treat all the card (but the run_card.dat)"""
75
76
94
95
96
97
99 """detect the type of the card """
100
101 return self.file.split('/')[-1].split('_')[0].lower()
102
103
104
106 """ DEPRECIATED """
107 print("warning depreciated funtion read_card in use")
108 raise Exception
109 self.read(name_card)
110
111
112 - def read(self,name_card):
113 """put all card information in a dictionary"""
114
115 self.charged=1
116
117 p_block=re.compile(r'''^block\s+(?P<block>\w*)\s*(?P<comment>.*)''',re.I)
118
119 get_comment = False
120 if 'madweight' in name_card.lower():
121 get_comment = True
122
123 try:
124 card=open("./Cards/"+name_card,'r')
125 except:
126 try:
127 card=open(name_card,'r')
128 except:
129 card=open("./Events/"+name_card,'r')
130
131
132 info = self
133 self['comment'] = {}
134 name_block=''
135
136
137 while 1:
138 line=card.readline()
139 if line=='':
140 break
141 prov=[name_block]
142
143 if p_block.search(line):
144 name_block=p_block.search(line).group('block')
145 name_block=name_block.lower()
146 info[name_block]={}
147 info['comment'][name_block]=p_block.search(line).group('comment')
148 continue
149
150 if '#' in line:
151 line_content, comment= line.split('#',1)
152 else:
153 line_content = line
154 comment = ''
155 line_content = line_content.strip()
156 comment = comment.strip()
157 if not line_content:
158 continue
159
160
161 if "'" in line_content:
162 begin = line_content.find("'")
163 end = line_content.rfind("'")
164 line_content = line_content[:begin].split() + [line_content[begin+1:end]] + line_content[end+1:].split()
165 else:
166 line_content = line_content.split()
167
168 line_content[0] = line_content[0].lower()
169 if line_content[0].lower()=='decay':
170 name_block='decay'
171 line_content=line_content[1:]
172 if 'decay' not in list(info.keys()):
173 info['decay']={}
174 decay_tag=line_content[0]
175 elif name_block in ['decay','br']:
176 name_block='br'
177 line_content=[decay_tag]+line_content[2:]+[line_content[0]]
178 if 'br' not in list(info.keys()):
179 info['br']={}
180
181
182 obj=line_content[-1]
183 for i in range(-2,-len(line_content)-1,-1):
184 obj={line_content[i]:obj}
185
186 dico=info[name_block]
187 if 'comment' not in dico and get_comment:
188 dico['comment'] = {}
189 if get_comment:
190 comments = dico['comment']
191
192 if len(line_content)==1:
193 dico[' ']=obj
194 for i in range(0,len(line_content)-1):
195 if line_content[0] == 'comment':
196 continue
197 if line_content[i] not in list(dico.keys()):
198 dico[line_content[i]]=obj[line_content[i]]
199 if get_comment and line_content[i] != 'comment':
200 comments[line_content[i]] = comment
201 break
202 elif i!=len(line_content)-2:
203 dico=dico[line_content[i]]
204 if get_comment and line_content[i] != 'comment':
205 comments[line_content[i]] = comment
206 obj=obj[line_content[i]]
207 elif(type(dico[line_content[i]])==list):
208 dico[line_content[i]].append(obj[line_content[i]])
209 if get_comment and line_content[i] != 'comment':
210 comments[line_content[i]] += comment
211 else:
212 dico[line_content[i]]=[dico[line_content[i]],line_content[i+1]]
213 if get_comment and line_content[i] != 'comment':
214 comments[line_content[i]] += comment
215 return info
216
217
219 """ read ident file only four and five column format are supported yet """
220
221 self.charged=1
222 try:
223 ff=open(self.file,'r')
224 except:
225 sys.exit('FATAL ERROR: no file ./Cards/ident_mw_card.dat\n This File is created during the definition of the transfer function\n\
226 either newprocess was not perform after ./bin/PassToMadWeight, either your transfer function is not correctly set up. launch\n\
227 $>./bin/change_tf.py to solve that problem')
228 line_format=re.compile(r'''^\s*(?P<block>\w+)\s+(?P<tag>\w+)\s+(?P<name>\w+)\s+(?P<type>\w+)\s*(?P<default>[\w.+-]*)\s*$''')
229 ident = self
230 while 1:
231 line=ff.readline()
232 if line=='':
233 break
234 words=line_format.search(line)
235 if not words:
236 continue
237 block=words.group('block').lower()
238 tag=words.group('tag').lower()
239 name=words.group('name').lower()
240 type=words.group('type').lower()
241 value=words.group('default').lower()
242
243 if block not in ident:
244 ident[block]={tag:[name,type,value]}
245 else:
246 ident[block][tag]=[name,type,value]
247
248 return ident
249
250
251
252
253
254
255
256
258 """ create an output of type name=value from part common in both card
259 be careful of the restriction in the ident file -> 4 column (only one tag) or 5 (one tag+default value)
260
261 Default value are used only if the block is defined in the card but not the entry
262 """
263
264
265 logger.debug('create file %s' % output)
266 out=open(output,'w')
267 out.writelines('C automatic include file for card '+self.file+' and '+card.file+'\n\n')
268
269 if card.type=='ident':
270 ident=card.info
271 info=self.info
272 elif self.type=='ident':
273 info=card.info
274 ident=self.info
275
276 for block in info.keys():
277 if block in ident:
278 for tag in ident[block].keys():
279 if tag in info[block]:
280 value=self.pass_in_type(info[block][tag],ident[block][tag][1])
281 out.writelines(' '+ident[block][tag][0]+' = '+str(value)+'\n')
282 elif ident[block][tag][2]:
283 value=self.pass_in_type(ident[block][tag][2],ident[block][tag][1])
284 out.writelines(' '+ident[block][tag][0]+' = '+str(value)+'\n')
285
286
288 """ create an output of type name(I)=value from part common in both card
289 be careful of the restriction in the ident file -> 4 column (only one tag) or 5 (one tag+default value)
290
291 Default value are used only if the block is defined in the card but not the entry
292 """
293
294
295 logger.debug('create file %s' % output)
296 out=open(output+'transfer_card.inc','w')
297 out.writelines('C automatic include file for card '+self.file+' and '+card.file+'\n\n')
298
299 if card.type=='ident':
300 ident=card.info
301 info=self.info
302 elif self.type=='ident':
303 info=card.info
304 ident=self.info
305
306 nb_element = 0
307
308
309 template = " %s(%s) = %s \n"
310 for block in info.keys():
311 if block in ident:
312 for tag in ident[block].keys():
313 type_format = ident[block][tag][1]
314 if tag in info[block]:
315 values = info[block][tag]
316 else:
317 values = [ident[block][tag][2]] * max(1, nb_element)
318
319
320 if isinstance(values, list):
321 values = [str(self.pass_in_type(value, type_format)) for value in values]
322 else:
323 values = [str(self.pass_in_type(values, type_format))]
324
325 if not nb_element:
326 nb_element = len(values)
327 elif nb_element != len(values):
328 print(nb_element, len(values))
329 raise Exception('All input in tranfer_card.dat should have the same number of element')
330
331
332 out.writelines(''.join(template % (ident[block][tag][0], i+1,val)
333 for i,val in enumerate(values)))
334 out.writelines('\n')
335
336
337
338
339
340
341
342
343
344 if nb_element ==0:
345 nb_element = 1
346 fsock = open(pjoin(output,'nb_tf.inc'),'w')
347 fsock.write("""
348 integer nb_tf
349 parameter (nb_tf=%i)
350 """ % nb_element)
351
352
353
354
356 """ value convertisor """
357 if type=='logical':
358 if value in ['F','f','0', 0, False]:
359 return '.false.'
360 elif value in ['T','t','1',1, True]:
361 return '.true.'
362 else:
363 return value
364 elif type in ['integer','string']:
365 return value
366 elif type in ['double','real']:
367 value = str(value)
368 value=value.replace('d','e')
369 value=value.replace('D','e')
370 value=float(value)
371 value='%(test)e' % {'test':value}
372 value=value.replace('e','d')
373 return value
374 else:
375 print('error in type for',value,type)
376
377
378 - def write(self, output):
379
380 if isinstance(output, str):
381 output = open(output, 'w')
382
383 header = """##########################################################################
384 ## ##
385 ## MadWeigth ##
386 ## ============= ##
387 ## ##
388 ## Run control ##
389 ## ----------- ##
390 ## ##
391 ## ##
392 ## Author: Mattelaer Olivier (UIUC) ##
393 ## Artoisenet Pierre (NIKHEF) ##
394 ## ##
395 ## Version: 5.0.0 ##
396 ## Last change: 27/03/13 ##
397 ## ##
398 ##########################################################################
399 ## ##
400 ## This Card defines all specific parameters of Madweight ##
401 ## ##
402 ##########################################################################
403 """
404 output.write(header)
405
406 for key in self:
407 if key == 'comment':
408 continue
409
410 output.write('\n\nBlock %s\n' % key)
411 for key2, value in self[key].items():
412 if key2 == 'comment':
413 continue
414 if isinstance(key2,tuple):
415 key2 = '%s'.join(map(str, key2))
416 comment = ''
417 try:
418 comment = self[key]['comment'][key2]
419 except Exception:
420 pass
421
422 if not isinstance(value, list):
423 value = [value]
424 for value in value:
425 output.write(' %s %s #%s\n' % (key2,value,comment))
426
427
428
429
430
431
432
433
434
435 -class Particles_file(Card):
436 """ all routine linked to particles.dat file """
437
438
439 - def __init__(self,file='./Source/MODEL/particles.dat',type=''):
440
441 self.charged = False
442 if not os.path.exists(file):
443 self.v4model = False
444
445 else:
446 self.v4model = True
447 Card.__init__(self, file, type)
448
449
451 """read a particles.dat file (don't read multiple info now)"""
452
453 self.charged=1
454 if self.v4model:
455 particle_pattern=re.compile(r'''^\s*
456 (?P<part>[\w+-~]{1,4})\s+
457 (?P<partx>[\w+-~]{1,5})\s+
458 (?P<spin>[SFVT])\s+
459 (?P<LineType>[WSDC])\s+
460 (?P<mass>\w+)\s+
461 (?P<width>\w+)\s+
462 (?P<color>[STO])\s+
463 (?P<label>[\w+-~]{1,5})\s+
464 (?P<pid>[\d-]*)\s*$''',re.VERBOSE)
465 ff=open(self.file,'r')
466
467 particle=[]
468 while 1:
469 line=ff.readline()
470 if line=='':
471 break
472 pat_particle=particle_pattern.search(line)
473 if pat_particle:
474 particle.append(list(pat_particle.groups()))
475
476 self.info={'particles':particle}
477 else:
478
479 try:
480 import internal.ufomodel.particles as particles
481 except Exception:
482 sys.path.append(pjoin(os.getcwd(), 'bin'))
483 import internal.ufomodel.particles as particles
484
485 v4_part_info = []
486 done = []
487 for p in particles.all_particles:
488 if p.pdg_code in done:
489 continue
490 done += [p.pdg_code,-1*p.pdg_code]
491 info = [p.name,
492 p.antiname,
493 p.spin,
494 p.line,
495 p.mass,
496 p.width,
497 p.color,
498 p.name,
499 p.pdg_code]
500 v4_part_info.append([str(i) for i in info])
501 self.info={'particles':v4_part_info}
502
503
504
505 - def give_pid_dict(self):
506 """ return a list of pid for each tag -d'ont treat multiple tag-"""
507
508 if not self.charged:
509 self.read()
510 pid={}
511 for data in self.info['particles']:
512
513 if data[0]==data[1]:
514 pid.update({data[0]:[int(data[-1])]})
515 else:
516 pid.update({data[0]:[int(data[-1])],data[1]:[-1*int(data[-1])]})
517
518 return pid
519
520
521
523 """ return two dict {pid:fortran_mass_code} and {pid:fortran_width_code}
524 pid value are always positive
525 """
526
527
528
529 if not self.charged:
530 self.read()
531 dict_mass={}
532 dict_width={}
533 for data in self.info['particles']:
534 pid=abs(int(data[-1]))
535 mass=data[-5]
536 width=data[-4]
537
538
539 if mass.lower() != 'zero':
540 dict_mass[pid]='mdl_%s' % mass
541 else:
542 dict_mass[pid] = str(mass)
543 if width.lower() != 'zero':
544 dict_width[pid] = 'mdl_%s' % width
545 else:
546 dict_width[pid] = str(width)
547
548
549
550 return dict_mass,dict_width
551
552
554 """ return a dict {pid:label}
555 """
556
557
558 return {1: 'd', 2: 'u', 3: 's', 4: 'c', 5: 'b', 6: 't', 11: 'e', 12: 've', 13: 'mu', 14: 'vm', 15: 'ta', 16: 'vt', 21: 'g', 22: 'A', 23: 'Z', 24: 'W', 25: 'h'}
559
560
561
562
563
564
565
566
567
568
569
570 return out
571
573 """ read a leshouches.inc file and returns [list of pid] in the MG order """
574
575
576
577 pid_pat=re.compile(r'''\s*DATA\s*\(IDUP\(I,\s*\d+\s*,\s*\d+\s*\),I=\d,\s*\d+\s*\)/(?P<pid>[\-,\s\d]*)/''',re.I)
578
579
580
581
582 dict_pid={}
583 ff=open(filepos,'r')
584 while 1:
585 line=ff.readline()
586
587
588 if line=='':
589 raise FileInputException('incorrect leshouche.inc at position '+filepos)
590 if line[5] != ' ':
591 line = old_line.rstrip() + line[6:]
592 if pid_pat.search(line):
593 pid_list=pid_pat.search(line).group('pid')
594 pid_list=pid_list.replace(',',' ').split()
595 ff.close()
596 break
597 old_line = line
598
599 return pid_list
600