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