320
322
files.cp(model.restrict_card, out_path)
324
#===========================================================================
325
# write_maxparticles_file
326
#===========================================================================
327
def write_maxparticles_file(self, writer, maxparticles):
328
"""Write the maxparticles.inc file for MadEvent"""
330
lines = "integer max_particles, max_branch\n"
331
lines += "parameter (max_particles=%d) \n" % maxparticles
332
lines += "parameter (max_branch=max_particles-1)"
335
writer.writelines(lines)
340
#===========================================================================
341
# write_maxconfigs_file
342
#===========================================================================
343
def write_maxconfigs_file(self, writer, maxconfigs):
344
"""Write the maxconfigs.inc file for MadEvent"""
346
lines = "integer lmaxconfigs\n"
347
lines += "parameter (lmaxconfigs=%d)" % maxconfigs
350
writer.writelines(lines)
355
325
#===============================================================================
356
326
# write a procdef_mg5 (an equivalent of the MG4 proc_card.dat)
357
327
#===============================================================================
603
filename = 'ngraphs.inc'
604
self.write_ngraphs_file(writers.FortranWriter(filename),
573
filename = 'maxconfigs.inc'
574
self.write_maxconfigs_file(writers.FortranWriter(filename),
575
max(nconfigs,matrix_element.born_me.get_number_of_amplitudes()))
607
577
#write the wrappers for real ME's
608
578
filename_me = 'real_me_chooser.f'
627
597
writers.FortranWriter(filename),
600
filename = 'a0Gmuconv.inc'
601
startfroma0 = self.write_a0gmuconv_file(
602
writers.FortranWriter(filename),
605
filename = 'rescale_alpha_tagged.f'
606
self.write_rescale_a0gmu_file(
607
writers.FortranWriter(filename),
608
startfroma0, matrix_element)
630
610
filename = 'orders.h'
631
611
self.write_orders_c_header_file(
632
612
writers.CPPWriter(filename),
638
618
amp_split_orders)
639
619
self.proc_characteristic['ninitial'] = ninitial
640
620
self.proc_characteristic['nexternal'] = max(self.proc_characteristic['nexternal'], nexternal)
622
filename = 'maxparticles.inc'
623
self.write_maxparticles_file(writers.FortranWriter(filename),
642
626
filename = 'pmass.inc'
644
628
self.write_pmass_file(writers.FortranWriter(filename),
846
823
filename = os.path.join(self.dir_path,'Source','MODEL','get_mass_width_fcts.f')
847
824
makeinc = os.path.join(self.dir_path,'Source','MODEL','makeinc.inc')
848
825
self.write_get_mass_width_file(writers.FortranWriter(filename), makeinc, self.model)
850
# # Write maxconfigs.inc based on max of ME's/subprocess groups
852
filename = os.path.join(self.dir_path,'Source','maxconfigs.inc')
853
self.write_maxconfigs_file(writers.FortranWriter(filename),
854
matrix_elements.get_max_configs())
856
# # Write maxparticles.inc based on max of ME's/subprocess groups
857
filename = os.path.join(self.dir_path,'Source','maxparticles.inc')
858
self.write_maxparticles_file(writers.FortranWriter(filename),
859
matrix_elements.get_max_particles())
861
827
# Touch "done" file
862
828
os.system('touch %s/done' % os.path.join(self.dir_path,'SubProcesses'))
1096
1062
writer.writelines(text)
1065
def write_a0gmuconv_file(self, writer, matrix_element):
1066
"""writes an include file with the informations about the
1067
alpha0 < > gmu conversion, to be used when the process has
1071
bool_dict = {True: '.true.', False: '.false.'}
1072
bornproc = matrix_element.born_me['processes'][0]
1073
startfromalpha0 = False
1074
if any([l['is_tagged'] and l['id'] == 22 for l in bornproc['legs']]):
1075
if 'loop_qcd_qed_sm_a0' in bornproc['model'].get('modelpath'):
1076
startfromalpha0 = True
1078
text = 'logical startfroma0\nparameter (startfroma0=%s)\n' % bool_dict[startfromalpha0]
1079
writer.writelines(text)
1080
return startfromalpha0
1099
1082
def write_orders_c_header_file(self, writer, amp_split_size, amp_split_size_born):
1100
1083
"""writes the header file including the amp_split_size declaration for amcblast
1105
1088
writer.writelines(text)
1091
def write_rescale_a0gmu_file(self, writer, startfroma0, matrix_element):
1092
"""writes the function that computes the rescaling factor needed in
1093
the case of external photons
1096
# get the model parameters
1097
params = sum([v for v in self.model.get('parameters').values()], [])
1098
parnames = [p.name.lower() for p in params]
1100
bornproc = matrix_element.born_me['processes'][0]
1101
# this is to ensure compatibility with standard processes
1102
if not any([l['is_tagged'] and l['id'] == 22 for l in bornproc['legs']]):
1109
to_check = ['mdl_aewgmu', 'mdl_aew']
1110
base = 'mdl_aewgmu/mdl_aew'
1111
exp = 'qed_pow/2d0-ntag'
1112
expr = '(%s)**(%s)' % (base, exp)
1113
conv_fin = '(qed_pow - ntagph * 2d0) * MDL_ECOUP_DGMUA0_UV_EW_FIN_ * born_wgt'
1114
conv_pol = '(qed_pow - ntagph * 2d0) * MDL_ECOUP_DGMUA0_UV_EW_1EPS_ * born_wgt'
1116
to_check = ['mdl_aew', 'mdl_aew0']
1117
base = 'mdl_aew0/mdl_aew'
1119
expr = '(%s)**(%s)' % (base, exp)
1120
conv_fin = '- ntagph * 2d0 * MDL_ECOUP_DGMUA0_UV_EW_FIN_ * born_wgt'
1121
conv_pol = '- ntagph * 2d0 * MDL_ECOUP_DGMUA0_UV_EW_1EPS_ * born_wgt'
1123
replace_dict = {'rescale_fact': expr,
1124
'virtual_a0Gmu_conv_finite': conv_fin,
1125
'virtual_a0Gmu_conv_pole': conv_pol}
1127
if not all(p in parnames for p in to_check):
1128
raise fks_common.FKSProcessError(
1129
'Some parameters needed when there are tagged '+\
1130
'photons cannot be found in the model.\n' +\
1131
'Please load the correct model and restriction ' +\
1132
'(e.g loop_qcd_qed_sm_Gmu-a0 or loop_qcd_qed_sm_a0-Gmu)')
1134
file = open(os.path.join(_file_path, \
1135
'iolibs/template_files/rescale_alpha_tagged.inc')).read()
1136
file = file % replace_dict
1139
writer.writelines(file)
1109
1143
def write_orders_file(self, writer, matrix_element):
1110
1144
"""writes the include file with the informations about coupling orders.
1583
1617
writer.writelines(lines)
1620
def write_maxparticles_file(self, writer, maxparticles):
1621
"""Write the maxparticles.inc file for MadEvent"""
1622
lines = "integer max_particles, max_branch\n"
1623
lines += "parameter (max_particles=%d) \n" % maxparticles
1624
lines += "parameter (max_branch=max_particles-1)"
1625
writer.writelines(lines)
1628
def write_maxconfigs_file(self, writer, maxconfigs):
1629
"""Write the maxconfigs.inc file for MadEvent"""
1630
lines = "integer lmaxconfigs\n"
1631
lines += "parameter (lmaxconfigs=%d)" % maxconfigs
1632
writer.writelines(lines)
1586
1635
def write_genps(self, writer, maxproc,ngraphs,ncolor,maxflow, fortran_model):
1587
1636
"""writes the genps.inc file
1808
1857
if 'sa_symmetry 'not in self.opt:
1809
1858
self.opt['sa_symmetry']=False
1861
# Add information relevant for FxFx matching:
1862
# Maximum QCD power in all the contributions
1864
for diag in matrix_element.get('diagrams'):
1865
orders = diag.calculate_orders()
1867
max_qcd_order = max(max_qcd_order,orders['QCD'])
1868
max_n_light_final_partons = max(len([1 for id in proc.get_final_ids()
1869
if proc.get('model').get_particle(id).get('mass')=='ZERO' and
1870
proc.get('model').get_particle(id).get('color')>1])
1871
for proc in matrix_element.get('processes'))
1872
# Maximum number of final state light jets to be matched
1873
self.proc_characteristic['max_n_matched_jets'] = max(
1874
self.proc_characteristic['max_n_matched_jets'],
1875
min(max_qcd_order,max_n_light_final_partons))
1811
1877
# Set lowercase/uppercase Fortran code
1812
1878
writers.FortranWriter.downcase = False
1971
2037
self.write_born_nhel_file(writers.FortranWriter(filename),
1972
2038
born_me, nflows, fortran_model)
1974
filename = 'born_ngraphs.inc'
1975
self.write_ngraphs_file(writers.FortranWriter(filename), nconfigs)
1977
filename = 'ncombs.inc'
1978
self.write_ncombs_file(writers.FortranWriter(filename),
1979
born_me, fortran_model)
1981
2040
filename = 'born_coloramps.inc'
1982
2041
self.write_coloramps_file(writers.FortranWriter(filename),
1983
2042
mapconfigs, born_me, fortran_model)
2408
2467
proc.get('model').get_particle(id).get('color')>1])
2409
2468
for proc in matrix_element.get('processes'))
2410
2469
# Maximum number of final state light jets to be matched
2470
misc.sprint(self.proc_characteristic['max_n_matched_jets'], max_qcd_order,max_n_light_final_partons)
2411
2471
self.proc_characteristic['max_n_matched_jets'] = max(
2412
2472
self.proc_characteristic['max_n_matched_jets'],
2413
2473
min(max_qcd_order,max_n_light_final_partons))
2870
2931
'DATA (PARTICLE_CHARGE_D(%d, IPOS), IPOS=1, NEXTERNAL) / %s /'\
2871
2932
% (i + 1, ', '.join('%19.15fd0' % charg\
2872
2933
for charg in fksborn.real_processes[info['n_me']-1].charges) ))
2935
'DATA (PARTICLE_TAG_D(%d, IPOS), IPOS=1, NEXTERNAL) / %s /' \
2936
% (i + 1, ', '.join(bool_dict[tag] for tag in fksborn.real_processes[info['n_me']-1].particle_tags) ))
2873
2937
fks_j_from_i_lines.extend(self.get_fks_j_from_i_lines(fksborn.real_processes[info['n_me']-1],\
2875
2939
split_type_lines.append( \
2884
2948
pdgs = [l.get('id') for l in bornproc.get('legs')] + [-21]
2885
2949
colors = [l.get('color') for l in bornproc.get('legs')] + [8]
2886
2950
charges = [l.get('charge') for l in bornproc.get('legs')] + [0.]
2951
tags = [l.get('is_tagged') for l in bornproc.get('legs')] + [False]
2888
2953
fks_i = len(colors)
2889
2954
# fist look for a colored legs (set j to 1 otherwise)
2919
2984
% ', '.join([str(pdg) for pdg in pdgs])]
2920
2985
charge_lines = ['DATA (PARTICLE_CHARGE_D(1, IPOS), IPOS=1, NEXTERNAL) / %s /' \
2921
2986
% ', '.join('%19.15fd0' % charg for charg in charges)]
2987
tag_lines = ['DATA (PARTICLE_TAG_D(1, IPOS), IPOS=1, NEXTERNAL) / %s /' \
2988
% ', '.join(bool_dict[tag] for tag in tags)]
2922
2989
fks_j_from_i_lines = ['DATA (FKS_J_FROM_I_D(1, %d, JPOS), JPOS = 0, 1) / 1, %d /' \
2923
2990
% (fks_i, fks_j)]
2924
2991
split_type_lines = [ \
2930
2997
replace_dict['col_lines'] = '\n'.join(col_lines)
2931
2998
replace_dict['pdg_lines'] = '\n'.join(pdg_lines)
2932
2999
replace_dict['charge_lines'] = '\n'.join(charge_lines)
3000
replace_dict['tag_lines'] = '\n'.join(tag_lines)
2933
3001
replace_dict['fks_j_from_i_lines'] = '\n'.join(fks_j_from_i_lines)
2934
3002
replace_dict['split_type_lines'] = '\n'.join(split_type_lines)
3692
3759
writer.writelines(file)
3696
#===============================================================================
3698
#===============================================================================
3699
def write_ncombs_file(self, writer, matrix_element, fortran_model):
3701
"""Write the ncombs.inc file for MadEvent."""
3703
# Extract number of external particles
3704
(nexternal, ninitial) = matrix_element.get_nexternal_ninitial()
3706
# ncomb (used for clustering) is 2^(nexternal)
3707
file = " integer n_max_cl\n"
3708
file = file + "parameter (n_max_cl=%d)" % (2 ** (nexternal+1))
3711
writer.writelines(file)
3715
#===========================================================================
3716
# write_config_subproc_map_file
3717
#===========================================================================
3718
def write_config_subproc_map_file(self, writer, s_and_t_channels):
3719
"""Write a dummy config_subproc.inc file for MadEvent"""
3723
for iconfig in range(len(s_and_t_channels)):
3724
lines.append("DATA CONFSUB(1,%d)/1/" % \
3728
writer.writelines(lines)
3732
3763
#===========================================================================
3733
3764
# write_colors_file
3794
3825
""" % model.get_first_non_pdg()
3795
3826
lines += """else
3796
3827
write(*,*)'Error: No color given for pdg ',ipdg
3835
function get_spin(ipdg)
3837
integer get_spin, ipdg
3842
""" % (particle_ids[0], model.get_particle(particle_ids[0]).get('spin'))
3844
for part_id in particle_ids[1:]:
3845
lines += """else if(ipdg.eq.%d)then
3848
""" % (part_id, model.get_particle(part_id).get('spin'))
3849
# Dummy particle for multiparticle vertices with pdg given by
3850
# first code not in the model
3851
lines += """else if(ipdg.eq.%d)then
3852
c This is dummy particle used in multiparticle vertices
3855
""" % model.get_first_non_pdg()
3857
write(*,*)'Error: No spin given for pdg ',ipdg