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

Source Code for Module madgraph.madweight.Cards

  1  #!/usr/bin/env python 
  2  ########################################################################## 
  3  ##                                                                      ## 
  4  ##                               MadWeight                              ## 
  5  ##                               ---------                              ## 
  6  ########################################################################## 
  7  ##                                                                      ## 
  8  ##   author: Mattelaer Olivier (CP3)                                    ## 
  9  ##       email:  olivier.mattelaer@uclouvain.be                         ## 
 10  ##   author: Artoisenet Pierre (CP3)                                    ## 
 11  ##       email:  pierre.artoisenet@uclouvain.be                         ## 
 12  ##                                                                      ## 
 13  ########################################################################## 
 14  ##                                                                      ## 
 15  ##   license: GNU                                                       ## 
 16  ##   last-modif:04/08/08                                                ## 
 17  ##                                                                      ## 
 18  ########################################################################## 
 19  ##                                                                      ## 
 20  ##   Content                                                            ## 
 21  ##   -------                                                            ## 
 22  ##                                                                      ## 
 23  ##      + create_include_file                                           ## 
 24  ##      + Card                                                          ## 
 25  ##      |    + init                                                     ## 
 26  ##      |    |    +   detect_type                                       ## 
 27  ##      |    + read_card                                                ## 
 28  ##      |    + read_ident                                               ## 
 29  ##      |    + read_particles                                           ## 
 30  ##      |    |    +   give_pid_dict                                     ## 
 31  ##      |    + create_include_file                                      ## 
 32  ##      |    |    +   pass_in_type                                      ## 
 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   
48 -class FileInputException(Exception): pass
49 50 #1 #########################################################################
51 -def create_include_file(MWparam):
52 """ create all the include file and make all the link """ 53 54 #create include file corresponding to MW_card and transfer_card 55 #charge card 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 #create output 62 madweight.create_include_file(ident,'./Source/madweight_card.inc') 63 transfer.create_include_file_tf(ident,'./Source/MadWeight/transfer_function/') 64 65 #make all the symbolic link 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 #1 #########################################################################
73 -class Card(dict):
74 """ The routine to read and treat all the card (but the run_card.dat)""" 75 76 #2 #########################################################################
77 - def __init__(self,file,type=''):
78 79 dict.__init__(self) 80 self.info = self #retro compatibility 81 82 self.file=file 83 self.charged = 0 # most of the file are automaticaly read, but not all 84 85 if not type: 86 self.type=self.detect_type() 87 else: 88 self.type=type.lower() 89 90 if self.type in ['transfer','param','madweight']: 91 self.read(self.file) 92 elif(self.type in ['ident']): 93 self.read_ident()
94 95 96 97 #3 #########################################################################
98 - def detect_type(self):
99 """detect the type of the card """ 100 101 return self.file.split('/')[-1].split('_')[0].lower()
102 103 104 #2 #########################################################################
105 - def read_card(self,name_card):
106 """ DEPRECIATED """ 107 print("warning depreciated funtion read_card in use") 108 raise Exception 109 self.read(name_card)
110 111 #2 #########################################################################
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') #->read banner 130 131 #init output 132 info = self 133 self['comment'] = {} 134 name_block='' 135 136 #read the card 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 #deal with line as queue '-o test -d u' 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 #treat decay anomaly 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 #create list of dictionary 182 obj=line_content[-1] 183 for i in range(-2,-len(line_content)-1,-1): 184 obj={line_content[i]:obj} 185 #put in final data 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): #multiple definition of the same input 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 #2 #########################################################################
218 - def read_ident(self):
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 #2 #########################################################################
257 - def create_include_file(self,card,output):
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]: #check if default value is defined 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 #2 #########################################################################
287 - def create_include_file_tf(self,card,output):
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 #template = " DATA ( %s(I), I=1,nb_tf) / %s /\n" 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 # convert the input in the fortran format 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 # check that all element have the same number of input 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 # add the line 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 #if info[block].has_key(tag): 339 # value=self.pass_in_type(info[block][tag],ident[block][tag][1]) 340 # out.writelines(' '+ident[block][tag][0]+' = '+str(value)+'\n') 341 #elif ident[block][tag][2]: #check if default value is defined 342 # value=self.pass_in_type(ident[block][tag][2],ident[block][tag][1]) 343 # out.writelines(' '+ident[block][tag][0]+' = '+str(value)+'\n') 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 #3 #########################################################################
355 - def pass_in_type(self,value,type):
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 #3 #########################################################################
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 #2 #########################################################################
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 #UFO model 445 else: 446 self.v4model = True 447 Card.__init__(self, file, type)
448 449 #2 #########################################################################
450 - def read(self):
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 # UFO MODEL 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 #3 #########################################################################
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() #not automaticly read for the moment 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 #return {'e-': [11], 'a': [22], 've': [12], 'e+': [-11], 'w-': [-24], 'w+': [24], 'vm': [14], 'd~': [-1], 'b': [5], 'vt': [16], 'c~': [-4], 'ta-': [15], 'b~': [-5], 'ta+': [-15], 't~': [-6], 'vm~': [-14], 'c': [4], 'u~': [-2], 'd': [1], 'g': [21], 've~': [-12], 'h': [25], 's~': [-3], 's': [3], 'u': [2], 't': [6], 'mu-': [13], 'z': [23], 'mu+': [-13], 'vt~': [-16]} 520 521 #3 #########################################################################
522 - def give_mass_width_dict(self):
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() #not automaticly read for the moment 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 # Adding model prefixing 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 # return {1: 'ZERO', 2: 'ZERO', 3: 'ZERO', 4: 'ZERO', 5: 'MB', 6: 'MT', 11: 'ZERO', 12: 'ZERO', 13: 'ZERO', 14: 'ZERO', 15: 'MTA', 16: 'ZERO', 21: 'ZERO', 22: 'ZERO', 23: 'MZ', 24: 'MW', 25: 'MH'}, {1: 'ZERO', 2: 'ZERO', 3: 'ZERO', 4: 'ZERO', 5: 'ZERO', 6: 'WT', 11: 'ZERO', 12: 'ZERO', 13: 'ZERO', 14: 'ZERO', 15: 'ZERO', 16: 'ZERO', 21: 'ZERO', 22: 'WA', 23: 'WZ', 24: 'WW', 25: 'WH'} 549 550 return dict_mass,dict_width
551 552 #3 #########################################################################
553 - def give_pid_to_label(self):
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 # if not self.charged: 560 # self.read() #not automaticly read for the moment 561 # out={} 562 # for data in self.info['particles']: 563 # pid=abs(int(data[-1])) 564 # label=data[-2] 565 566 # out[pid]=label 567 568 569 570 return out
571
572 -def read_leshouches_file(filepos):
573 """ read a leshouches.inc file and returns [list of pid] in the MG order """ 574 575 576 # pid_pat=re.compile(r'''^\s*DATA\s+\(IDUP\(I,\s*\d+\s*\),I=\d,\s*\d+\s*\)/(?P<pid>[\-,\s\d]*)/''',re.I) 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 # mass_pat=re.compile(r'''^\s*pmass\(\s*(?P<MG_id>\d+)\s*\)\s*=\s*(?P<mass>\w+)''',re.I) 581 582 dict_pid={} 583 ff=open(filepos,'r') 584 while 1: 585 line=ff.readline() 586 #print line, [line[4],line[5], line[6]] 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() #pass to a list of pid 595 ff.close() 596 break 597 old_line = line 598 599 return pid_list
600