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