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