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