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