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