Package madgraph :: Package iolibs :: Module export_fks
[hide private]
[frames] | no frames]

Source Code for Module madgraph.iolibs.export_fks

   1  ################################################################################ 
   2  # 
   3  # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors 
   4  # 
   5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
   6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
   7  # high-energy processes in the Standard Model and beyond. 
   8  # 
   9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
  10  # distribution. 
  11  # 
  12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
  13  # 
  14  ################################################################################ 
  15  """Methods and classes to export matrix elements to fks format.""" 
  16   
  17  from distutils import dir_util 
  18  import glob 
  19  import logging 
  20  import os 
  21  import re 
  22  import shutil 
  23  import subprocess 
  24  import string 
  25  import copy 
  26  import platform 
  27   
  28  import madgraph.core.color_algebra as color 
  29  import madgraph.core.helas_objects as helas_objects 
  30  import madgraph.core.base_objects as base_objects 
  31  import madgraph.fks.fks_helas_objects as fks_helas_objects 
  32  import madgraph.fks.fks_base as fks 
  33  import madgraph.fks.fks_common as fks_common 
  34  import madgraph.iolibs.drawing_eps as draw 
  35  import madgraph.iolibs.gen_infohtml as gen_infohtml 
  36  import madgraph.iolibs.files as files 
  37  import madgraph.various.misc as misc 
  38  import madgraph.iolibs.file_writers as writers 
  39  import madgraph.iolibs.template_files as template_files 
  40  import madgraph.iolibs.ufo_expression_parsers as parsers 
  41  import madgraph.iolibs.export_v4 as export_v4 
  42  import madgraph.loop.loop_exporters as loop_exporters 
  43  import madgraph.various.q_polynomial as q_polynomial 
  44  import madgraph.various.banner as banner_mod 
  45   
  46  import aloha.create_aloha as create_aloha 
  47   
  48  import models.write_param_card as write_param_card 
  49  import models.check_param_card as check_param_card 
  50  from madgraph import MadGraph5Error, MG5DIR, InvalidCmd 
  51  from madgraph.iolibs.files import cp, ln, mv 
  52   
  53  pjoin = os.path.join 
  54   
  55  _file_path = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0] + '/' 
  56  logger = logging.getLogger('madgraph.export_fks') 
  57   
  58   
59 -def make_jpeg_async(args):
60 Pdir = args[0] 61 old_pos = args[1] 62 dir_path = args[2] 63 64 devnull = os.open(os.devnull, os.O_RDWR) 65 66 os.chdir(Pdir) 67 subprocess.call([os.path.join(old_pos, dir_path, 'bin', 'internal', 'gen_jpeg-pl')], 68 stdout = devnull) 69 os.chdir(os.path.pardir)
70 71 72 #================================================================================= 73 # Class for used of the (non-optimized) Loop process 74 #=================================================================================
75 -class ProcessExporterFortranFKS(loop_exporters.LoopProcessExporterFortranSA):
76 """Class to take care of exporting a set of matrix elements to 77 Fortran (v4) format.""" 78 79 #=============================================================================== 80 # copy the Template in a new directory. 81 #===============================================================================
82 - def copy_fkstemplate(self):
83 """create the directory run_name as a copy of the MadEvent 84 Template, and clean the directory 85 For now it is just the same as copy_v4template, but it will be modified 86 """ 87 mgme_dir = self.mgme_dir 88 dir_path = self.dir_path 89 clean =self.opt['clean'] 90 91 92 #First copy the full template tree if dir_path doesn't exit 93 if not os.path.isdir(dir_path): 94 if not mgme_dir: 95 raise MadGraph5Error, \ 96 "No valid MG_ME path given for MG4 run directory creation." 97 logger.info('initialize a new directory: %s' % \ 98 os.path.basename(dir_path)) 99 shutil.copytree(os.path.join(mgme_dir, 'Template', 'NLO'), dir_path, True) 100 # distutils.dir_util.copy_tree since dir_path already exists 101 dir_util.copy_tree(pjoin(self.mgme_dir, 'Template', 'Common'), 102 dir_path) 103 elif not os.path.isfile(os.path.join(dir_path, 'TemplateVersion.txt')): 104 if not mgme_dir: 105 raise MadGraph5Error, \ 106 "No valid MG_ME path given for MG4 run directory creation." 107 try: 108 shutil.copy(os.path.join(mgme_dir, 'MGMEVersion.txt'), dir_path) 109 except IOError: 110 MG5_version = misc.get_pkg_info() 111 open(os.path.join(dir_path, 'MGMEVersion.txt'), 'w').write( \ 112 "5." + MG5_version['version']) 113 114 #Ensure that the Template is clean 115 if clean: 116 logger.info('remove old information in %s' % os.path.basename(dir_path)) 117 if os.environ.has_key('MADGRAPH_BASE'): 118 subprocess.call([os.path.join('bin', 'internal', 'clean_template'), 119 '--web'],cwd=dir_path) 120 else: 121 try: 122 subprocess.call([os.path.join('bin', 'internal', 'clean_template')], \ 123 cwd=dir_path) 124 except Exception, why: 125 raise MadGraph5Error('Failed to clean correctly %s: \n %s' \ 126 % (os.path.basename(dir_path),why)) 127 #Write version info 128 MG_version = misc.get_pkg_info() 129 open(os.path.join(dir_path, 'SubProcesses', 'MGVersion.txt'), 'w').write( 130 MG_version['version']) 131 132 # We must link the CutTools to the Library folder of the active Template 133 self.link_CutTools(dir_path) 134 135 link_tir_libs=[] 136 tir_libs=[] 137 os.remove(os.path.join(self.dir_path,'SubProcesses','makefile_loop.inc')) 138 dirpath = os.path.join(self.dir_path, 'SubProcesses') 139 filename = pjoin(self.dir_path, 'SubProcesses','makefile_loop') 140 calls = self.write_makefile_TIR(writers.MakefileWriter(filename), 141 link_tir_libs,tir_libs) 142 os.remove(os.path.join(self.dir_path,'Source','make_opts.inc')) 143 filename = pjoin(self.dir_path, 'Source','make_opts') 144 calls = self.write_make_opts(writers.MakefileWriter(filename), 145 link_tir_libs,tir_libs) 146 147 # Duplicate run_card and FO_analyse_card 148 for card in ['FO_analyse_card', 'shower_card']: 149 try: 150 shutil.copy(pjoin(self.dir_path, 'Cards', 151 card + '.dat'), 152 pjoin(self.dir_path, 'Cards', 153 card + '_default.dat')) 154 except IOError: 155 logger.warning("Failed to copy " + card + ".dat to default") 156 157 cwd = os.getcwd() 158 dirpath = os.path.join(self.dir_path, 'SubProcesses') 159 try: 160 os.chdir(dirpath) 161 except os.error: 162 logger.error('Could not cd to directory %s' % dirpath) 163 return 0 164 165 # We add here the user-friendly MadLoop option setter. 166 cpfiles= ["SubProcesses/MadLoopParamReader.f", 167 "Cards/MadLoopParams.dat", 168 "SubProcesses/MadLoopParams.inc"] 169 170 for file in cpfiles: 171 shutil.copy(os.path.join(self.loop_dir,'StandAlone/', file), 172 os.path.join(self.dir_path, file)) 173 174 shutil.copy(pjoin(self.dir_path, 'Cards','MadLoopParams.dat'), 175 pjoin(self.dir_path, 'Cards','MadLoopParams_default.dat')) 176 177 if os.path.exists(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')): 178 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.dir_path, 179 'Cards', 'MadLoopParams.dat')) 180 # write the output file 181 self.MadLoopparam.write(pjoin(self.dir_path,"SubProcesses", 182 "MadLoopParams.dat")) 183 184 # We need minimal editing of MadLoopCommons.f 185 MadLoopCommon = open(os.path.join(self.loop_dir,'StandAlone', 186 "SubProcesses","MadLoopCommons.inc")).read() 187 writer = writers.FortranWriter(os.path.join(self.dir_path, 188 "SubProcesses","MadLoopCommons.f")) 189 writer.writelines(MadLoopCommon%{ 190 'print_banner_commands':self.MadLoop_banner}) 191 writer.close() 192 193 # Write the cts_mpc.h and cts_mprec.h files imported from CutTools 194 self.write_mp_files(writers.FortranWriter('cts_mprec.h'),\ 195 writers.FortranWriter('cts_mpc.h')) 196 197 198 # Finally make sure to turn off MC over Hel for the default mode. 199 FKS_card_path = pjoin(self.dir_path,'Cards','FKS_params.dat') 200 FKS_card_file = open(FKS_card_path,'r') 201 FKS_card = FKS_card_file.read() 202 FKS_card_file.close() 203 FKS_card = re.sub(r"#NHelForMCoverHels\n-?\d+", 204 "#NHelForMCoverHels\n-1", FKS_card) 205 FKS_card_file = open(FKS_card_path,'w') 206 FKS_card_file.write(FKS_card) 207 FKS_card_file.close() 208 209 # Return to original PWD 210 os.chdir(cwd) 211 # Copy the different python files in the Template 212 self.copy_python_files() 213 214 # We need to create the correct open_data for the pdf 215 self.write_pdf_opendata()
216 217 # I put it here not in optimized one, because I want to use the same makefile_loop.inc 218 # Also, we overload this function (i.e. it is already defined in 219 # LoopProcessExporterFortranSA) because the path of the template makefile 220 # is different.
221 - def write_makefile_TIR(self, writer, link_tir_libs,tir_libs,tir_include=[]):
222 """ Create the file makefile_loop which links to the TIR libraries.""" 223 224 file = open(os.path.join(self.mgme_dir,'Template','NLO', 225 'SubProcesses','makefile_loop.inc')).read() 226 replace_dict={} 227 replace_dict['link_tir_libs']=' '.join(link_tir_libs) 228 replace_dict['tir_libs']=' '.join(tir_libs) 229 replace_dict['dotf']='%.f' 230 replace_dict['doto']='%.o' 231 replace_dict['tir_include']=' '.join(tir_include) 232 file=file%replace_dict 233 if writer: 234 writer.writelines(file) 235 else: 236 return file
237 238 # I put it here not in optimized one, because I want to use the same make_opts.inc
239 - def write_make_opts(self, writer, link_tir_libs,tir_libs):
240 """ Create the file make_opts which links to the TIR libraries.""" 241 file = open(os.path.join(self.mgme_dir,'Template','NLO', 242 'Source','make_opts.inc')).read() 243 replace_dict={} 244 replace_dict['link_tir_libs']=' '.join(link_tir_libs) 245 replace_dict['tir_libs']=' '.join(tir_libs) 246 replace_dict['dotf']='%.f' 247 replace_dict['doto']='%.o' 248 file=file%replace_dict 249 if writer: 250 writer.writelines(file) 251 else: 252 return file
253 254 #=========================================================================== 255 # copy_python_files 256 #===========================================================================
257 - def copy_python_files(self):
258 """copy python files required for the Template""" 259 260 files_to_copy = [ \ 261 pjoin('interface','amcatnlo_run_interface.py'), 262 pjoin('interface','extended_cmd.py'), 263 pjoin('interface','common_run_interface.py'), 264 pjoin('interface','coloring_logging.py'), 265 pjoin('various','misc.py'), 266 pjoin('various','shower_card.py'), 267 pjoin('various','FO_analyse_card.py'), 268 pjoin('various','histograms.py'), 269 pjoin('various','banner.py'), 270 pjoin('various','cluster.py'), 271 pjoin('various','lhe_parser.py'), 272 pjoin('madevent','sum_html.py'), 273 pjoin('madevent','gen_crossxhtml.py'), 274 pjoin('iolibs','files.py'), 275 pjoin('iolibs','save_load_object.py'), 276 pjoin('iolibs','file_writers.py'), 277 pjoin('..','models','check_param_card.py'), 278 pjoin('__init__.py') 279 ] 280 cp(_file_path+'/interface/.mg5_logging.conf', 281 self.dir_path+'/bin/internal/me5_logging.conf') 282 283 for cp_file in files_to_copy: 284 cp(pjoin(_file_path,cp_file), 285 pjoin(self.dir_path,'bin','internal',os.path.basename(cp_file)))
286
287 - def convert_model_to_mg4(self, model, wanted_lorentz = [], 288 wanted_couplings = []):
289 290 super(ProcessExporterFortranFKS,self).convert_model_to_mg4(model, 291 wanted_lorentz, wanted_couplings) 292 293 IGNORE_PATTERNS = ('*.pyc','*.dat','*.py~') 294 try: 295 shutil.rmtree(pjoin(self.dir_path,'bin','internal','ufomodel')) 296 except OSError as error: 297 pass 298 model_path = model.get('modelpath') 299 shutil.copytree(model_path, 300 pjoin(self.dir_path,'bin','internal','ufomodel'), 301 ignore=shutil.ignore_patterns(*IGNORE_PATTERNS)) 302 if hasattr(model, 'restrict_card'): 303 out_path = pjoin(self.dir_path, 'bin', 'internal','ufomodel', 304 'restrict_default.dat') 305 if isinstance(model.restrict_card, check_param_card.ParamCard): 306 model.restrict_card.write(out_path) 307 else: 308 files.cp(model.restrict_card, out_path)
309 310 311 312 #=========================================================================== 313 # write_maxparticles_file 314 #===========================================================================
315 - def write_maxparticles_file(self, writer, maxparticles):
316 """Write the maxparticles.inc file for MadEvent""" 317 318 lines = "integer max_particles, max_branch\n" 319 lines += "parameter (max_particles=%d) \n" % maxparticles 320 lines += "parameter (max_branch=max_particles-1)" 321 322 # Write the file 323 writer.writelines(lines) 324 325 return True
326 327 328 #=========================================================================== 329 # write_maxconfigs_file 330 #===========================================================================
331 - def write_maxconfigs_file(self, writer, maxconfigs):
332 """Write the maxconfigs.inc file for MadEvent""" 333 334 lines = "integer lmaxconfigs\n" 335 lines += "parameter (lmaxconfigs=%d)" % maxconfigs 336 337 # Write the file 338 writer.writelines(lines) 339 340 return True
341 342 343 #=============================================================================== 344 # write a procdef_mg5 (an equivalent of the MG4 proc_card.dat) 345 #===============================================================================
346 - def write_procdef_mg5(self, file_pos, modelname, process_str):
347 """ write an equivalent of the MG4 proc_card in order that all the Madevent 348 Perl script of MadEvent4 are still working properly for pure MG5 run.""" 349 350 proc_card_template = template_files.mg4_proc_card.mg4_template 351 process_template = template_files.mg4_proc_card.process_template 352 process_text = '' 353 coupling = '' 354 new_process_content = [] 355 356 # First find the coupling and suppress the coupling from process_str 357 #But first ensure that coupling are define whithout spaces: 358 process_str = process_str.replace(' =', '=') 359 process_str = process_str.replace('= ', '=') 360 process_str = process_str.replace(',',' , ') 361 #now loop on the element and treat all the coupling 362 for info in process_str.split(): 363 if '=' in info: 364 coupling += info + '\n' 365 else: 366 new_process_content.append(info) 367 # Recombine the process_str (which is the input process_str without coupling 368 #info) 369 process_str = ' '.join(new_process_content) 370 371 #format the SubProcess 372 process_text += process_template.substitute({'process': process_str, \ 373 'coupling': coupling}) 374 375 text = proc_card_template.substitute({'process': process_text, 376 'model': modelname, 377 'multiparticle':''}) 378 ff = open(file_pos, 'w') 379 ff.write(text) 380 ff.close()
381 382 383 #=============================================================================== 384 # write a initial states map, useful for the fast PDF NLO interface 385 #===============================================================================
386 - def write_init_map(self, file_pos, initial_states):
387 """ Write an initial state process map. Each possible PDF 388 combination gets an unique identifier.""" 389 390 text='' 391 for i,e in enumerate(initial_states): 392 text=text+str(i+1)+' '+str(len(e)) 393 for t in e: 394 text=text+' ' 395 try: 396 for p in t: 397 text=text+' '+str(p) 398 except TypeError: 399 text=text+' '+str(t) 400 text=text+'\n' 401 402 ff = open(file_pos, 'w') 403 ff.write(text) 404 ff.close()
405
406 - def get_ME_identifier(self, matrix_element, *args, **opts):
407 """ A function returning a string uniquely identifying the matrix 408 element given in argument so that it can be used as a prefix to all 409 MadLoop5 subroutines and common blocks related to it. This allows 410 to compile several processes into one library as requested by the 411 BLHA (Binoth LesHouches Accord) guidelines. The MadFKS design 412 necessitates that there is no process prefix.""" 413 414 return ''
415 416 #=============================================================================== 417 # write_coef_specs 418 #===============================================================================
419 - def write_coef_specs_file(self, virt_me_list):
420 """writes the coef_specs.inc in the DHELAS folder. Should not be called in the 421 non-optimized mode""" 422 raise fks_common.FKSProcessError(), \ 423 "write_coef_specs should be called only in the loop-optimized mode"
424 425 426 #=============================================================================== 427 # generate_directories_fks 428 #===============================================================================
429 - def generate_directories_fks(self, matrix_element, fortran_model, me_number, 430 me_ntot, path=os.getcwd(),OLP='MadLoop'):
431 """Generate the Pxxxxx_i directories for a subprocess in MadFKS, 432 including the necessary matrix.f and various helper files""" 433 proc = matrix_element.born_matrix_element['processes'][0] 434 435 if not self.model: 436 self.model = matrix_element.get('processes')[0].get('model') 437 438 cwd = os.getcwd() 439 try: 440 os.chdir(path) 441 except OSError, error: 442 error_msg = "The directory %s should exist in order to be able " % path + \ 443 "to \"export\" in it. If you see this error message by " + \ 444 "typing the command \"export\" please consider to use " + \ 445 "instead the command \"output\". " 446 raise MadGraph5Error, error_msg 447 448 calls = 0 449 450 self.fksdirs = [] 451 #first make and cd the direcrory corresponding to the born process: 452 borndir = "P%s" % \ 453 (matrix_element.get('processes')[0].shell_string()) 454 os.mkdir(borndir) 455 os.chdir(borndir) 456 logger.info('Writing files in %s (%d / %d)' % (borndir, me_number + 1, me_ntot)) 457 458 ## write the files corresponding to the born process in the P* directory 459 self.generate_born_fks_files(matrix_element, 460 fortran_model, me_number, path) 461 462 # With NJET you want to generate the order file per subprocess and most 463 # likely also generate it for each subproc. 464 if OLP=='NJET': 465 filename = 'OLE_order.lh' 466 self.write_lh_order(filename, [matrix_element.born_matrix_element.get('processes')[0]], OLP) 467 468 if matrix_element.virt_matrix_element: 469 calls += self.generate_virt_directory( \ 470 matrix_element.virt_matrix_element, \ 471 fortran_model, \ 472 os.path.join(path, borndir)) 473 474 #write the infortions for the different real emission processes 475 476 self.write_real_matrix_elements(matrix_element, fortran_model) 477 478 self.write_pdf_calls(matrix_element, fortran_model) 479 480 filename = 'nFKSconfigs.inc' 481 self.write_nfksconfigs_file(writers.FortranWriter(filename), 482 matrix_element, 483 fortran_model) 484 485 filename = 'iproc.dat' 486 self.write_iproc_file(writers.FortranWriter(filename), 487 me_number) 488 489 filename = 'fks_info.inc' 490 self.write_fks_info_file(writers.FortranWriter(filename), 491 matrix_element, 492 fortran_model) 493 494 filename = 'leshouche_info.dat' 495 nfksconfs,maxproc,maxflow,nexternal=\ 496 self.write_leshouche_info_file(filename,matrix_element) 497 498 # if no corrections are generated ([LOonly] mode), get 499 # these variables from the born 500 if nfksconfs == maxproc == maxflow == 0: 501 nfksconfs = 1 502 (dummylines, maxproc, maxflow) = self.get_leshouche_lines( 503 matrix_element.born_matrix_element, 1) 504 505 filename = 'leshouche_decl.inc' 506 self.write_leshouche_info_declarations( 507 writers.FortranWriter(filename), 508 nfksconfs,maxproc,maxflow,nexternal, 509 fortran_model) 510 511 filename = 'configs_and_props_info.dat' 512 nconfigs,max_leg_number,nfksconfs=self.write_configs_and_props_info_file( 513 filename, 514 matrix_element) 515 516 filename = 'configs_and_props_decl.inc' 517 self.write_configs_and_props_info_declarations( 518 writers.FortranWriter(filename), 519 nconfigs,max_leg_number,nfksconfs, 520 fortran_model) 521 522 filename = 'real_from_born_configs.inc' 523 self.write_real_from_born_configs( 524 writers.FortranWriter(filename), 525 matrix_element, 526 fortran_model) 527 528 filename = 'ngraphs.inc' 529 self.write_ngraphs_file(writers.FortranWriter(filename), 530 nconfigs) 531 532 #write the wrappers 533 filename = 'real_me_chooser.f' 534 self.write_real_me_wrapper(writers.FortranWriter(filename), 535 matrix_element, 536 fortran_model) 537 538 filename = 'parton_lum_chooser.f' 539 self.write_pdf_wrapper(writers.FortranWriter(filename), 540 matrix_element, 541 fortran_model) 542 543 filename = 'get_color.f' 544 self.write_colors_file(writers.FortranWriter(filename), 545 matrix_element) 546 547 filename = 'nexternal.inc' 548 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 549 self.write_nexternal_file(writers.FortranWriter(filename), 550 nexternal, ninitial) 551 self.proc_characteristic['ninitial'] = ninitial 552 self.proc_characteristic['nexternal'] = max(self.proc_characteristic['nexternal'], nexternal) 553 554 filename = 'pmass.inc' 555 try: 556 self.write_pmass_file(writers.FortranWriter(filename), 557 matrix_element.real_processes[0].matrix_element) 558 except IndexError: 559 self.write_pmass_file(writers.FortranWriter(filename), 560 matrix_element.born_matrix_element) 561 562 #draw the diagrams 563 self.draw_feynman_diagrams(matrix_element) 564 565 linkfiles = ['BinothLHADummy.f', 566 'check_poles.f', 567 'MCmasses_HERWIG6.inc', 568 'MCmasses_HERWIGPP.inc', 569 'MCmasses_PYTHIA6Q.inc', 570 'MCmasses_PYTHIA6PT.inc', 571 'MCmasses_PYTHIA8.inc', 572 'add_write_info.f', 573 'coupl.inc', 574 'cuts.f', 575 'FKS_params.dat', 576 'initial_states_map.dat', 577 'OLE_order.olc', 578 'FKSParams.inc', 579 'FKSParamReader.f', 580 'cuts.inc', 581 'unlops.inc', 582 'pythia_unlops.f', 583 'driver_mintMC.f', 584 'driver_mintFO.f', 585 'driver_vegas.f', 586 'appl_interface.cc', 587 'appl_interface_dummy.f', 588 'appl_common.inc', 589 'reweight_appl.inc', 590 'driver_reweight.f', 591 'fastjetfortran_madfks_core.cc', 592 'fastjetfortran_madfks_full.cc', 593 'fjcore.cc', 594 'fastjet_wrapper.f', 595 'fjcore.hh', 596 'fks_Sij.f', 597 'fks_powers.inc', 598 'fks_singular.f', 599 'veto_xsec.f', 600 'veto_xsec.inc', 601 'c_weight.inc', 602 'fks_inc_chooser.f', 603 'leshouche_inc_chooser.f', 604 'configs_and_props_inc_chooser.f', 605 'genps.inc', 606 'genps_fks.f', 607 'boostwdir2.f', 608 'madfks_mcatnlo.inc', 609 'open_output_files.f', 610 'open_output_files_dummy.f', 611 'HwU_dummy.f', 612 'madfks_plot.f', 613 'analysis_dummy.f', 614 'mint-integrator2.f', 615 'MC_integer.f', 616 'mint.inc', 617 'montecarlocounter.f', 618 'q_es.inc', 619 'recluster.cc', 620 'Boosts.h', 621 'reweight.inc', 622 'reweight0.inc', 623 'reweight1.inc', 624 'reweightNLO.inc', 625 'reweight_all.inc', 626 'reweight_events.f', 627 'reweight_xsec.f', 628 'reweight_xsec_events.f', 629 'reweight_xsec_events_pdf_dummy.f', 630 'iproc_map.f', 631 'run.inc', 632 'run_card.inc', 633 'setcuts.f', 634 'setscales.f', 635 'symmetry_fks_test_MC.f', 636 'symmetry_fks_test_ME.f', 637 'symmetry_fks_test_Sij.f', 638 'symmetry_fks_v3.f', 639 'trapfpe.c', 640 'vegas2.for', 641 'write_ajob.f', 642 'handling_lhe_events.f', 643 'write_event.f', 644 'fill_MC_mshell.f', 645 'maxparticles.inc', 646 'message.inc', 647 'initcluster.f', 648 'cluster.inc', 649 'cluster.f', 650 'reweight.f', 651 'randinit', 652 'sudakov.inc', 653 'maxconfigs.inc', 654 'timing_variables.inc'] 655 656 for file in linkfiles: 657 ln('../' + file , '.') 658 os.system("ln -s ../../Cards/param_card.dat .") 659 660 #copy the makefile 661 os.system("ln -s ../makefile_fks_dir ./makefile") 662 if matrix_element.virt_matrix_element: 663 os.system("ln -s ../BinothLHA.f ./BinothLHA.f") 664 elif OLP!='MadLoop': 665 os.system("ln -s ../BinothLHA_OLP.f ./BinothLHA.f") 666 else: 667 os.system("ln -s ../BinothLHA_user.f ./BinothLHA.f") 668 669 670 #import nexternal/leshouches in Source 671 ln('nexternal.inc', '../../Source', log=False) 672 ln('born_leshouche.inc', '../../Source', log=False) 673 674 675 # Return to SubProcesses dir 676 os.chdir(os.path.pardir) 677 # Add subprocess to subproc.mg 678 filename = 'subproc.mg' 679 files.append_to_file(filename, 680 self.write_subproc, 681 borndir) 682 683 684 os.chdir(cwd) 685 # Generate info page 686 gen_infohtml.make_info_html_nlo(self.dir_path) 687 688 689 return calls
690 691 #=========================================================================== 692 # create the run_card 693 #===========================================================================
694 - def create_run_card(self, processes, history):
695 """ """ 696 697 run_card = banner_mod.RunCardNLO() 698 699 run_card.create_default_for_process(self.proc_characteristic, 700 history, 701 processes) 702 703 run_card.write(pjoin(self.dir_path, 'Cards', 'run_card_default.dat')) 704 run_card.write(pjoin(self.dir_path, 'Cards', 'run_card.dat'))
705 706
707 - def finalize_fks_directory(self, matrix_elements, history, makejpg = False, 708 online = False, 709 compiler_dict={'fortran': 'gfortran', 'cpp': 'g++'}, 710 output_dependencies = 'external', MG5DIR = None):
711 """Finalize FKS directory by creating jpeg diagrams, html 712 pages,proc_card_mg5.dat and madevent.tar.gz.""" 713 714 self.proc_characteristic['grouped_matrix'] = False 715 self.create_proc_charac() 716 717 self.create_run_card(matrix_elements.get_processes(), history) 718 # modelname = self.model.get('name') 719 # if modelname == 'mssm' or modelname.startswith('mssm-'): 720 # param_card = os.path.join(self.dir_path, 'Cards','param_card.dat') 721 # mg5_param = os.path.join(self.dir_path, 'Source', 'MODEL', 'MG5_param.dat') 722 # check_param_card.convert_to_mg5card(param_card, mg5_param) 723 # check_param_card.check_valid_param_card(mg5_param) 724 725 # # write the model functions get_mass/width_from_id 726 filename = os.path.join(self.dir_path,'Source','MODEL','get_mass_width_fcts.f') 727 makeinc = os.path.join(self.dir_path,'Source','MODEL','makeinc.inc') 728 self.write_get_mass_width_file(writers.FortranWriter(filename), makeinc, self.model) 729 730 # # Write maxconfigs.inc based on max of ME's/subprocess groups 731 732 filename = os.path.join(self.dir_path,'Source','maxconfigs.inc') 733 self.write_maxconfigs_file(writers.FortranWriter(filename), 734 matrix_elements.get_max_configs()) 735 736 # # Write maxparticles.inc based on max of ME's/subprocess groups 737 filename = os.path.join(self.dir_path,'Source','maxparticles.inc') 738 self.write_maxparticles_file(writers.FortranWriter(filename), 739 matrix_elements.get_max_particles()) 740 741 # Touch "done" file 742 os.system('touch %s/done' % os.path.join(self.dir_path,'SubProcesses')) 743 744 # Check for compiler 745 fcompiler_chosen = self.set_fortran_compiler(compiler_dict) 746 ccompiler_chosen = self.set_cpp_compiler(compiler_dict['cpp']) 747 748 old_pos = os.getcwd() 749 os.chdir(os.path.join(self.dir_path, 'SubProcesses')) 750 P_dir_list = [proc for proc in os.listdir('.') if os.path.isdir(proc) and \ 751 proc[0] == 'P'] 752 753 devnull = os.open(os.devnull, os.O_RDWR) 754 # Convert the poscript in jpg files (if authorize) 755 if makejpg: 756 logger.info("Generate jpeg diagrams") 757 for Pdir in P_dir_list: 758 os.chdir(Pdir) 759 subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_jpeg-pl')], 760 stdout = devnull) 761 os.chdir(os.path.pardir) 762 # 763 logger.info("Generate web pages") 764 # Create the WebPage using perl script 765 766 subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], \ 767 stdout = devnull) 768 769 os.chdir(os.path.pardir) 770 # 771 # obj = gen_infohtml.make_info_html(self.dir_path) 772 # [mv(name, './HTML/') for name in os.listdir('.') if \ 773 # (name.endswith('.html') or name.endswith('.jpg')) and \ 774 # name != 'index.html'] 775 # if online: 776 # nb_channel = obj.rep_rule['nb_gen_diag'] 777 # open(os.path.join('./Online'),'w').write(str(nb_channel)) 778 779 # Write command history as proc_card_mg5 780 if os.path.isdir('Cards'): 781 output_file = os.path.join('Cards', 'proc_card_mg5.dat') 782 history.write(output_file) 783 784 # Duplicate run_card and FO_analyse_card 785 for card in ['run_card', 'FO_analyse_card', 'shower_card']: 786 try: 787 shutil.copy(pjoin(self.dir_path, 'Cards', 788 card + '.dat'), 789 pjoin(self.dir_path, 'Cards', 790 card + '_default.dat')) 791 except IOError: 792 logger.warning("Failed to copy " + card + ".dat to default") 793 794 795 subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], 796 stdout = devnull) 797 798 # Run "make" to generate madevent.tar.gz file 799 if os.path.exists(pjoin('SubProcesses', 'subproc.mg')): 800 if os.path.exists('amcatnlo.tar.gz'): 801 os.remove('amcatnlo.tar.gz') 802 subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'make_amcatnlo_tar')], 803 stdout = devnull) 804 # 805 subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], 806 stdout = devnull) 807 808 #return to the initial dir 809 os.chdir(old_pos) 810 811 # Setup stdHep 812 # Find the correct fortran compiler 813 base_compiler= ['FC=g77','FC=gfortran'] 814 815 StdHep_path = pjoin(MG5DIR, 'vendor', 'StdHEP') 816 817 if output_dependencies == 'external': 818 # check if stdhep has to be compiled (only the first time) 819 if not os.path.exists(pjoin(MG5DIR, 'vendor', 'StdHEP', 'lib', 'libstdhep.a')) or \ 820 not os.path.exists(pjoin(MG5DIR, 'vendor', 'StdHEP', 'lib', 'libFmcfio.a')): 821 if 'FC' not in os.environ or not os.environ['FC']: 822 path = os.path.join(StdHep_path, 'src', 'make_opts') 823 text = open(path).read() 824 for base in base_compiler: 825 text = text.replace(base,'FC=%s' % fcompiler_chosen) 826 open(path, 'w').writelines(text) 827 828 logger.info('Compiling StdHEP. This has to be done only once.') 829 misc.compile(cwd = pjoin(MG5DIR, 'vendor', 'StdHEP')) 830 logger.info('Done.') 831 #then link the libraries in the exported dir 832 files.ln(pjoin(StdHep_path, 'lib', 'libstdhep.a'), \ 833 pjoin(self.dir_path, 'MCatNLO', 'lib')) 834 files.ln(pjoin(StdHep_path, 'lib', 'libFmcfio.a'), \ 835 pjoin(self.dir_path, 'MCatNLO', 'lib')) 836 837 elif output_dependencies == 'internal': 838 StdHEP_internal_path = pjoin(self.dir_path,'Source','StdHEP') 839 shutil.copytree(StdHep_path,StdHEP_internal_path, symlinks=True) 840 # Create the links to the lib folder 841 linkfiles = ['libstdhep.a', 'libFmcfio.a'] 842 for file in linkfiles: 843 ln(pjoin(os.path.pardir,os.path.pardir,'Source','StdHEP','lib',file), 844 os.path.join(self.dir_path, 'MCatNLO', 'lib')) 845 if 'FC' not in os.environ or not os.environ['FC']: 846 path = pjoin(StdHEP_internal_path, 'src', 'make_opts') 847 text = open(path).read() 848 for base in base_compiler: 849 text = text.replace(base,'FC=%s' % fcompiler_chosen) 850 open(path, 'w').writelines(text) 851 # To avoid compiler version conflicts, we force a clean here 852 misc.compile(['clean'],cwd = StdHEP_internal_path) 853 854 elif output_dependencies == 'environment_paths': 855 # Here the user chose to define the dependencies path in one of 856 # his environmental paths 857 libStdHep = misc.which_lib('libstdhep.a') 858 libFmcfio = misc.which_lib('libFmcfio.a') 859 if not libStdHep is None and not libFmcfio is None: 860 logger.info('MG5_aMC is using StdHep installation found at %s.'%\ 861 os.path.dirname(libStdHep)) 862 ln(pjoin(libStdHep),pjoin(self.dir_path, 'MCatNLO', 'lib'),abspath=True) 863 ln(pjoin(libFmcfio),pjoin(self.dir_path, 'MCatNLO', 'lib'),abspath=True) 864 else: 865 raise InvalidCmd("Could not find the location of the files"+\ 866 " libstdhep.a and libFmcfio.a in you environment paths.") 867 868 else: 869 raise MadGraph5Error, 'output_dependencies option %s not recognized'\ 870 %output_dependencies
871 872
873 - def write_real_from_born_configs(self, writer, matrix_element, fortran_model):
874 """Writes the real_from_born_configs.inc file that contains 875 the mapping to go for a given born configuration (that is used 876 e.g. in the multi-channel phase-space integration to the 877 corresponding real-emission diagram, i.e. the real emission 878 diagram in which the combined ij is split in i_fks and 879 j_fks.""" 880 lines=[] 881 lines2=[] 882 max_links=0 883 born_me=matrix_element.born_matrix_element 884 for iFKS, conf in enumerate(matrix_element.get_fks_info_list()): 885 iFKS=iFKS+1 886 links=conf['fks_info']['rb_links'] 887 max_links=max(max_links,len(links)) 888 for i,diags in enumerate(links): 889 if not i == diags['born_conf']: 890 print links 891 raise MadGraph5Error, "born_conf should be canonically ordered" 892 real_configs=', '.join(['%d' % int(diags['real_conf']+1) for diags in links]) 893 lines.append("data (real_from_born_conf(irfbc,%d),irfbc=1,%d) /%s/" \ 894 % (iFKS,len(links),real_configs)) 895 896 lines2.append("integer irfbc") 897 lines2.append("integer real_from_born_conf(%d,%d)" \ 898 % (max_links,len(matrix_element.get_fks_info_list()))) 899 # Write the file 900 writer.writelines(lines2+lines)
901 902 903 #=============================================================================== 904 # write_get_mass_width_file 905 #=============================================================================== 906 #test written
907 - def write_get_mass_width_file(self, writer, makeinc, model):
908 """Write the get_mass_width_file.f file for MG4. 909 Also update the makeinc.inc file 910 """ 911 mass_particles = [p for p in model['particles'] if p['mass'].lower() != 'zero'] 912 width_particles = [p for p in model['particles'] if p['width'].lower() != 'zero'] 913 914 iflines_mass = '' 915 iflines_width = '' 916 917 for i, part in enumerate(mass_particles): 918 if i == 0: 919 ifstring = 'if' 920 else: 921 ifstring = 'else if' 922 if part['self_antipart']: 923 iflines_mass += '%s (id.eq.%d) then\n' % \ 924 (ifstring, part.get_pdg_code()) 925 else: 926 iflines_mass += '%s (id.eq.%d.or.id.eq.%d) then\n' % \ 927 (ifstring, part.get_pdg_code(), part.get_anti_pdg_code()) 928 iflines_mass += 'get_mass_from_id=abs(%s)\n' % part.get('mass') 929 930 for i, part in enumerate(width_particles): 931 if i == 0: 932 ifstring = 'if' 933 else: 934 ifstring = 'else if' 935 if part['self_antipart']: 936 iflines_width += '%s (id.eq.%d) then\n' % \ 937 (ifstring, part.get_pdg_code()) 938 else: 939 iflines_width += '%s (id.eq.%d.or.id.eq.%d) then\n' % \ 940 (ifstring, part.get_pdg_code(), part.get_anti_pdg_code()) 941 iflines_width += 'get_width_from_id=abs(%s)\n' % part.get('width') 942 943 replace_dict = {'iflines_mass' : iflines_mass, 944 'iflines_width' : iflines_width} 945 946 file = open(os.path.join(_file_path, \ 947 'iolibs/template_files/get_mass_width_fcts.inc')).read() 948 file = file % replace_dict 949 950 # Write the file 951 writer.writelines(file) 952 953 # update the makeinc 954 makeinc_content = open(makeinc).read() 955 makeinc_content = makeinc_content.replace('MODEL = ', 'MODEL = get_mass_width_fcts.o ') 956 open(makeinc, 'w').write(makeinc_content) 957 958 return
959 960
961 - def write_configs_and_props_info_declarations(self, writer, max_iconfig, max_leg_number, nfksconfs, fortran_model):
962 """writes the declarations for the variables relevant for configs_and_props 963 """ 964 lines = [] 965 lines.append("integer ifr,lmaxconfigs_used,max_branch_used") 966 lines.append("parameter (lmaxconfigs_used=%4d)" % max_iconfig) 967 lines.append("parameter (max_branch_used =%4d)" % -max_leg_number) 968 lines.append("integer mapconfig_d(%3d,0:lmaxconfigs_used)" % nfksconfs) 969 lines.append("integer iforest_d(%3d,2,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 970 lines.append("integer sprop_d(%3d,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 971 lines.append("integer tprid_d(%3d,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 972 lines.append("double precision pmass_d(%3d,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 973 lines.append("double precision pwidth_d(%3d,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 974 lines.append("integer pow_d(%3d,-max_branch_used:-1,lmaxconfigs_used)" % nfksconfs) 975 976 writer.writelines(lines)
977 978
979 - def write_configs_and_props_info_file(self, filename, matrix_element):
980 """writes the configs_and_props_info.inc file that cointains 981 all the (real-emission) configurations (IFOREST) as well as 982 the masses and widths of intermediate particles""" 983 lines = [] 984 lines.append("# C -> MAPCONFIG_D") 985 lines.append("# F/D -> IFOREST_D") 986 lines.append("# S -> SPROP_D") 987 lines.append("# T -> TPRID_D") 988 lines.append("# M -> PMASS_D/PWIDTH_D") 989 lines.append("# P -> POW_D") 990 lines2 = [] 991 nconfs = len(matrix_element.get_fks_info_list()) 992 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 993 994 max_iconfig=0 995 max_leg_number=0 996 997 for iFKS, conf in enumerate(matrix_element.get_fks_info_list()): 998 iFKS=iFKS+1 999 iconfig = 0 1000 s_and_t_channels = [] 1001 mapconfigs = [] 1002 fks_matrix_element=matrix_element.real_processes[conf['n_me'] - 1].matrix_element 1003 base_diagrams = fks_matrix_element.get('base_amplitude').get('diagrams') 1004 model = fks_matrix_element.get('base_amplitude').get('process').get('model') 1005 minvert = min([max([len(vert.get('legs')) for vert in \ 1006 diag.get('vertices')]) for diag in base_diagrams]) 1007 1008 lines.append("# ") 1009 lines.append("# nFKSprocess %d" % iFKS) 1010 for idiag, diag in enumerate(base_diagrams): 1011 if any([len(vert.get('legs')) > minvert for vert in 1012 diag.get('vertices')]): 1013 # Only 3-vertices allowed in configs.inc 1014 continue 1015 iconfig = iconfig + 1 1016 helas_diag = fks_matrix_element.get('diagrams')[idiag] 1017 mapconfigs.append(helas_diag.get('number')) 1018 lines.append("# Diagram %d for nFKSprocess %d" % \ 1019 (helas_diag.get('number'),iFKS)) 1020 # Correspondance between the config and the amplitudes 1021 lines.append("C %4d %4d %4d " % (iFKS,iconfig, 1022 helas_diag.get('number'))) 1023 1024 # Need to reorganize the topology so that we start with all 1025 # final state external particles and work our way inwards 1026 schannels, tchannels = helas_diag.get('amplitudes')[0].\ 1027 get_s_and_t_channels(ninitial, model, 990) 1028 1029 s_and_t_channels.append([schannels, tchannels]) 1030 1031 # Write out propagators for s-channel and t-channel vertices 1032 allchannels = schannels 1033 if len(tchannels) > 1: 1034 # Write out tchannels only if there are any non-trivial ones 1035 allchannels = schannels + tchannels 1036 1037 for vert in allchannels: 1038 daughters = [leg.get('number') for leg in vert.get('legs')[:-1]] 1039 last_leg = vert.get('legs')[-1] 1040 lines.append("F %4d %4d %4d %4d" % \ 1041 (iFKS,last_leg.get('number'), iconfig, len(daughters))) 1042 for d in daughters: 1043 lines.append("D %4d" % d) 1044 if vert in schannels: 1045 lines.append("S %4d %4d %4d %10d" % \ 1046 (iFKS,last_leg.get('number'), iconfig, 1047 last_leg.get('id'))) 1048 elif vert in tchannels[:-1]: 1049 lines.append("T %4d %4d %4d %10d" % \ 1050 (iFKS,last_leg.get('number'), iconfig, 1051 abs(last_leg.get('id')))) 1052 1053 # update what the array sizes (mapconfig,iforest,etc) will be 1054 max_leg_number = min(max_leg_number,last_leg.get('number')) 1055 max_iconfig = max(max_iconfig,iconfig) 1056 1057 # Write out number of configs 1058 lines.append("# Number of configs for nFKSprocess %d" % iFKS) 1059 lines.append("C %4d %4d %4d" % (iFKS,0,iconfig)) 1060 1061 # write the props.inc information 1062 lines2.append("# ") 1063 particle_dict = fks_matrix_element.get('processes')[0].get('model').\ 1064 get('particle_dict') 1065 1066 for iconf, configs in enumerate(s_and_t_channels): 1067 for vertex in configs[0] + configs[1][:-1]: 1068 leg = vertex.get('legs')[-1] 1069 if leg.get('id') not in particle_dict: 1070 # Fake propagator used in multiparticle vertices 1071 pow_part = 0 1072 else: 1073 particle = particle_dict[leg.get('id')] 1074 1075 pow_part = 1 + int(particle.is_boson()) 1076 1077 lines2.append("M %4d %4d %4d %10d " % \ 1078 (iFKS,leg.get('number'), iconf + 1, leg.get('id'))) 1079 lines2.append("P %4d %4d %4d %4d " % \ 1080 (iFKS,leg.get('number'), iconf + 1, pow_part)) 1081 1082 # Write the file 1083 open(filename,'w').write('\n'.join(lines+lines2)) 1084 1085 return max_iconfig, max_leg_number, nconfs
1086 1087
1088 - def write_leshouche_info_declarations(self, writer, nfksconfs, 1089 maxproc, maxflow, nexternal, fortran_model):
1090 """writes the declarations for the variables relevant for leshouche_info 1091 """ 1092 lines = [] 1093 lines.append('integer maxproc_used, maxflow_used') 1094 lines.append('parameter (maxproc_used = %d)' % maxproc) 1095 lines.append('parameter (maxflow_used = %d)' % maxflow) 1096 lines.append('integer idup_d(%d,%d,maxproc_used)' % (nfksconfs, nexternal)) 1097 lines.append('integer mothup_d(%d,%d,%d,maxproc_used)' % (nfksconfs, 2, nexternal)) 1098 lines.append('integer icolup_d(%d,%d,%d,maxflow_used)' % (nfksconfs, 2, nexternal)) 1099 lines.append('integer niprocs_d(%d)' % (nfksconfs)) 1100 1101 writer.writelines(lines)
1102 1103
1104 - def write_leshouche_info_file(self, filename, matrix_element):
1105 """writes the leshouche_info.inc file which contains 1106 the LHA informations for all the real emission processes 1107 """ 1108 lines = [] 1109 lines.append("# I -> IDUP_D") 1110 lines.append("# M -> MOTHUP_D") 1111 lines.append("# C -> ICOLUP_D") 1112 nfksconfs = len(matrix_element.get_fks_info_list()) 1113 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 1114 1115 maxproc = 0 1116 maxflow = 0 1117 for i, conf in enumerate(matrix_element.get_fks_info_list()): 1118 # for i, real in enumerate(matrix_element.real_processes): 1119 (newlines, nprocs, nflows) = self.get_leshouche_lines( 1120 matrix_element.real_processes[conf['n_me'] - 1].matrix_element, i + 1) 1121 lines.extend(newlines) 1122 maxproc = max(maxproc, nprocs) 1123 maxflow = max(maxflow, nflows) 1124 1125 # Write the file 1126 open(filename,'w').write('\n'.join(lines)) 1127 1128 return nfksconfs, maxproc, maxflow, nexternal
1129 1130
1131 - def write_pdf_wrapper(self, writer, matrix_element, fortran_model):
1132 """writes the wrapper which allows to chose among the different real matrix elements""" 1133 1134 file = \ 1135 """double precision function dlum() 1136 implicit none 1137 include 'timing_variables.inc' 1138 integer nfksprocess 1139 common/c_nfksprocess/nfksprocess 1140 call cpu_time(tbefore) 1141 """ 1142 if matrix_element.real_processes: 1143 for n, info in enumerate(matrix_element.get_fks_info_list()): 1144 file += \ 1145 """if (nfksprocess.eq.%(n)d) then 1146 call dlum_%(n_me)d(dlum) 1147 else""" % {'n': n + 1, 'n_me' : info['n_me']} 1148 file += \ 1149 """ 1150 write(*,*) 'ERROR: invalid n in dlum :', nfksprocess 1151 stop 1152 endif 1153 call cpu_time(tAfter) 1154 tPDF = tPDF + (tAfter-tBefore) 1155 return 1156 end 1157 """ 1158 else: 1159 file+= \ 1160 """call dlum_0(dlum) 1161 call cpu_time(tAfter) 1162 tPDF = tPDF + (tAfter-tBefore) 1163 return 1164 end 1165 """ 1166 1167 # Write the file 1168 writer.writelines(file) 1169 return 0
1170 1171
1172 - def write_real_me_wrapper(self, writer, matrix_element, fortran_model):
1173 """writes the wrapper which allows to chose among the different real matrix elements""" 1174 1175 file = \ 1176 """subroutine smatrix_real(p, wgt) 1177 implicit none 1178 include 'nexternal.inc' 1179 double precision p(0:3, nexternal) 1180 double precision wgt 1181 integer nfksprocess 1182 common/c_nfksprocess/nfksprocess 1183 """ 1184 for n, info in enumerate(matrix_element.get_fks_info_list()): 1185 file += \ 1186 """if (nfksprocess.eq.%(n)d) then 1187 call smatrix_%(n_me)d(p, wgt) 1188 else""" % {'n': n + 1, 'n_me' : info['n_me']} 1189 1190 if matrix_element.real_processes: 1191 file += \ 1192 """ 1193 write(*,*) 'ERROR: invalid n in real_matrix :', nfksprocess 1194 stop 1195 endif 1196 return 1197 end 1198 """ 1199 else: 1200 file += \ 1201 """ 1202 wgt=0d0 1203 return 1204 end 1205 """ 1206 # Write the file 1207 writer.writelines(file) 1208 return 0
1209 1210
1211 - def draw_feynman_diagrams(self, matrix_element):
1212 """Create the ps files containing the feynman diagrams for the born process, 1213 as well as for all the real emission processes""" 1214 1215 filename = 'born.ps' 1216 plot = draw.MultiEpsDiagramDrawer(matrix_element.born_matrix_element.\ 1217 get('base_amplitude').get('diagrams'), 1218 filename, 1219 model=matrix_element.born_matrix_element.\ 1220 get('processes')[0].get('model'), 1221 amplitude=True, diagram_type='born') 1222 plot.draw() 1223 1224 for n, fksreal in enumerate(matrix_element.real_processes): 1225 filename = 'matrix_%d.ps' % (n + 1) 1226 plot = draw.MultiEpsDiagramDrawer(fksreal.matrix_element.\ 1227 get('base_amplitude').get('diagrams'), 1228 filename, 1229 model=fksreal.matrix_element.\ 1230 get('processes')[0].get('model'), 1231 amplitude=True, diagram_type='real') 1232 plot.draw()
1233 1234
1235 - def write_real_matrix_elements(self, matrix_element, fortran_model):
1236 """writes the matrix_i.f files which contain the real matrix elements""" 1237 1238 1239 1240 for n, fksreal in enumerate(matrix_element.real_processes): 1241 filename = 'matrix_%d.f' % (n + 1) 1242 self.write_matrix_element_fks(writers.FortranWriter(filename), 1243 fksreal.matrix_element, n + 1, 1244 fortran_model)
1245
1246 - def write_pdf_calls(self, matrix_element, fortran_model):
1247 """writes the parton_lum_i.f files which contain the real matrix elements. 1248 If no real emission existst, write the one for the born""" 1249 1250 if matrix_element.real_processes: 1251 for n, fksreal in enumerate(matrix_element.real_processes): 1252 filename = 'parton_lum_%d.f' % (n + 1) 1253 self.write_pdf_file(writers.FortranWriter(filename), 1254 fksreal.matrix_element, n + 1, 1255 fortran_model) 1256 else: 1257 filename = 'parton_lum_0.f' 1258 self.write_pdf_file(writers.FortranWriter(filename), 1259 matrix_element.born_matrix_element, 0, 1260 fortran_model)
1261 1262
1263 - def generate_born_fks_files(self, matrix_element, fortran_model, me_number, path):
1264 """generates the files needed for the born amplitude in the P* directory, which will 1265 be needed by the P* directories""" 1266 pathdir = os.getcwd() 1267 1268 filename = 'born.f' 1269 calls_born, ncolor_born = \ 1270 self.write_born_fks(writers.FortranWriter(filename),\ 1271 matrix_element, 1272 fortran_model) 1273 1274 filename = 'born_hel.f' 1275 self.write_born_hel(writers.FortranWriter(filename),\ 1276 matrix_element, 1277 fortran_model) 1278 1279 1280 filename = 'born_conf.inc' 1281 nconfigs, mapconfigs, s_and_t_channels = \ 1282 self.write_configs_file( 1283 writers.FortranWriter(filename), 1284 matrix_element.born_matrix_element, 1285 fortran_model) 1286 1287 filename = 'born_props.inc' 1288 self.write_props_file(writers.FortranWriter(filename), 1289 matrix_element.born_matrix_element, 1290 fortran_model, 1291 s_and_t_channels) 1292 1293 filename = 'born_decayBW.inc' 1294 self.write_decayBW_file(writers.FortranWriter(filename), 1295 s_and_t_channels) 1296 1297 filename = 'born_leshouche.inc' 1298 nflows = self.write_leshouche_file(writers.FortranWriter(filename), 1299 matrix_element.born_matrix_element, 1300 fortran_model) 1301 1302 filename = 'born_nhel.inc' 1303 self.write_born_nhel_file(writers.FortranWriter(filename), 1304 matrix_element.born_matrix_element, nflows, 1305 fortran_model, 1306 ncolor_born) 1307 1308 filename = 'born_ngraphs.inc' 1309 self.write_ngraphs_file(writers.FortranWriter(filename), 1310 matrix_element.born_matrix_element.get_number_of_amplitudes()) 1311 1312 filename = 'ncombs.inc' 1313 self.write_ncombs_file(writers.FortranWriter(filename), 1314 matrix_element.born_matrix_element, 1315 fortran_model) 1316 1317 filename = 'born_maxamps.inc' 1318 maxamps = len(matrix_element.get('diagrams')) 1319 maxflows = ncolor_born 1320 self.write_maxamps_file(writers.FortranWriter(filename), 1321 maxamps, 1322 maxflows, 1323 max([len(matrix_element.get('processes')) for me in \ 1324 matrix_element.born_matrix_element]),1) 1325 1326 filename = 'config_subproc_map.inc' 1327 self.write_config_subproc_map_file(writers.FortranWriter(filename), 1328 s_and_t_channels) 1329 1330 filename = 'coloramps.inc' 1331 self.write_coloramps_file(writers.FortranWriter(filename), 1332 mapconfigs, 1333 matrix_element.born_matrix_element, 1334 fortran_model) 1335 1336 #write the sborn_sf.f and the b_sf_files 1337 filename = ['sborn_sf.f', 'sborn_sf_dum.f'] 1338 for i, links in enumerate([matrix_element.color_links, []]): 1339 self.write_sborn_sf(writers.FortranWriter(filename[i]), 1340 links, 1341 fortran_model) 1342 self.color_link_files = [] 1343 for i in range(len(matrix_element.color_links)): 1344 filename = 'b_sf_%3.3d.f' % (i + 1) 1345 self.color_link_files.append(filename) 1346 self.write_b_sf_fks(writers.FortranWriter(filename), 1347 matrix_element, i, 1348 fortran_model)
1349 1350
1351 - def generate_virtuals_from_OLP(self,process_list,export_path, OLP):
1352 """Generates the library for computing the loop matrix elements 1353 necessary for this process using the OLP specified.""" 1354 1355 # Start by writing the BLHA order file 1356 virtual_path = pjoin(export_path,'OLP_virtuals') 1357 if not os.path.exists(virtual_path): 1358 os.makedirs(virtual_path) 1359 filename = os.path.join(virtual_path,'OLE_order.lh') 1360 self.write_lh_order(filename, process_list, OLP) 1361 1362 fail_msg='Generation of the virtuals with %s failed.\n'%OLP+\ 1363 'Please check the virt_generation.log file in %s.'\ 1364 %str(pjoin(virtual_path,'virt_generation.log')) 1365 1366 # Perform some tasks specific to certain OLP's 1367 if OLP=='GoSam': 1368 cp(pjoin(self.mgme_dir,'Template','loop_material','OLP_specifics', 1369 'GoSam','makevirt'),pjoin(virtual_path,'makevirt')) 1370 cp(pjoin(self.mgme_dir,'Template','loop_material','OLP_specifics', 1371 'GoSam','gosam.rc'),pjoin(virtual_path,'gosam.rc')) 1372 ln(pjoin(export_path,'Cards','param_card.dat'),virtual_path) 1373 # Now generate the process 1374 logger.info('Generating the loop matrix elements with %s...'%OLP) 1375 virt_generation_log = \ 1376 open(pjoin(virtual_path,'virt_generation.log'), 'w') 1377 retcode = subprocess.call(['./makevirt'],cwd=virtual_path, 1378 stdout=virt_generation_log, stderr=virt_generation_log) 1379 virt_generation_log.close() 1380 # Check what extension is used for the share libraries on this system 1381 possible_other_extensions = ['so','dylib'] 1382 shared_lib_ext='so' 1383 for ext in possible_other_extensions: 1384 if os.path.isfile(pjoin(virtual_path,'Virtuals','lib', 1385 'libgolem_olp.'+ext)): 1386 shared_lib_ext = ext 1387 1388 # Now check that everything got correctly generated 1389 files_to_check = ['olp_module.mod',str(pjoin('lib', 1390 'libgolem_olp.'+shared_lib_ext))] 1391 if retcode != 0 or any([not os.path.exists(pjoin(virtual_path, 1392 'Virtuals',f)) for f in files_to_check]): 1393 raise fks_common.FKSProcessError(fail_msg) 1394 # link the library to the lib folder 1395 ln(pjoin(virtual_path,'Virtuals','lib','libgolem_olp.'+shared_lib_ext), 1396 pjoin(export_path,'lib')) 1397 1398 # Specify in make_opts the right library necessitated by the OLP 1399 make_opts_content=open(pjoin(export_path,'Source','make_opts')).read() 1400 make_opts=open(pjoin(export_path,'Source','make_opts'),'w') 1401 if OLP=='GoSam': 1402 if platform.system().lower()=='darwin': 1403 # On mac the -rpath is not supported and the path of the dynamic 1404 # library is automatically wired in the executable 1405 make_opts_content=make_opts_content.replace('libOLP=', 1406 'libOLP=-Wl,-lgolem_olp') 1407 else: 1408 # On other platforms the option , -rpath= path to libgolem.so is necessary 1409 # Using a relative path is not ideal because the file libgolem.so is not 1410 # copied on the worker nodes. 1411 # make_opts_content=make_opts_content.replace('libOLP=', 1412 # 'libOLP=-Wl,-rpath=../$(LIBDIR) -lgolem_olp') 1413 # Using the absolute path is working in the case where the disk of the 1414 # front end machine is mounted on all worker nodes as well. 1415 make_opts_content=make_opts_content.replace('libOLP=', 1416 'libOLP=-Wl,-rpath='+str(pjoin(export_path,'lib'))+' -lgolem_olp') 1417 1418 1419 make_opts.write(make_opts_content) 1420 make_opts.close() 1421 1422 # A priori this is generic to all OLP's 1423 1424 # Parse the contract file returned and propagate the process label to 1425 # the include of the BinothLHA.f file 1426 proc_to_label = self.parse_contract_file( 1427 pjoin(virtual_path,'OLE_order.olc')) 1428 1429 self.write_BinothLHA_inc(process_list,proc_to_label,\ 1430 pjoin(export_path,'SubProcesses')) 1431 1432 # Link the contract file to within the SubProcess directory 1433 ln(pjoin(virtual_path,'OLE_order.olc'),pjoin(export_path,'SubProcesses'))
1434
1435 - def write_BinothLHA_inc(self, processes, proc_to_label, SubProcPath):
1436 """ Write the file Binoth_proc.inc in each SubProcess directory so as 1437 to provide the right process_label to use in the OLP call to get the 1438 loop matrix element evaluation. The proc_to_label is the dictionary of 1439 the format of the one returned by the function parse_contract_file.""" 1440 1441 for proc in processes: 1442 name = "P%s"%proc.shell_string() 1443 proc_pdgs=(tuple([leg.get('id') for leg in proc.get('legs') if \ 1444 not leg.get('state')]), 1445 tuple([leg.get('id') for leg in proc.get('legs') if \ 1446 leg.get('state')])) 1447 incFile = open(pjoin(SubProcPath, name,'Binoth_proc.inc'),'w') 1448 try: 1449 incFile.write( 1450 """ INTEGER PROC_LABEL 1451 PARAMETER (PROC_LABEL=%d)"""%(proc_to_label[proc_pdgs])) 1452 except KeyError: 1453 raise fks_common.FKSProcessError('Could not found the target'+\ 1454 ' process %s > %s in '%(str(proc_pdgs[0]),str(proc_pdgs[1]))+\ 1455 ' the proc_to_label argument in write_BinothLHA_inc.') 1456 incFile.close()
1457
1458 - def parse_contract_file(self, contract_file_path):
1459 """ Parses the BLHA contract file, make sure all parameters could be 1460 understood by the OLP and return a mapping of the processes (characterized 1461 by the pdg's of the initial and final state particles) to their process 1462 label. The format of the mapping is {((in_pdgs),(out_pdgs)):proc_label}. 1463 """ 1464 1465 proc_def_to_label = {} 1466 1467 if not os.path.exists(contract_file_path): 1468 raise fks_common.FKSProcessError('Could not find the contract file'+\ 1469 ' OLE_order.olc in %s.'%str(contract_file_path)) 1470 1471 comment_re=re.compile(r"^\s*#") 1472 proc_def_re=re.compile( 1473 r"^(?P<in_pdgs>(\s*-?\d+\s*)+)->(?P<out_pdgs>(\s*-?\d+\s*)+)\|"+ 1474 r"\s*(?P<proc_class>\d+)\s*(?P<proc_label>\d+)\s*$") 1475 line_OK_re=re.compile(r"^.*\|\s*OK") 1476 for line in file(contract_file_path): 1477 # Ignore comments 1478 if not comment_re.match(line) is None: 1479 continue 1480 # Check if it is a proc definition line 1481 proc_def = proc_def_re.match(line) 1482 if not proc_def is None: 1483 if int(proc_def.group('proc_class'))!=1: 1484 raise fks_common.FKSProcessError( 1485 'aMCatNLO can only handle loop processes generated by the OLP which have only '+\ 1486 ' process class attribute. Found %s instead in: \n%s'\ 1487 %(proc_def.group('proc_class'),line)) 1488 in_pdgs=tuple([int(in_pdg) for in_pdg in \ 1489 proc_def.group('in_pdgs').split()]) 1490 out_pdgs=tuple([int(out_pdg) for out_pdg in \ 1491 proc_def.group('out_pdgs').split()]) 1492 proc_def_to_label[(in_pdgs,out_pdgs)]=\ 1493 int(proc_def.group('proc_label')) 1494 continue 1495 # For the other types of line, just make sure they end with | OK 1496 if line_OK_re.match(line) is None: 1497 raise fks_common.FKSProcessError( 1498 'The OLP could not process the following line: \n%s'%line) 1499 1500 return proc_def_to_label
1501 1502
1503 - def generate_virt_directory(self, loop_matrix_element, fortran_model, dir_name):
1504 """writes the V**** directory inside the P**** directories specified in 1505 dir_name""" 1506 1507 cwd = os.getcwd() 1508 1509 matrix_element = loop_matrix_element 1510 1511 # Create the MadLoop5_resources directory if not already existing 1512 dirpath = os.path.join(dir_name, 'MadLoop5_resources') 1513 try: 1514 os.mkdir(dirpath) 1515 except os.error as error: 1516 logger.warning(error.strerror + " " + dirpath) 1517 1518 # Create the directory PN_xx_xxxxx in the specified path 1519 name = "V%s" % matrix_element.get('processes')[0].shell_string() 1520 dirpath = os.path.join(dir_name, name) 1521 1522 try: 1523 os.mkdir(dirpath) 1524 except os.error as error: 1525 logger.warning(error.strerror + " " + dirpath) 1526 1527 try: 1528 os.chdir(dirpath) 1529 except os.error: 1530 logger.error('Could not cd to directory %s' % dirpath) 1531 return 0 1532 1533 logger.info('Creating files in directory %s' % name) 1534 1535 # Extract number of external particles 1536 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 1537 1538 calls=self.write_loop_matrix_element_v4(None,matrix_element,fortran_model) 1539 # The born matrix element, if needed 1540 filename = 'born_matrix.f' 1541 calls = self.write_bornmatrix( 1542 writers.FortranWriter(filename), 1543 matrix_element, 1544 fortran_model) 1545 1546 filename = 'nexternal.inc' 1547 self.write_nexternal_file(writers.FortranWriter(filename), 1548 nexternal, ninitial) 1549 1550 filename = 'pmass.inc' 1551 self.write_pmass_file(writers.FortranWriter(filename), 1552 matrix_element) 1553 1554 filename = 'ngraphs.inc' 1555 self.write_ngraphs_file(writers.FortranWriter(filename), 1556 len(matrix_element.get_all_amplitudes())) 1557 1558 filename = "loop_matrix.ps" 1559 plot = draw.MultiEpsDiagramDrawer(base_objects.DiagramList( 1560 matrix_element.get('base_amplitude').get('loop_diagrams')[:1000]), 1561 filename, 1562 model=matrix_element.get('processes')[0].get('model'), 1563 amplitude='') 1564 logger.info("Drawing loop Feynman diagrams for " + \ 1565 matrix_element.get('processes')[0].nice_string(print_weighted=False)) 1566 plot.draw() 1567 1568 filename = "born_matrix.ps" 1569 plot = draw.MultiEpsDiagramDrawer(matrix_element.get('base_amplitude').\ 1570 get('born_diagrams'),filename,model=matrix_element.get('processes')[0].\ 1571 get('model'),amplitude='') 1572 logger.info("Generating born Feynman diagrams for " + \ 1573 matrix_element.get('processes')[0].nice_string(print_weighted=False)) 1574 plot.draw() 1575 1576 linkfiles = ['coupl.inc', 'mp_coupl.inc', 'mp_coupl_same_name.inc', 1577 'cts_mprec.h', 'cts_mpc.h', 'MadLoopParamReader.f', 1578 'MadLoopCommons.f','MadLoopParams.inc'] 1579 1580 # We should move to MadLoop5_resources directory from the SubProcesses 1581 1582 ln(pjoin(os.path.pardir,os.path.pardir,'MadLoopParams.dat'), 1583 pjoin('..','MadLoop5_resources')) 1584 1585 for file in linkfiles: 1586 ln('../../%s' % file) 1587 1588 os.system("ln -s ../../makefile_loop makefile") 1589 1590 linkfiles = ['mpmodule.mod'] 1591 1592 for file in linkfiles: 1593 ln('../../../lib/%s' % file) 1594 1595 linkfiles = ['coef_specs.inc'] 1596 1597 for file in linkfiles: 1598 ln('../../../Source/DHELAS/%s' % file) 1599 1600 # Return to original PWD 1601 os.chdir(cwd) 1602 1603 if not calls: 1604 calls = 0 1605 return calls
1606
1607 - def get_qed_qcd_orders_from_weighted(self, nexternal, weighted):
1608 """computes the QED/QCD orders from the knowledge of the n of ext particles 1609 and of the weighted orders""" 1610 # n vertices = nexternal - 2 =QED + QCD 1611 # weighted = 2*QED + QCD 1612 QED = weighted - nexternal + 2 1613 QCD = weighted - 2 * QED 1614 return QED, QCD
1615 1616 1617 1618 #=============================================================================== 1619 # write_lh_order 1620 #=============================================================================== 1621 #test written
1622 - def write_lh_order(self, filename, process_list, OLP='MadLoop'):
1623 """Creates the OLE_order.lh file. This function should be edited according 1624 to the OLP which is used. For now it is generic.""" 1625 1626 1627 if len(process_list)==0: 1628 raise fks_common.FKSProcessError('No matrix elements provided to '+\ 1629 'the function write_lh_order.') 1630 return 1631 1632 # We assume the orders to be common to all Subprocesses 1633 1634 orders = process_list[0].get('orders') 1635 if 'QED' in orders.keys() and 'QCD' in orders.keys(): 1636 QED=orders['QED'] 1637 QCD=orders['QCD'] 1638 elif 'QED' in orders.keys(): 1639 QED=orders['QED'] 1640 QCD=0 1641 elif 'QCD' in orders.keys(): 1642 QED=0 1643 QCD=orders['QCD'] 1644 else: 1645 QED, QCD = self.get_qed_qcd_orders_from_weighted(\ 1646 len(process_list[0].get('legs')), 1647 orders['WEIGHTED']) 1648 1649 replace_dict = {} 1650 replace_dict['mesq'] = 'CHaveraged' 1651 replace_dict['corr'] = ' '.join(process_list[0].\ 1652 get('perturbation_couplings')) 1653 replace_dict['irreg'] = 'CDR' 1654 replace_dict['aspow'] = QCD 1655 replace_dict['aepow'] = QED 1656 replace_dict['modelfile'] = './param_card.dat' 1657 replace_dict['params'] = 'alpha_s' 1658 proc_lines=[] 1659 for proc in process_list: 1660 proc_lines.append('%s -> %s' % \ 1661 (' '.join(str(l['id']) for l in proc['legs'] if not l['state']), 1662 ' '.join(str(l['id']) for l in proc['legs'] if l['state']))) 1663 replace_dict['pdgs'] = '\n'.join(proc_lines) 1664 replace_dict['symfin'] = 'Yes' 1665 content = \ 1666 "#OLE_order written by MadGraph5_aMC@NLO\n\ 1667 \n\ 1668 MatrixElementSquareType %(mesq)s\n\ 1669 CorrectionType %(corr)s\n\ 1670 IRregularisation %(irreg)s\n\ 1671 AlphasPower %(aspow)d\n\ 1672 AlphaPower %(aepow)d\n\ 1673 NJetSymmetrizeFinal %(symfin)s\n\ 1674 ModelFile %(modelfile)s\n\ 1675 Parameters %(params)s\n\ 1676 \n\ 1677 # process\n\ 1678 %(pdgs)s\n\ 1679 " % replace_dict 1680 1681 file = open(filename, 'w') 1682 file.write(content) 1683 file.close 1684 return
1685 1686 1687 #=============================================================================== 1688 # write_born_fks 1689 #=============================================================================== 1690 # test written
1691 - def write_born_fks(self, writer, fksborn, fortran_model):
1692 """Export a matrix element to a born.f file in MadFKS format""" 1693 1694 matrix_element = fksborn.born_matrix_element 1695 1696 if not matrix_element.get('processes') or \ 1697 not matrix_element.get('diagrams'): 1698 return 0 1699 1700 if not isinstance(writer, writers.FortranWriter): 1701 raise writers.FortranWriter.FortranWriterError(\ 1702 "writer not FortranWriter") 1703 # Set lowercase/uppercase Fortran code 1704 writers.FortranWriter.downcase = False 1705 1706 replace_dict = {} 1707 1708 # Extract version number and date from VERSION file 1709 info_lines = self.get_mg5_info_lines() 1710 replace_dict['info_lines'] = info_lines 1711 1712 # Extract process info lines 1713 process_lines = self.get_process_info_lines(matrix_element) 1714 replace_dict['process_lines'] = process_lines 1715 1716 1717 # Extract ncomb 1718 ncomb = matrix_element.get_helicity_combinations() 1719 replace_dict['ncomb'] = ncomb 1720 1721 # Extract helicity lines 1722 helicity_lines = self.get_helicity_lines(matrix_element) 1723 replace_dict['helicity_lines'] = helicity_lines 1724 1725 # Extract IC line 1726 ic_line = self.get_ic_line(matrix_element) 1727 replace_dict['ic_line'] = ic_line 1728 1729 # Extract overall denominator 1730 # Averaging initial state color, spin, and identical FS particles 1731 #den_factor_line = get_den_factor_line(matrix_element) 1732 1733 # Extract ngraphs 1734 ngraphs = matrix_element.get_number_of_amplitudes() 1735 replace_dict['ngraphs'] = ngraphs 1736 1737 # Extract nwavefuncs 1738 nwavefuncs = matrix_element.get_number_of_wavefunctions() 1739 replace_dict['nwavefuncs'] = nwavefuncs 1740 1741 # Extract ncolor 1742 ncolor = max(1, len(matrix_element.get('color_basis'))) 1743 replace_dict['ncolor'] = ncolor 1744 1745 # Extract color data lines 1746 color_data_lines = self.get_color_data_lines(matrix_element) 1747 replace_dict['color_data_lines'] = "\n".join(color_data_lines) 1748 1749 # Extract helas calls 1750 helas_calls = fortran_model.get_matrix_element_calls(\ 1751 matrix_element) 1752 replace_dict['helas_calls'] = "\n".join(helas_calls) 1753 1754 # Extract amp2 lines 1755 amp2_lines = self.get_amp2_lines(matrix_element) 1756 replace_dict['amp2_lines'] = '\n'.join(amp2_lines) 1757 1758 # Extract JAMP lines 1759 jamp_lines = self.get_JAMP_lines(matrix_element) 1760 replace_dict['jamp_lines'] = '\n'.join(jamp_lines) 1761 1762 # Set the size of Wavefunction 1763 if not self.model or any([p.get('spin') in [4,5] for p in self.model.get('particles') if p]): 1764 replace_dict['wavefunctionsize'] = 20 1765 else: 1766 replace_dict['wavefunctionsize'] = 8 1767 1768 # Extract glu_ij_lines 1769 ij_lines = self.get_ij_lines(fksborn) 1770 replace_dict['ij_lines'] = '\n'.join(ij_lines) 1771 1772 # Extract den_factor_lines 1773 den_factor_lines = self.get_den_factor_lines(fksborn) 1774 replace_dict['den_factor_lines'] = '\n'.join(den_factor_lines) 1775 1776 # Extract the number of FKS process 1777 replace_dict['nconfs'] = max(len(fksborn.get_fks_info_list()),1) 1778 1779 file = open(os.path.join(_file_path, \ 1780 'iolibs/template_files/born_fks.inc')).read() 1781 file = file % replace_dict 1782 1783 # Write the file 1784 writer.writelines(file) 1785 1786 return len(filter(lambda call: call.find('#') != 0, helas_calls)), ncolor
1787 1788
1789 - def write_born_hel(self, writer, fksborn, fortran_model):
1790 """Export a matrix element to a born_hel.f file in MadFKS format""" 1791 1792 matrix_element = fksborn.born_matrix_element 1793 1794 if not matrix_element.get('processes') or \ 1795 not matrix_element.get('diagrams'): 1796 return 0 1797 1798 if not isinstance(writer, writers.FortranWriter): 1799 raise writers.FortranWriter.FortranWriterError(\ 1800 "writer not FortranWriter") 1801 # Set lowercase/uppercase Fortran code 1802 writers.FortranWriter.downcase = False 1803 1804 replace_dict = {} 1805 1806 # Extract version number and date from VERSION file 1807 info_lines = self.get_mg5_info_lines() 1808 replace_dict['info_lines'] = info_lines 1809 1810 # Extract process info lines 1811 process_lines = self.get_process_info_lines(matrix_element) 1812 replace_dict['process_lines'] = process_lines 1813 1814 1815 # Extract ncomb 1816 ncomb = matrix_element.get_helicity_combinations() 1817 replace_dict['ncomb'] = ncomb 1818 1819 # Extract helicity lines 1820 helicity_lines = self.get_helicity_lines(matrix_element) 1821 replace_dict['helicity_lines'] = helicity_lines 1822 1823 # Extract IC line 1824 ic_line = self.get_ic_line(matrix_element) 1825 replace_dict['ic_line'] = ic_line 1826 1827 # Extract overall denominator 1828 # Averaging initial state color, spin, and identical FS particles 1829 #den_factor_line = get_den_factor_line(matrix_element) 1830 1831 # Extract ngraphs 1832 ngraphs = matrix_element.get_number_of_amplitudes() 1833 replace_dict['ngraphs'] = ngraphs 1834 1835 # Extract nwavefuncs 1836 nwavefuncs = matrix_element.get_number_of_wavefunctions() 1837 replace_dict['nwavefuncs'] = nwavefuncs 1838 1839 # Extract ncolor 1840 ncolor = max(1, len(matrix_element.get('color_basis'))) 1841 replace_dict['ncolor'] = ncolor 1842 1843 # Extract color data lines 1844 color_data_lines = self.get_color_data_lines(matrix_element) 1845 replace_dict['color_data_lines'] = "\n".join(color_data_lines) 1846 1847 # Extract amp2 lines 1848 amp2_lines = self.get_amp2_lines(matrix_element) 1849 replace_dict['amp2_lines'] = '\n'.join(amp2_lines) 1850 1851 # Extract JAMP lines 1852 jamp_lines = self.get_JAMP_lines(matrix_element) 1853 replace_dict['jamp_lines'] = '\n'.join(jamp_lines) 1854 1855 # Extract den_factor_lines 1856 den_factor_lines = self.get_den_factor_lines(fksborn) 1857 replace_dict['den_factor_lines'] = '\n'.join(den_factor_lines) 1858 1859 # Extract the number of FKS process 1860 replace_dict['nconfs'] = len(fksborn.get_fks_info_list()) 1861 1862 file = open(os.path.join(_file_path, \ 1863 'iolibs/template_files/born_fks_hel.inc')).read() 1864 file = file % replace_dict 1865 1866 # Write the file 1867 writer.writelines(file) 1868 1869 return
1870 1871 1872 #=============================================================================== 1873 # write_born_sf_fks 1874 #=============================================================================== 1875 #test written
1876 - def write_sborn_sf(self, writer, color_links, fortran_model):
1877 """Creates the sborn_sf.f file, containing the calls to the different 1878 color linked borns""" 1879 1880 replace_dict = {} 1881 nborns = len(color_links) 1882 ifkss = [] 1883 iborns = [] 1884 mms = [] 1885 nns = [] 1886 iflines = "\n" 1887 1888 #header for the sborn_sf.f file 1889 file = """subroutine sborn_sf(p_born,m,n,wgt) 1890 implicit none 1891 include "nexternal.inc" 1892 double precision p_born(0:3,nexternal-1),wgt 1893 double complex wgt1(2) 1894 integer m,n \n""" 1895 1896 if nborns > 0: 1897 1898 for i, c_link in enumerate(color_links): 1899 iborn = i+1 1900 1901 iff = {True : 'if', False : 'elseif'}[i==0] 1902 1903 m, n = c_link['link'] 1904 1905 if m != n: 1906 iflines += \ 1907 "c b_sf_%(iborn)3.3d links partons %(m)d and %(n)d \n\ 1908 %(iff)s ((m.eq.%(m)d .and. n.eq.%(n)d).or.(m.eq.%(n)d .and. n.eq.%(m)d)) then \n\ 1909 call sb_sf_%(iborn)3.3d(p_born,wgt)\n\n" \ 1910 %{'m':m, 'n': n, 'iff': iff, 'iborn': iborn} 1911 else: 1912 iflines += \ 1913 "c b_sf_%(iborn)3.3d links partons %(m)d and %(n)d \n\ 1914 %(iff)s (m.eq.%(m)d .and. n.eq.%(n)d) then \n\ 1915 call sb_sf_%(iborn)3.3d(p_born,wgt)\n\n" \ 1916 %{'m':m, 'n': n, 'iff': iff, 'iborn': iborn} 1917 1918 1919 file += iflines + \ 1920 """else 1921 wgt = 0d0 1922 endif 1923 1924 return 1925 end""" 1926 elif nborns == 0: 1927 #write a dummy file 1928 file+=""" 1929 c This is a dummy function because 1930 c this subdir has no soft singularities 1931 wgt = 0d0 1932 1933 return 1934 end""" 1935 # Write the end of the file 1936 1937 writer.writelines(file)
1938 1939 1940 #=============================================================================== 1941 # write_b_sf_fks 1942 #=============================================================================== 1943 #test written
1944 - def write_b_sf_fks(self, writer, fksborn, i, fortran_model):
1945 """Create the b_sf_xxx.f file for the soft linked born in MadFKS format""" 1946 1947 matrix_element = copy.copy(fksborn.born_matrix_element) 1948 1949 if not matrix_element.get('processes') or \ 1950 not matrix_element.get('diagrams'): 1951 return 0 1952 1953 if not isinstance(writer, writers.FortranWriter): 1954 raise writers.FortranWriter.FortranWriterError(\ 1955 "writer not FortranWriter") 1956 # Set lowercase/uppercase Fortran code 1957 writers.FortranWriter.downcase = False 1958 1959 iborn = i + 1 1960 link = fksborn.color_links[i] 1961 1962 replace_dict = {} 1963 1964 replace_dict['iborn'] = iborn 1965 1966 # Extract version number and date from VERSION file 1967 info_lines = self.get_mg5_info_lines() 1968 replace_dict['info_lines'] = info_lines 1969 1970 # Extract process info lines 1971 process_lines = self.get_process_info_lines(matrix_element) 1972 replace_dict['process_lines'] = process_lines + \ 1973 "\nc spectators: %d %d \n" % tuple(link['link']) 1974 1975 # Extract ncomb 1976 ncomb = matrix_element.get_helicity_combinations() 1977 replace_dict['ncomb'] = ncomb 1978 1979 # Extract helicity lines 1980 helicity_lines = self.get_helicity_lines(matrix_element) 1981 replace_dict['helicity_lines'] = helicity_lines 1982 1983 # Extract IC line 1984 ic_line = self.get_ic_line(matrix_element) 1985 replace_dict['ic_line'] = ic_line 1986 1987 # Extract den_factor_lines 1988 den_factor_lines = self.get_den_factor_lines(fksborn) 1989 replace_dict['den_factor_lines'] = '\n'.join(den_factor_lines) 1990 1991 # Extract ngraphs 1992 ngraphs = matrix_element.get_number_of_amplitudes() 1993 replace_dict['ngraphs'] = ngraphs 1994 1995 # Extract nwavefuncs 1996 nwavefuncs = matrix_element.get_number_of_wavefunctions() 1997 replace_dict['nwavefuncs'] = nwavefuncs 1998 1999 # Extract ncolor 2000 ncolor1 = max(1, len(link['orig_basis'])) 2001 replace_dict['ncolor1'] = ncolor1 2002 ncolor2 = max(1, len(link['link_basis'])) 2003 replace_dict['ncolor2'] = ncolor2 2004 2005 # Extract color data lines 2006 color_data_lines = self.get_color_data_lines_from_color_matrix(\ 2007 link['link_matrix']) 2008 replace_dict['color_data_lines'] = "\n".join(color_data_lines) 2009 2010 # Extract amp2 lines 2011 amp2_lines = self.get_amp2_lines(matrix_element) 2012 replace_dict['amp2_lines'] = '\n'.join(amp2_lines) 2013 2014 # Extract JAMP lines 2015 jamp_lines = self.get_JAMP_lines(matrix_element) 2016 new_jamp_lines = [] 2017 for line in jamp_lines: 2018 line = string.replace(line, 'JAMP', 'JAMP1') 2019 new_jamp_lines.append(line) 2020 replace_dict['jamp1_lines'] = '\n'.join(new_jamp_lines) 2021 2022 matrix_element.set('color_basis', link['link_basis'] ) 2023 jamp_lines = self.get_JAMP_lines(matrix_element) 2024 new_jamp_lines = [] 2025 for line in jamp_lines: 2026 line = string.replace(line, 'JAMP', 'JAMP2') 2027 new_jamp_lines.append(line) 2028 replace_dict['jamp2_lines'] = '\n'.join(new_jamp_lines) 2029 2030 2031 # Extract the number of FKS process 2032 replace_dict['nconfs'] = len(fksborn.get_fks_info_list()) 2033 2034 file = open(os.path.join(_file_path, \ 2035 'iolibs/template_files/b_sf_xxx_fks.inc')).read() 2036 file = file % replace_dict 2037 2038 # Write the file 2039 writer.writelines(file) 2040 2041 return 0 , ncolor1
2042 2043 2044 #=============================================================================== 2045 # write_born_nhel_file 2046 #=============================================================================== 2047 #test written
2048 - def write_born_nhel_file(self, writer, matrix_element, nflows, fortran_model, ncolor):
2049 """Write the born_nhel.inc file for MG4.""" 2050 2051 ncomb = matrix_element.get_helicity_combinations() 2052 file = " integer max_bhel, max_bcol \n" 2053 file = file + "parameter (max_bhel=%d)\nparameter(max_bcol=%d)" % \ 2054 (ncomb, nflows) 2055 2056 # Write the file 2057 writer.writelines(file) 2058 2059 return True
2060 2061 #=============================================================================== 2062 # write_fks_info_file 2063 #===============================================================================
2064 - def write_nfksconfigs_file(self, writer, fksborn, fortran_model):
2065 """Writes the content of nFKSconfigs.inc, which just gives the 2066 total FKS dirs as a parameter. 2067 nFKSconfigs is always >=1 (use a fake configuration for LOonly)""" 2068 replace_dict = {} 2069 replace_dict['nconfs'] = max(len(fksborn.get_fks_info_list()), 1) 2070 content = \ 2071 """ INTEGER FKS_CONFIGS 2072 PARAMETER (FKS_CONFIGS=%(nconfs)d) 2073 2074 """ % replace_dict 2075 2076 writer.writelines(content)
2077 2078 2079 #=============================================================================== 2080 # write_fks_info_file 2081 #===============================================================================
2082 - def write_fks_info_file(self, writer, fksborn, fortran_model): #test_written
2083 """Writes the content of fks_info.inc, which lists the informations on the 2084 possible splittings of the born ME. 2085 nconfs is always >=1 (use a fake configuration for LOonly). 2086 The fake configuration use an 'antigluon' (id -21, color=8) as i_fks and 2087 the last colored particle as j_fks.""" 2088 2089 replace_dict = {} 2090 fks_info_list = fksborn.get_fks_info_list() 2091 replace_dict['nconfs'] = max(len(fks_info_list), 1) 2092 2093 # this is for processes with 'real' or 'all' as NLO mode 2094 if len(fks_info_list) > 0: 2095 fks_i_values = ', '.join(['%d' % info['fks_info']['i'] \ 2096 for info in fks_info_list]) 2097 fks_j_values = ', '.join(['%d' % info['fks_info']['j'] \ 2098 for info in fks_info_list]) 2099 2100 col_lines = [] 2101 pdg_lines = [] 2102 charge_lines = [] 2103 fks_j_from_i_lines = [] 2104 for i, info in enumerate(fks_info_list): 2105 col_lines.append( \ 2106 'DATA (PARTICLE_TYPE_D(%d, IPOS), IPOS=1, NEXTERNAL) / %s /' \ 2107 % (i + 1, ', '.join('%d' % col for col in fksborn.real_processes[info['n_me']-1].colors) )) 2108 pdg_lines.append( \ 2109 'DATA (PDG_TYPE_D(%d, IPOS), IPOS=1, NEXTERNAL) / %s /' \ 2110 % (i + 1, ', '.join('%d' % pdg for pdg in info['pdgs']))) 2111 charge_lines.append(\ 2112 'DATA (PARTICLE_CHARGE_D(%d, IPOS), IPOS=1, NEXTERNAL) / %s /'\ 2113 % (i + 1, ', '.join('%19.15fd0' % charg\ 2114 for charg in fksborn.real_processes[info['n_me']-1].charges) )) 2115 fks_j_from_i_lines.extend(self.get_fks_j_from_i_lines(fksborn.real_processes[info['n_me']-1],\ 2116 i + 1)) 2117 else: 2118 # this is for 'LOonly', generate a fake FKS configuration with 2119 # - i_fks = nexternal, pdg type = -21 and color =8 2120 # - j_fks = the last colored particle 2121 bornproc = fksborn.born_matrix_element.get('processes')[0] 2122 pdgs = [l.get('id') for l in bornproc.get('legs')] + [-21] 2123 colors = [l.get('color') for l in bornproc.get('legs')] + [8] 2124 charges = [0.] * len(colors) 2125 2126 fks_i = len(colors) 2127 # use the first colored particle if it exists, or 2128 # just the first 2129 fks_j=1 2130 for cpos, col in enumerate(colors[:-1]): 2131 if col != 1: 2132 fks_j = cpos+1 2133 2134 fks_i_values = str(fks_i) 2135 fks_j_values = str(fks_j) 2136 col_lines = ['DATA (PARTICLE_TYPE_D(1, IPOS), IPOS=1, NEXTERNAL) / %s /' \ 2137 % ', '.join([str(col) for col in colors])] 2138 pdg_lines = ['DATA (PDG_TYPE_D(1, IPOS), IPOS=1, NEXTERNAL) / %s /' \ 2139 % ', '.join([str(pdg) for pdg in pdgs])] 2140 charge_lines = ['DATA (PARTICLE_CHARGE_D(1, IPOS), IPOS=1, NEXTERNAL) / %s /' \ 2141 % ', '.join('%19.15fd0' % charg for charg in charges)] 2142 fks_j_from_i_lines = ['DATA (FKS_J_FROM_I_D(1, %d, JPOS), JPOS = 0, 1) / 1, %d /' \ 2143 % (fks_i, fks_j)] 2144 2145 2146 replace_dict['fks_i_line'] = "data fks_i_D / %s /" % fks_i_values 2147 replace_dict['fks_j_line'] = "data fks_j_D / %s /" % fks_j_values 2148 replace_dict['col_lines'] = '\n'.join(col_lines) 2149 replace_dict['pdg_lines'] = '\n'.join(pdg_lines) 2150 replace_dict['charge_lines'] = '\n'.join(charge_lines) 2151 replace_dict['fks_j_from_i_lines'] = '\n'.join(fks_j_from_i_lines) 2152 2153 content = \ 2154 """ INTEGER IPOS, JPOS 2155 INTEGER FKS_I_D(%(nconfs)d), FKS_J_D(%(nconfs)d) 2156 INTEGER FKS_J_FROM_I_D(%(nconfs)d, NEXTERNAL, 0:NEXTERNAL) 2157 INTEGER PARTICLE_TYPE_D(%(nconfs)d, NEXTERNAL), PDG_TYPE_D(%(nconfs)d, NEXTERNAL) 2158 REAL*8 PARTICLE_CHARGE_D(%(nconfs)d, NEXTERNAL) 2159 2160 %(fks_i_line)s 2161 %(fks_j_line)s 2162 2163 %(fks_j_from_i_lines)s 2164 2165 C 2166 C Particle type: 2167 C octet = 8, triplet = 3, singlet = 1 2168 %(col_lines)s 2169 2170 C 2171 C Particle type according to PDG: 2172 C 2173 %(pdg_lines)s 2174 2175 C 2176 C Particle charge: 2177 C charge is set 0. with QCD corrections, which is irrelevant 2178 %(charge_lines)s 2179 """ % replace_dict 2180 if not isinstance(writer, writers.FortranWriter): 2181 raise writers.FortranWriter.FortranWriterError(\ 2182 "writer not FortranWriter") 2183 # Set lowercase/uppercase Fortran code 2184 writers.FortranWriter.downcase = False 2185 2186 writer.writelines(content) 2187 2188 return True
2189 2190 2191 #=============================================================================== 2192 # write_matrix_element_fks 2193 #=============================================================================== 2194 #test written
2195 - def write_matrix_element_fks(self, writer, matrix_element, n, fortran_model):
2196 """Export a matrix element to a matrix.f file in MG4 madevent format""" 2197 2198 if not matrix_element.get('processes') or \ 2199 not matrix_element.get('diagrams'): 2200 return 0,0 2201 2202 if not isinstance(writer, writers.FortranWriter): 2203 raise writers.FortranWriter.FortranWriterError(\ 2204 "writer not FortranWriter") 2205 # Set lowercase/uppercase Fortran code 2206 writers.FortranWriter.downcase = False 2207 2208 replace_dict = {} 2209 replace_dict['N_me'] = n 2210 2211 # Extract version number and date from VERSION file 2212 info_lines = self.get_mg5_info_lines() 2213 replace_dict['info_lines'] = info_lines 2214 2215 # Extract process info lines 2216 process_lines = self.get_process_info_lines(matrix_element) 2217 replace_dict['process_lines'] = process_lines 2218 2219 # Extract ncomb 2220 ncomb = matrix_element.get_helicity_combinations() 2221 replace_dict['ncomb'] = ncomb 2222 2223 # Extract helicity lines 2224 helicity_lines = self.get_helicity_lines(matrix_element) 2225 replace_dict['helicity_lines'] = helicity_lines 2226 2227 # Extract IC line 2228 ic_line = self.get_ic_line(matrix_element) 2229 replace_dict['ic_line'] = ic_line 2230 2231 # Extract overall denominator 2232 # Averaging initial state color, spin, and identical FS particles 2233 den_factor_line = self.get_den_factor_line(matrix_element) 2234 replace_dict['den_factor_line'] = den_factor_line 2235 2236 # Extract ngraphs 2237 ngraphs = matrix_element.get_number_of_amplitudes() 2238 replace_dict['ngraphs'] = ngraphs 2239 2240 # Extract ncolor 2241 ncolor = max(1, len(matrix_element.get('color_basis'))) 2242 replace_dict['ncolor'] = ncolor 2243 2244 # Extract color data lines 2245 color_data_lines = self.get_color_data_lines(matrix_element) 2246 replace_dict['color_data_lines'] = "\n".join(color_data_lines) 2247 2248 # Extract helas calls 2249 helas_calls = fortran_model.get_matrix_element_calls(\ 2250 matrix_element) 2251 replace_dict['helas_calls'] = "\n".join(helas_calls) 2252 2253 # Extract nwavefuncs (important to place after get_matrix_element_calls 2254 # so that 'me_id' is set) 2255 nwavefuncs = matrix_element.get_number_of_wavefunctions() 2256 replace_dict['nwavefuncs'] = nwavefuncs 2257 2258 # Extract amp2 lines 2259 amp2_lines = self.get_amp2_lines(matrix_element) 2260 replace_dict['amp2_lines'] = '\n'.join(amp2_lines) 2261 2262 # Set the size of Wavefunction 2263 if not self.model or any([p.get('spin') in [4,5] for p in self.model.get('particles') if p]): 2264 replace_dict['wavefunctionsize'] = 20 2265 else: 2266 replace_dict['wavefunctionsize'] = 8 2267 2268 # Extract JAMP lines 2269 jamp_lines = self.get_JAMP_lines(matrix_element) 2270 2271 replace_dict['jamp_lines'] = '\n'.join(jamp_lines) 2272 2273 realfile = open(os.path.join(_file_path, \ 2274 'iolibs/template_files/realmatrix_fks.inc')).read() 2275 2276 realfile = realfile % replace_dict 2277 2278 # Write the file 2279 writer.writelines(realfile) 2280 2281 return len(filter(lambda call: call.find('#') != 0, helas_calls)), ncolor
2282 2283 2284 #=============================================================================== 2285 # write_pdf_file 2286 #===============================================================================
2287 - def write_pdf_file(self, writer, matrix_element, n, fortran_model):
2288 #test written 2289 """Write the auto_dsig.f file for MadFKS, which contains 2290 pdf call information""" 2291 2292 if not matrix_element.get('processes') or \ 2293 not matrix_element.get('diagrams'): 2294 return 0 2295 2296 nexternal, ninitial = matrix_element.get_nexternal_ninitial() 2297 2298 if ninitial < 1 or ninitial > 2: 2299 raise writers.FortranWriter.FortranWriterError, \ 2300 """Need ninitial = 1 or 2 to write auto_dsig file""" 2301 2302 replace_dict = {} 2303 2304 replace_dict['N_me'] = n 2305 2306 # Extract version number and date from VERSION file 2307 info_lines = self.get_mg5_info_lines() 2308 replace_dict['info_lines'] = info_lines 2309 2310 # Extract process info lines 2311 process_lines = self.get_process_info_lines(matrix_element) 2312 replace_dict['process_lines'] = process_lines 2313 2314 pdf_vars, pdf_data, pdf_lines = \ 2315 self.get_pdf_lines_mir(matrix_element, ninitial, False, False) 2316 replace_dict['pdf_vars'] = pdf_vars 2317 replace_dict['pdf_data'] = pdf_data 2318 replace_dict['pdf_lines'] = pdf_lines 2319 2320 pdf_vars_mirr, pdf_data_mirr, pdf_lines_mirr = \ 2321 self.get_pdf_lines_mir(matrix_element, ninitial, False, True) 2322 replace_dict['pdf_lines_mirr'] = pdf_lines_mirr 2323 2324 file = open(os.path.join(_file_path, \ 2325 'iolibs/template_files/parton_lum_n_fks.inc')).read() 2326 file = file % replace_dict 2327 2328 # Write the file 2329 writer.writelines(file)
2330 2331 2332 2333 #=============================================================================== 2334 # write_coloramps_file 2335 #=============================================================================== 2336 #test written
2337 - def write_coloramps_file(self, writer, mapconfigs, matrix_element, fortran_model):
2338 """Write the coloramps.inc file for MadEvent""" 2339 2340 lines = [] 2341 lines.append( "logical icolamp(%d,%d,1)" % \ 2342 (max(len(matrix_element.get('color_basis').keys()), 1), 2343 len(mapconfigs))) 2344 2345 lines += self.get_icolamp_lines(mapconfigs, matrix_element, 1) 2346 2347 # Write the file 2348 writer.writelines(lines) 2349 2350 return True
2351 2352 2353 #=============================================================================== 2354 # write_leshouche_file 2355 #=============================================================================== 2356 #test written
2357 - def write_leshouche_file(self, writer, matrix_element, fortran_model):
2358 """Write the leshouche.inc file for MG4""" 2359 2360 # Extract number of external particles 2361 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 2362 2363 lines = [] 2364 for iproc, proc in enumerate(matrix_element.get('processes')): 2365 legs = proc.get_legs_with_decays() 2366 lines.append("DATA (IDUP(i,%d),i=1,%d)/%s/" % \ 2367 (iproc + 1, nexternal, 2368 ",".join([str(l.get('id')) for l in legs]))) 2369 for i in [1, 2]: 2370 lines.append("DATA (MOTHUP(%d,i,%3r),i=1,%2r)/%s/" % \ 2371 (i, iproc + 1, nexternal, 2372 ",".join([ "%3r" % 0 ] * ninitial + \ 2373 [ "%3r" % i ] * (nexternal - ninitial)))) 2374 2375 # Here goes the color connections corresponding to the JAMPs 2376 # Only one output, for the first subproc! 2377 if iproc == 0: 2378 # If no color basis, just output trivial color flow 2379 if not matrix_element.get('color_basis'): 2380 for i in [1, 2]: 2381 lines.append("DATA (ICOLUP(%d,i, 1),i=1,%2r)/%s/" % \ 2382 (i, nexternal, 2383 ",".join([ "%3r" % 0 ] * nexternal))) 2384 color_flow_list = [] 2385 2386 else: 2387 # First build a color representation dictionnary 2388 repr_dict = {} 2389 for l in legs: 2390 repr_dict[l.get('number')] = \ 2391 proc.get('model').get_particle(l.get('id')).get_color()\ 2392 * (-1)**(1+l.get('state')) 2393 # Get the list of color flows 2394 color_flow_list = \ 2395 matrix_element.get('color_basis').color_flow_decomposition(repr_dict, 2396 ninitial) 2397 # And output them properly 2398 for cf_i, color_flow_dict in enumerate(color_flow_list): 2399 for i in [0, 1]: 2400 lines.append("DATA (ICOLUP(%d,i,%3r),i=1,%2r)/%s/" % \ 2401 (i + 1, cf_i + 1, nexternal, 2402 ",".join(["%3r" % color_flow_dict[l.get('number')][i] \ 2403 for l in legs]))) 2404 2405 # Write the file 2406 writer.writelines(lines) 2407 2408 return len(color_flow_list)
2409 2410 2411 #=============================================================================== 2412 # write_configs_file 2413 #=============================================================================== 2414 #test_written
2415 - def write_configs_file(self, writer, matrix_element, fortran_model):
2416 """Write the configs.inc file for MadEvent""" 2417 2418 # Extract number of external particles 2419 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 2420 lines = [] 2421 2422 iconfig = 0 2423 2424 s_and_t_channels = [] 2425 mapconfigs = [] 2426 2427 model = matrix_element.get('processes')[0].get('model') 2428 # new_pdg = model.get_first_non_pdg() 2429 2430 base_diagrams = matrix_element.get('base_amplitude').get('diagrams') 2431 model = matrix_element.get('base_amplitude').get('process').get('model') 2432 minvert = min([max([len(vert.get('legs')) for vert in \ 2433 diag.get('vertices')]) for diag in base_diagrams]) 2434 2435 for idiag, diag in enumerate(base_diagrams): 2436 if any([len(vert.get('legs')) > minvert for vert in 2437 diag.get('vertices')]): 2438 # Only 3-vertices allowed in configs.inc 2439 continue 2440 iconfig = iconfig + 1 2441 helas_diag = matrix_element.get('diagrams')[idiag] 2442 mapconfigs.append(helas_diag.get('number')) 2443 lines.append("# Diagram %d, Amplitude %d" % \ 2444 (helas_diag.get('number'),helas_diag.get('amplitudes')[0]['number'])) 2445 # Correspondance between the config and the amplitudes 2446 lines.append("data mapconfig(%4d)/%4d/" % (iconfig, 2447 helas_diag.get('amplitudes')[0]['number'])) 2448 2449 # Need to reorganize the topology so that we start with all 2450 # final state external particles and work our way inwards 2451 schannels, tchannels = helas_diag.get('amplitudes')[0].\ 2452 get_s_and_t_channels(ninitial, model, 990) 2453 2454 s_and_t_channels.append([schannels, tchannels]) 2455 2456 # Write out propagators for s-channel and t-channel vertices 2457 allchannels = schannels 2458 if len(tchannels) > 1: 2459 # Write out tchannels only if there are any non-trivial ones 2460 allchannels = schannels + tchannels 2461 2462 for vert in allchannels: 2463 daughters = [leg.get('number') for leg in vert.get('legs')[:-1]] 2464 last_leg = vert.get('legs')[-1] 2465 lines.append("data (iforest(i,%3d,%4d),i=1,%d)/%s/" % \ 2466 (last_leg.get('number'), iconfig, len(daughters), 2467 ",".join(["%3d" % d for d in daughters]))) 2468 if vert in schannels: 2469 lines.append("data sprop(%4d,%4d)/%8d/" % \ 2470 (last_leg.get('number'), iconfig, 2471 last_leg.get('id'))) 2472 elif vert in tchannels[:-1]: 2473 lines.append("data tprid(%4d,%4d)/%8d/" % \ 2474 (last_leg.get('number'), iconfig, 2475 abs(last_leg.get('id')))) 2476 2477 # Write out number of configs 2478 lines.append("# Number of configs") 2479 lines.append("data mapconfig(0)/%4d/" % iconfig) 2480 2481 # Write the file 2482 writer.writelines(lines) 2483 2484 return iconfig, mapconfigs, s_and_t_channels
2485 2486 2487 #=============================================================================== 2488 # write_decayBW_file 2489 #=============================================================================== 2490 #test written
2491 - def write_decayBW_file(self, writer, s_and_t_channels):
2492 """Write the decayBW.inc file for MadEvent""" 2493 2494 lines = [] 2495 2496 booldict = {False: ".false.", True: ".false."} 2497 ####Changed by MZ 2011-11-23!!!! 2498 2499 for iconf, config in enumerate(s_and_t_channels): 2500 schannels = config[0] 2501 for vertex in schannels: 2502 # For the resulting leg, pick out whether it comes from 2503 # decay or not, as given by the from_group flag 2504 leg = vertex.get('legs')[-1] 2505 lines.append("data gForceBW(%d,%d)/%s/" % \ 2506 (leg.get('number'), iconf + 1, 2507 booldict[leg.get('from_group')])) 2508 2509 # Write the file 2510 writer.writelines(lines) 2511 2512 return True
2513 2514 2515 #=============================================================================== 2516 # write_dname_file 2517 #===============================================================================
2518 - def write_dname_file(self, writer, matrix_element, fortran_model):
2519 """Write the dname.mg file for MG4""" 2520 2521 line = "DIRNAME=P%s" % \ 2522 matrix_element.get('processes')[0].shell_string() 2523 2524 # Write the file 2525 writer.write(line + "\n") 2526 2527 return True
2528 2529 2530 #=============================================================================== 2531 # write_iproc_file 2532 #===============================================================================
2533 - def write_iproc_file(self, writer, me_number):
2534 """Write the iproc.dat file for MG4""" 2535 2536 line = "%d" % (me_number + 1) 2537 2538 # Write the file 2539 for line_to_write in writer.write_line(line): 2540 writer.write(line_to_write) 2541 return True
2542 2543 2544 #=============================================================================== 2545 # Helper functions 2546 #=============================================================================== 2547 2548 2549 #=============================================================================== 2550 # get_fks_j_from_i_lines 2551 #=============================================================================== 2552
2553 - def get_fks_j_from_i_lines(self, me, i = 0): #test written
2554 """generate the lines for fks.inc describing initializating the 2555 fks_j_from_i array""" 2556 lines = [] 2557 if not me.isfinite: 2558 for ii, js in me.fks_j_from_i.items(): 2559 if js: 2560 lines.append('DATA (FKS_J_FROM_I_D(%d, %d, JPOS), JPOS = 0, %d) / %d, %s /' \ 2561 % (i, ii, len(js), len(js), ', '.join(["%d" % j for j in js]))) 2562 else: 2563 lines.append('DATA (FKS_J_FROM_I_D(%d, JPOS), JPOS = 0, %d) / %d, %s /' \ 2564 % (2, 1, 1, '1')) 2565 lines.append('') 2566 2567 return lines 2568 2569 2570 #=============================================================================== 2571 # get_leshouche_lines 2572 #===============================================================================
2573 - def get_leshouche_lines(self, matrix_element, ime):
2574 #test written 2575 """Write the leshouche.inc file for MG4""" 2576 2577 # Extract number of external particles 2578 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 2579 2580 lines = [] 2581 for iproc, proc in enumerate(matrix_element.get('processes')): 2582 legs = proc.get_legs_with_decays() 2583 lines.append("I %4d %4d %s" % \ 2584 (ime, iproc + 1, 2585 " ".join([str(l.get('id')) for l in legs]))) 2586 for i in [1, 2]: 2587 lines.append("M %4d %4d %4d %s" % \ 2588 (ime, i, iproc + 1, 2589 " ".join([ "%3d" % 0 ] * ninitial + \ 2590 [ "%3d" % i ] * (nexternal - ninitial)))) 2591 2592 # Here goes the color connections corresponding to the JAMPs 2593 # Only one output, for the first subproc! 2594 if iproc == 0: 2595 # If no color basis, just output trivial color flow 2596 if not matrix_element.get('color_basis'): 2597 for i in [1, 2]: 2598 lines.append("C %4d %4d 1 %s" % \ 2599 (ime, i, 2600 " ".join([ "%3d" % 0 ] * nexternal))) 2601 color_flow_list = [] 2602 nflow = 1 2603 2604 else: 2605 # First build a color representation dictionnary 2606 repr_dict = {} 2607 for l in legs: 2608 repr_dict[l.get('number')] = \ 2609 proc.get('model').get_particle(l.get('id')).get_color()\ 2610 * (-1)**(1+l.get('state')) 2611 # Get the list of color flows 2612 color_flow_list = \ 2613 matrix_element.get('color_basis').color_flow_decomposition(repr_dict, 2614 ninitial) 2615 # And output them properly 2616 for cf_i, color_flow_dict in enumerate(color_flow_list): 2617 for i in [0, 1]: 2618 lines.append("C %4d %4d %4d %s" % \ 2619 (ime, i + 1, cf_i + 1, 2620 " ".join(["%3d" % color_flow_dict[l.get('number')][i] \ 2621 for l in legs]))) 2622 2623 nflow = len(color_flow_list) 2624 2625 nproc = len(matrix_element.get('processes')) 2626 2627 return lines, nproc, nflow
2628 2629 2630 #=============================================================================== 2631 # get_den_factor_lines 2632 #===============================================================================
2633 - def get_den_factor_lines(self, fks_born):
2634 """returns the lines with the information on the denominator keeping care 2635 of the identical particle factors in the various real emissions""" 2636 2637 lines = [] 2638 info_list = fks_born.get_fks_info_list() 2639 if info_list: 2640 # if the reals have been generated, fill with the corresponding average factor 2641 lines.append('INTEGER IDEN_VALUES(%d)' % len(info_list)) 2642 lines.append('DATA IDEN_VALUES /' + \ 2643 ', '.join(['%d' % ( 2644 fks_born.born_matrix_element.get_denominator_factor() ) \ 2645 for info in info_list]) + '/') 2646 else: 2647 # otherwise use the born 2648 lines.append('INTEGER IDEN_VALUES(1)') 2649 lines.append('DATA IDEN_VALUES / %d /' \ 2650 % fks_born.born_matrix_element.get_denominator_factor()) 2651 2652 return lines
2653 2654 2655 #=============================================================================== 2656 # get_ij_lines 2657 #===============================================================================
2658 - def get_ij_lines(self, fks_born):
2659 """returns the lines with the information on the particle number of the born 2660 that splits""" 2661 info_list = fks_born.get_fks_info_list() 2662 lines = [] 2663 if info_list: 2664 # if the reals have been generated, fill with the corresponding value of ij 2665 lines.append('INTEGER IJ_VALUES(%d)' % len(info_list)) 2666 lines.append('DATA IJ_VALUES /' + \ 2667 ', '.join(['%d' % info['fks_info']['ij'] for info in info_list]) + '/') 2668 else: 2669 #otherwise just put the first leg 2670 lines.append('INTEGER IJ_VALUES(1)') 2671 lines.append('DATA IJ_VALUES / 1 /') 2672 2673 return lines
2674 2675
2676 - def get_pdf_lines_mir(self, matrix_element, ninitial, subproc_group = False,\ 2677 mirror = False): #test written
2678 """Generate the PDF lines for the auto_dsig.f file""" 2679 2680 processes = matrix_element.get('processes') 2681 model = processes[0].get('model') 2682 2683 pdf_definition_lines = "" 2684 pdf_data_lines = "" 2685 pdf_lines = "" 2686 2687 if ninitial == 1: 2688 pdf_lines = "PD(0) = 0d0\nIPROC = 0\n" 2689 for i, proc in enumerate(processes): 2690 process_line = proc.base_string() 2691 pdf_lines = pdf_lines + "IPROC=IPROC+1 ! " + process_line 2692 pdf_lines = pdf_lines + "\nPD(IPROC) = 1d0\n" 2693 pdf_lines = pdf_lines + "\nPD(0)=PD(0)+PD(IPROC)\n" 2694 else: 2695 # Pick out all initial state particles for the two beams 2696 initial_states = [sorted(list(set([p.get_initial_pdg(1) for \ 2697 p in processes]))), 2698 sorted(list(set([p.get_initial_pdg(2) for \ 2699 p in processes])))] 2700 2701 # Prepare all variable names 2702 pdf_codes = dict([(p, model.get_particle(p).get_name()) for p in \ 2703 sum(initial_states,[])]) 2704 for key,val in pdf_codes.items(): 2705 pdf_codes[key] = val.replace('~','x').replace('+','p').replace('-','m') 2706 2707 # Set conversion from PDG code to number used in PDF calls 2708 pdgtopdf = {21: 0, 22: 7} 2709 # Fill in missing entries of pdgtopdf 2710 for pdg in sum(initial_states,[]): 2711 if not pdg in pdgtopdf and not pdg in pdgtopdf.values(): 2712 pdgtopdf[pdg] = pdg 2713 elif pdg not in pdgtopdf and pdg in pdgtopdf.values(): 2714 # If any particle has pdg code 7, we need to use something else 2715 pdgtopdf[pdg] = 6000000 + pdg 2716 2717 # Get PDF variable declarations for all initial states 2718 for i in [0,1]: 2719 pdf_definition_lines += "DOUBLE PRECISION " + \ 2720 ",".join(["%s%d" % (pdf_codes[pdg],i+1) \ 2721 for pdg in \ 2722 initial_states[i]]) + \ 2723 "\n" 2724 2725 # Get PDF data lines for all initial states 2726 for i in [0,1]: 2727 pdf_data_lines += "DATA " + \ 2728 ",".join(["%s%d" % (pdf_codes[pdg],i+1) \ 2729 for pdg in initial_states[i]]) + \ 2730 "/%d*1D0/" % len(initial_states[i]) + \ 2731 "\n" 2732 2733 # Get PDF values for the different initial states 2734 for i, init_states in enumerate(initial_states): 2735 if not mirror: 2736 ibeam = i + 1 2737 else: 2738 ibeam = 2 - i 2739 if subproc_group: 2740 pdf_lines = pdf_lines + \ 2741 "IF (ABS(LPP(IB(%d))).GE.1) THEN\nLP=SIGN(1,LPP(IB(%d)))\n" \ 2742 % (ibeam, ibeam) 2743 else: 2744 pdf_lines = pdf_lines + \ 2745 "IF (ABS(LPP(%d)) .GE. 1) THEN\nLP=SIGN(1,LPP(%d))\n" \ 2746 % (ibeam, ibeam) 2747 2748 for initial_state in init_states: 2749 if initial_state in pdf_codes.keys(): 2750 if subproc_group: 2751 if abs(pdgtopdf[initial_state]) <= 7: 2752 pdf_lines = pdf_lines + \ 2753 ("%s%d=PDG2PDF(ABS(LPP(IB(%d))),%d*LP," + \ 2754 "XBK(IB(%d)),DSQRT(Q2FACT(%d)))\n") % \ 2755 (pdf_codes[initial_state], 2756 i + 1, ibeam, pdgtopdf[initial_state], 2757 ibeam, ibeam) 2758 else: 2759 # setting other partons flavours outside quark, gluon, photon to be 0d0 2760 pdf_lines = pdf_lines + \ 2761 ("c settings other partons flavours outside quark, gluon, photon to 0d0\n" + \ 2762 "%s%d=0d0\n") % \ 2763 (pdf_codes[initial_state],i + 1) 2764 else: 2765 if abs(pdgtopdf[initial_state]) <= 7: 2766 pdf_lines = pdf_lines + \ 2767 ("%s%d=PDG2PDF(ABS(LPP(%d)),%d*LP," + \ 2768 "XBK(%d),DSQRT(Q2FACT(%d)))\n") % \ 2769 (pdf_codes[initial_state], 2770 i + 1, ibeam, pdgtopdf[initial_state], 2771 ibeam, ibeam) 2772 else: 2773 # setting other partons flavours outside quark, gluon, photon to be 0d0 2774 pdf_lines = pdf_lines + \ 2775 ("c settings other partons flavours outside quark, gluon, photon to 0d0\n" + \ 2776 "%s%d=0d0\n") % \ 2777 (pdf_codes[initial_state],i + 1) 2778 2779 pdf_lines = pdf_lines + "ENDIF\n" 2780 2781 # Add up PDFs for the different initial state particles 2782 pdf_lines = pdf_lines + "PD(0) = 0d0\nIPROC = 0\n" 2783 for proc in processes: 2784 process_line = proc.base_string() 2785 pdf_lines = pdf_lines + "IPROC=IPROC+1 ! " + process_line 2786 pdf_lines = pdf_lines + "\nPD(IPROC) = " 2787 for ibeam in [1, 2]: 2788 initial_state = proc.get_initial_pdg(ibeam) 2789 if initial_state in pdf_codes.keys(): 2790 pdf_lines = pdf_lines + "%s%d*" % \ 2791 (pdf_codes[initial_state], ibeam) 2792 else: 2793 pdf_lines = pdf_lines + "1d0*" 2794 # Remove last "*" from pdf_lines 2795 pdf_lines = pdf_lines[:-1] + "\n" 2796 2797 # Remove last line break from pdf_lines 2798 return pdf_definition_lines[:-1], pdf_data_lines[:-1], pdf_lines[:-1] 2799 2800 2801 #test written
2802 - def get_color_data_lines_from_color_matrix(self, color_matrix, n=6):
2803 """Return the color matrix definition lines for the given color_matrix. Split 2804 rows in chunks of size n.""" 2805 2806 if not color_matrix: 2807 return ["DATA Denom(1)/1/", "DATA (CF(i,1),i=1,1) /1/"] 2808 else: 2809 ret_list = [] 2810 my_cs = color.ColorString() 2811 for index, denominator in \ 2812 enumerate(color_matrix.get_line_denominators()): 2813 # First write the common denominator for this color matrix line 2814 ret_list.append("DATA Denom(%i)/%i/" % (index + 1, denominator)) 2815 # Then write the numerators for the matrix elements 2816 num_list = color_matrix.get_line_numerators(index, denominator) 2817 for k in xrange(0, len(num_list), n): 2818 ret_list.append("DATA (CF(i,%3r),i=%3r,%3r) /%s/" % \ 2819 (index + 1, k + 1, min(k + n, len(num_list)), 2820 ','.join(["%5r" % i for i in num_list[k:k + n]]))) 2821 2822 return ret_list
2823 2824 #=========================================================================== 2825 # write_maxamps_file 2826 #===========================================================================
2827 - def write_maxamps_file(self, writer, maxamps, maxflows, 2828 maxproc,maxsproc):
2829 """Write the maxamps.inc file for MG4.""" 2830 2831 file = " integer maxamps, maxflow, maxproc, maxsproc\n" 2832 file = file + "parameter (maxamps=%d, maxflow=%d)\n" % \ 2833 (maxamps, maxflows) 2834 file = file + "parameter (maxproc=%d, maxsproc=%d)" % \ 2835 (maxproc, maxsproc) 2836 2837 # Write the file 2838 writer.writelines(file) 2839 2840 return True
2841 2842 #=============================================================================== 2843 # write_ncombs_file 2844 #===============================================================================
2845 - def write_ncombs_file(self, writer, matrix_element, fortran_model):
2846 # #test written 2847 """Write the ncombs.inc file for MadEvent.""" 2848 2849 # Extract number of external particles 2850 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 2851 2852 # ncomb (used for clustering) is 2^(nexternal) 2853 file = " integer n_max_cl\n" 2854 file = file + "parameter (n_max_cl=%d)" % (2 ** (nexternal+1)) 2855 2856 # Write the file 2857 writer.writelines(file) 2858 2859 return True
2860 2861 #=========================================================================== 2862 # write_config_subproc_map_file 2863 #===========================================================================
2864 - def write_config_subproc_map_file(self, writer, s_and_t_channels):
2865 """Write a dummy config_subproc.inc file for MadEvent""" 2866 2867 lines = [] 2868 2869 for iconfig in range(len(s_and_t_channels)): 2870 lines.append("DATA CONFSUB(1,%d)/1/" % \ 2871 (iconfig + 1)) 2872 2873 # Write the file 2874 writer.writelines(lines) 2875 2876 return True
2877 2878 #=========================================================================== 2879 # write_colors_file 2880 #===========================================================================
2881 - def write_colors_file(self, writer, matrix_element):
2882 """Write the get_color.f file for MadEvent, which returns color 2883 for all particles used in the matrix element.""" 2884 2885 try: 2886 matrix_elements=matrix_element.real_processes[0].matrix_element 2887 except IndexError: 2888 matrix_elements=[matrix_element.born_matrix_element] 2889 2890 if isinstance(matrix_elements, helas_objects.HelasMatrixElement): 2891 matrix_elements = [matrix_elements] 2892 2893 model = matrix_elements[0].get('processes')[0].get('model') 2894 2895 # We need the both particle and antiparticle wf_ids, since the identity 2896 # depends on the direction of the wf. 2897 # loop on the real emissions 2898 wf_ids = set(sum([sum([sum([sum([[wf.get_pdg_code(),wf.get_anti_pdg_code()] \ 2899 for wf in d.get('wavefunctions')],[]) \ 2900 for d in me.get('diagrams')],[]) \ 2901 for me in [real_proc.matrix_element]],[])\ 2902 for real_proc in matrix_element.real_processes],[])) 2903 # and also on the born 2904 wf_ids = wf_ids.union(set(sum([sum([[wf.get_pdg_code(),wf.get_anti_pdg_code()] \ 2905 for wf in d.get('wavefunctions')],[]) \ 2906 for d in matrix_element.born_matrix_element.get('diagrams')],[]))) 2907 2908 # loop on the real emissions 2909 leg_ids = set(sum([sum([sum([[l.get('id') for l in \ 2910 p.get_legs_with_decays()] for p in \ 2911 me.get('processes')], []) for me in \ 2912 [real_proc.matrix_element]], []) for real_proc in \ 2913 matrix_element.real_processes],[])) 2914 # and also on the born 2915 leg_ids = leg_ids.union(set(sum([[l.get('id') for l in \ 2916 p.get_legs_with_decays()] for p in \ 2917 matrix_element.born_matrix_element.get('processes')], []))) 2918 particle_ids = sorted(list(wf_ids.union(leg_ids))) 2919 2920 lines = """function get_color(ipdg) 2921 implicit none 2922 integer get_color, ipdg 2923 2924 if(ipdg.eq.%d)then 2925 get_color=%d 2926 return 2927 """ % (particle_ids[0], model.get_particle(particle_ids[0]).get_color()) 2928 2929 for part_id in particle_ids[1:]: 2930 lines += """else if(ipdg.eq.%d)then 2931 get_color=%d 2932 return 2933 """ % (part_id, model.get_particle(part_id).get_color()) 2934 # Dummy particle for multiparticle vertices with pdg given by 2935 # first code not in the model 2936 lines += """else if(ipdg.eq.%d)then 2937 c This is dummy particle used in multiparticle vertices 2938 get_color=2 2939 return 2940 """ % model.get_first_non_pdg() 2941 lines += """else 2942 write(*,*)'Error: No color given for pdg ',ipdg 2943 get_color=0 2944 return 2945 endif 2946 end 2947 """ 2948 2949 # Write the file 2950 writer.writelines(lines) 2951 2952 return True
2953 2954 #=============================================================================== 2955 # write_props_file 2956 #=============================================================================== 2957 #test_written
2958 - def write_props_file(self, writer, matrix_element, fortran_model, s_and_t_channels):
2959 """Write the props.inc file for MadEvent. Needs input from 2960 write_configs_file. With respect to the parent routine, it has some 2961 more specific formats that allow the props.inc file to be read by the 2962 link program""" 2963 2964 lines = [] 2965 2966 particle_dict = matrix_element.get('processes')[0].get('model').\ 2967 get('particle_dict') 2968 2969 for iconf, configs in enumerate(s_and_t_channels): 2970 for vertex in configs[0] + configs[1][:-1]: 2971 leg = vertex.get('legs')[-1] 2972 if leg.get('id') not in particle_dict: 2973 # Fake propagator used in multiparticle vertices 2974 mass = 'zero' 2975 width = 'zero' 2976 pow_part = 0 2977 else: 2978 particle = particle_dict[leg.get('id')] 2979 # Get mass 2980 if particle.get('mass').lower() == 'zero': 2981 mass = particle.get('mass') 2982 else: 2983 mass = "abs(%s)" % particle.get('mass') 2984 # Get width 2985 if particle.get('width').lower() == 'zero': 2986 width = particle.get('width') 2987 else: 2988 width = "abs(%s)" % particle.get('width') 2989 2990 pow_part = 1 + int(particle.is_boson()) 2991 2992 lines.append("pmass(%3d,%4d) = %s" % \ 2993 (leg.get('number'), iconf + 1, mass)) 2994 lines.append("pwidth(%3d,%4d) = %s" % \ 2995 (leg.get('number'), iconf + 1, width)) 2996 lines.append("pow(%3d,%4d) = %d" % \ 2997 (leg.get('number'), iconf + 1, pow_part)) 2998 2999 # Write the file 3000 writer.writelines(lines) 3001 3002 return True
3003 3004 3005 #=========================================================================== 3006 # write_subproc 3007 #===========================================================================
3008 - def write_subproc(self, writer, subprocdir):
3009 """Append this subprocess to the subproc.mg file for MG4""" 3010 3011 # Write line to file 3012 writer.write(subprocdir + "\n") 3013 3014 return True
3015 3016 3017 3018 3019 3020 #================================================================================= 3021 # Class for using the optimized Loop process 3022 #=================================================================================
3023 -class ProcessOptimizedExporterFortranFKS(loop_exporters.LoopProcessOptimizedExporterFortranSA,\ 3024 ProcessExporterFortranFKS):
3025 """Class to take care of exporting a set of matrix elements to 3026 Fortran (v4) format.""" 3027 3028 #=============================================================================== 3029 # copy the Template in a new directory. 3030 #===============================================================================
3031 - def copy_fkstemplate(self):
3032 """create the directory run_name as a copy of the MadEvent 3033 Template, and clean the directory 3034 For now it is just the same as copy_v4template, but it will be modified 3035 """ 3036 mgme_dir = self.mgme_dir 3037 dir_path = self.dir_path 3038 clean =self.opt['clean'] 3039 3040 #First copy the full template tree if dir_path doesn't exit 3041 if not os.path.isdir(dir_path): 3042 if not mgme_dir: 3043 raise MadGraph5Error, \ 3044 "No valid MG_ME path given for MG4 run directory creation." 3045 logger.info('initialize a new directory: %s' % \ 3046 os.path.basename(dir_path)) 3047 shutil.copytree(os.path.join(mgme_dir, 'Template', 'NLO'), dir_path, True) 3048 # distutils.dir_util.copy_tree since dir_path already exists 3049 dir_util.copy_tree(pjoin(self.mgme_dir, 'Template', 'Common'), 3050 dir_path) 3051 elif not os.path.isfile(os.path.join(dir_path, 'TemplateVersion.txt')): 3052 if not mgme_dir: 3053 raise MadGraph5Error, \ 3054 "No valid MG_ME path given for MG4 run directory creation." 3055 try: 3056 shutil.copy(os.path.join(mgme_dir, 'MGMEVersion.txt'), dir_path) 3057 except IOError: 3058 MG5_version = misc.get_pkg_info() 3059 open(os.path.join(dir_path, 'MGMEVersion.txt'), 'w').write( \ 3060 "5." + MG5_version['version']) 3061 3062 #Ensure that the Template is clean 3063 if clean: 3064 logger.info('remove old information in %s' % os.path.basename(dir_path)) 3065 if os.environ.has_key('MADGRAPH_BASE'): 3066 subprocess.call([os.path.join('bin', 'internal', 'clean_template'), 3067 '--web'], cwd=dir_path) 3068 else: 3069 try: 3070 subprocess.call([os.path.join('bin', 'internal', 'clean_template')], \ 3071 cwd=dir_path) 3072 except Exception, why: 3073 raise MadGraph5Error('Failed to clean correctly %s: \n %s' \ 3074 % (os.path.basename(dir_path),why)) 3075 #Write version info 3076 MG_version = misc.get_pkg_info() 3077 open(os.path.join(dir_path, 'SubProcesses', 'MGVersion.txt'), 'w').write( 3078 MG_version['version']) 3079 3080 # We must link the CutTools to the Library folder of the active Template 3081 self.link_CutTools(dir_path) 3082 # We must link the TIR to the Library folder of the active Template 3083 link_tir_libs=[] 3084 tir_libs=[] 3085 tir_include=[] 3086 for tir in self.all_tir: 3087 tir_dir="%s_dir"%tir 3088 libpath=getattr(self,tir_dir) 3089 libpath = self.link_TIR(os.path.join(self.dir_path, 'lib'), 3090 libpath,"lib%s.a"%tir,tir_name=tir) 3091 setattr(self,tir_dir,libpath) 3092 if libpath != "": 3093 if tir in ['pjfry','ninja','golem', 'samurai']: 3094 # We should link dynamically when possible, so we use the original 3095 # location of these libraries. 3096 link_tir_libs.append('-L%s/ -l%s'%(libpath,tir)) 3097 tir_libs.append('%s/lib%s.$(libext)'%(libpath,tir)) 3098 # We must add the corresponding includes for golem, samurai 3099 # and ninja 3100 if tir in ['golem','samurai','ninja']: 3101 trg_path = pjoin(os.path.dirname(libpath),'include') 3102 to_include = misc.find_includes_path(trg_path, 3103 self.include_names[tir]) 3104 if to_include is None: 3105 logger.error( 3106 'Could not find the include directory for %s, looking in %s.\n' % (tir ,str(trg_path))+ 3107 'Generation carries on but you will need to edit the include path by hand in the makefiles.') 3108 to_include = '<Not_found_define_it_yourself>' 3109 tir_include.append('-I %s'%to_include) 3110 else: 3111 link_tir_libs.append('-l%s'%tir) 3112 tir_libs.append('$(LIBDIR)lib%s.$(libext)'%tir) 3113 3114 os.remove(os.path.join(self.dir_path,'SubProcesses','makefile_loop.inc')) 3115 cwd = os.getcwd() 3116 dirpath = os.path.join(self.dir_path, 'SubProcesses') 3117 try: 3118 os.chdir(dirpath) 3119 except os.error: 3120 logger.error('Could not cd to directory %s' % dirpath) 3121 return 0 3122 filename = 'makefile_loop' 3123 calls = self.write_makefile_TIR(writers.MakefileWriter(filename), 3124 link_tir_libs,tir_libs,tir_include=tir_include) 3125 os.remove(os.path.join(self.dir_path,'Source','make_opts.inc')) 3126 dirpath = os.path.join(self.dir_path, 'Source') 3127 try: 3128 os.chdir(dirpath) 3129 except os.error: 3130 logger.error('Could not cd to directory %s' % dirpath) 3131 return 0 3132 filename = 'make_opts' 3133 calls = self.write_make_opts(writers.MakefileWriter(filename), 3134 link_tir_libs,tir_libs) 3135 # Return to original PWD 3136 os.chdir(cwd) 3137 3138 cwd = os.getcwd() 3139 dirpath = os.path.join(self.dir_path, 'SubProcesses') 3140 try: 3141 os.chdir(dirpath) 3142 except os.error: 3143 logger.error('Could not cd to directory %s' % dirpath) 3144 return 0 3145 3146 # We add here the user-friendly MadLoop option setter. 3147 cpfiles= ["SubProcesses/MadLoopParamReader.f", 3148 "Cards/MadLoopParams.dat", 3149 "SubProcesses/MadLoopParams.inc"] 3150 3151 for file in cpfiles: 3152 shutil.copy(os.path.join(self.loop_dir,'StandAlone/', file), 3153 os.path.join(self.dir_path, file)) 3154 3155 shutil.copy(pjoin(self.dir_path, 'Cards','MadLoopParams.dat'), 3156 pjoin(self.dir_path, 'Cards','MadLoopParams_default.dat')) 3157 3158 3159 3160 if os.path.exists(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')): 3161 self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.dir_path, 3162 'Cards', 'MadLoopParams.dat')) 3163 # write the output file 3164 self.MadLoopparam.write(pjoin(self.dir_path,"SubProcesses", 3165 "MadLoopParams.dat")) 3166 3167 # We need minimal editing of MadLoopCommons.f 3168 MadLoopCommon = open(os.path.join(self.loop_dir,'StandAlone', 3169 "SubProcesses","MadLoopCommons.inc")).read() 3170 writer = writers.FortranWriter(os.path.join(self.dir_path, 3171 "SubProcesses","MadLoopCommons.f")) 3172 writer.writelines(MadLoopCommon%{ 3173 'print_banner_commands':self.MadLoop_banner}) 3174 writer.close() 3175 3176 # link the files from the MODEL 3177 model_path = self.dir_path + '/Source/MODEL/' 3178 # Note that for the [real=] mode, these files are not present 3179 if os.path.isfile(os.path.join(model_path,'mp_coupl.inc')): 3180 ln(model_path + '/mp_coupl.inc', self.dir_path + '/SubProcesses') 3181 if os.path.isfile(os.path.join(model_path,'mp_coupl_same_name.inc')): 3182 ln(model_path + '/mp_coupl_same_name.inc', \ 3183 self.dir_path + '/SubProcesses') 3184 3185 # Write the cts_mpc.h and cts_mprec.h files imported from CutTools 3186 self.write_mp_files(writers.FortranWriter('cts_mprec.h'),\ 3187 writers.FortranWriter('cts_mpc.h'),) 3188 3189 self.copy_python_files() 3190 3191 3192 # We need to create the correct open_data for the pdf 3193 self.write_pdf_opendata() 3194 3195 3196 # Return to original PWD 3197 os.chdir(cwd)
3198
3199 - def generate_virt_directory(self, loop_matrix_element, fortran_model, dir_name):
3200 """writes the V**** directory inside the P**** directories specified in 3201 dir_name""" 3202 3203 cwd = os.getcwd() 3204 3205 matrix_element = loop_matrix_element 3206 3207 # Create the MadLoop5_resources directory if not already existing 3208 dirpath = os.path.join(dir_name, 'MadLoop5_resources') 3209 try: 3210 os.mkdir(dirpath) 3211 except os.error as error: 3212 logger.warning(error.strerror + " " + dirpath) 3213 3214 # Create the directory PN_xx_xxxxx in the specified path 3215 name = "V%s" % matrix_element.get('processes')[0].shell_string() 3216 dirpath = os.path.join(dir_name, name) 3217 3218 try: 3219 os.mkdir(dirpath) 3220 except os.error as error: 3221 logger.warning(error.strerror + " " + dirpath) 3222 3223 try: 3224 os.chdir(dirpath) 3225 except os.error: 3226 logger.error('Could not cd to directory %s' % dirpath) 3227 return 0 3228 3229 logger.info('Creating files in directory %s' % name) 3230 3231 # Extract number of external particles 3232 (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() 3233 3234 calls=self.write_loop_matrix_element_v4(None,matrix_element,fortran_model) 3235 3236 # We need a link to coefs.inc from DHELAS 3237 ln(pjoin(self.dir_path, 'Source', 'DHELAS', 'coef_specs.inc'), 3238 abspath=False, cwd=None) 3239 3240 # The born matrix element, if needed 3241 filename = 'born_matrix.f' 3242 calls = self.write_bornmatrix( 3243 writers.FortranWriter(filename), 3244 matrix_element, 3245 fortran_model) 3246 3247 filename = 'nexternal.inc' 3248 self.write_nexternal_file(writers.FortranWriter(filename), 3249 nexternal, ninitial) 3250 3251 filename = 'pmass.inc' 3252 self.write_pmass_file(writers.FortranWriter(filename), 3253 matrix_element) 3254 3255 filename = 'ngraphs.inc' 3256 self.write_ngraphs_file(writers.FortranWriter(filename), 3257 len(matrix_element.get_all_amplitudes())) 3258 3259 filename = "loop_matrix.ps" 3260 writers.FortranWriter(filename).writelines("""C Post-helas generation loop-drawing is not ready yet.""") 3261 plot = draw.MultiEpsDiagramDrawer(base_objects.DiagramList( 3262 matrix_element.get('base_amplitude').get('loop_diagrams')[:1000]), 3263 filename, 3264 model=matrix_element.get('processes')[0].get('model'), 3265 amplitude='') 3266 logger.info("Drawing loop Feynman diagrams for " + \ 3267 matrix_element.get('processes')[0].nice_string(\ 3268 print_weighted=False)) 3269 plot.draw() 3270 3271 filename = "born_matrix.ps" 3272 plot = draw.MultiEpsDiagramDrawer(matrix_element.get('base_amplitude').\ 3273 get('born_diagrams'), 3274 filename, 3275 model=matrix_element.get('processes')[0].\ 3276 get('model'), 3277 amplitude='') 3278 logger.info("Generating born Feynman diagrams for " + \ 3279 matrix_element.get('processes')[0].nice_string(\ 3280 print_weighted=False)) 3281 plot.draw() 3282 3283 linkfiles = ['coupl.inc', 'mp_coupl.inc', 'mp_coupl_same_name.inc', 3284 'cts_mprec.h', 'cts_mpc.h', 'MadLoopParamReader.f', 3285 'MadLoopParams.inc','MadLoopCommons.f'] 3286 3287 for file in linkfiles: 3288 ln('../../%s' % file) 3289 3290 3291 os.system("ln -s ../../makefile_loop makefile") 3292 3293 # We should move to MadLoop5_resources directory from the SubProcesses 3294 ln(pjoin(os.path.pardir,os.path.pardir,'MadLoopParams.dat'), 3295 pjoin('..','MadLoop5_resources')) 3296 3297 linkfiles = ['mpmodule.mod'] 3298 3299 for file in linkfiles: 3300 ln('../../../lib/%s' % file) 3301 3302 linkfiles = ['coef_specs.inc'] 3303 3304 for file in linkfiles: 3305 ln('../../../Source/DHELAS/%s' % file) 3306 3307 # Return to original PWD 3308 os.chdir(cwd) 3309 3310 if not calls: 3311 calls = 0 3312 return calls
3313 3314 3315 #=============================================================================== 3316 # write_coef_specs 3317 #===============================================================================
3318 - def write_coef_specs_file(self, max_loop_vertex_ranks):
3319 """ writes the coef_specs.inc in the DHELAS folder. Should not be called in the 3320 non-optimized mode""" 3321 filename = os.path.join(self.dir_path, 'Source', 'DHELAS', 'coef_specs.inc') 3322 3323 replace_dict = {} 3324 replace_dict['max_lwf_size'] = 4 3325 replace_dict['vertex_max_coefs'] = max(\ 3326 [q_polynomial.get_number_of_coefs_for_rank(n) 3327 for n in max_loop_vertex_ranks]) 3328 IncWriter=writers.FortranWriter(filename,'w') 3329 IncWriter.writelines("""INTEGER MAXLWFSIZE 3330 PARAMETER (MAXLWFSIZE=%(max_lwf_size)d) 3331 INTEGER VERTEXMAXCOEFS 3332 PARAMETER (VERTEXMAXCOEFS=%(vertex_max_coefs)d)"""\ 3333 % replace_dict) 3334 IncWriter.close()
3335