~maddevelopers/mg5amcnlo/simple_unlops

« back to all changes in this revision

Viewing changes to madgraph/iolibs/export_fks.py

  • Committer: olivier-mattelaer
  • Date: 2021-11-12 09:29:31 UTC
  • mfrom: (967.1.15 3.3.0)
  • Revision ID: olivier-mattelaer-20211112092931-4ec9qfzgxkeovqog
versionĀ 3.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import copy
28
28
import platform
29
29
 
 
30
import madgraph
30
31
import madgraph.core.color_algebra as color
31
32
import madgraph.core.helas_objects as helas_objects
32
33
import madgraph.core.base_objects as base_objects
58
59
 
59
60
_file_path = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0] + '/'
60
61
logger = logging.getLogger('madgraph.export_fks')
61
 
 
 
62
if madgraph.ordering:
 
63
    set = misc.OrderedSet
62
64
 
63
65
def make_jpeg_async(args):
64
66
    Pdir = args[0]
320
322
                files.cp(model.restrict_card, out_path)
321
323
 
322
324
 
323
 
 
324
 
    #===========================================================================
325
 
    # write_maxparticles_file
326
 
    #===========================================================================
327
 
    def write_maxparticles_file(self, writer, maxparticles):
328
 
        """Write the maxparticles.inc file for MadEvent"""
329
 
 
330
 
        lines = "integer max_particles, max_branch\n"
331
 
        lines += "parameter (max_particles=%d) \n" % maxparticles
332
 
        lines += "parameter (max_branch=max_particles-1)"
333
 
 
334
 
        # Write the file
335
 
        writer.writelines(lines)
336
 
 
337
 
        return True
338
 
 
339
 
 
340
 
    #===========================================================================
341
 
    # write_maxconfigs_file
342
 
    #===========================================================================
343
 
    def write_maxconfigs_file(self, writer, maxconfigs):
344
 
        """Write the maxconfigs.inc file for MadEvent"""
345
 
 
346
 
        lines = "integer lmaxconfigs\n"
347
 
        lines += "parameter (lmaxconfigs=%d)" % maxconfigs
348
 
 
349
 
        # Write the file
350
 
        writer.writelines(lines)
351
 
 
352
 
        return True
353
 
 
354
 
 
355
325
    #===============================================================================
356
326
    # write a procdef_mg5 (an equivalent of the MG4 proc_card.dat)
357
327
    #===============================================================================
600
570
                              matrix_element,
601
571
                              fortran_model)
602
572
 
603
 
        filename = 'ngraphs.inc'
604
 
        self.write_ngraphs_file(writers.FortranWriter(filename),
605
 
                            nconfigs)
 
573
        filename = 'maxconfigs.inc'
 
574
        self.write_maxconfigs_file(writers.FortranWriter(filename),
 
575
                max(nconfigs,matrix_element.born_me.get_number_of_amplitudes()))
606
576
 
607
577
#write the wrappers for real ME's
608
578
        filename_me = 'real_me_chooser.f'
627
597
                            writers.FortranWriter(filename),
628
598
                            matrix_element)
629
599
 
 
600
        filename = 'a0Gmuconv.inc'
 
601
        startfroma0 = self.write_a0gmuconv_file(
 
602
                            writers.FortranWriter(filename),
 
603
                            matrix_element)
 
604
 
 
605
        filename = 'rescale_alpha_tagged.f'
 
606
        self.write_rescale_a0gmu_file(
 
607
                            writers.FortranWriter(filename),
 
608
                            startfroma0, matrix_element)
 
609
 
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)
641
 
    
 
621
        
 
622
        filename = 'maxparticles.inc'
 
623
        self.write_maxparticles_file(writers.FortranWriter(filename),
 
624
                                     nexternal)
 
625
        
642
626
        filename = 'pmass.inc'
643
627
        try:
644
628
            self.write_pmass_file(writers.FortranWriter(filename),
720
704
                     'handling_lhe_events.f',
721
705
                     'write_event.f',
722
706
                     'fill_MC_mshell.f',
723
 
                     'maxparticles.inc',
724
 
                     'message.inc',
725
 
                     'initcluster.f',
726
 
                     'cluster.inc',
727
707
                     'cluster.f',
728
 
                     'reweight.f',
729
708
                     'randinit',
730
 
                     'sudakov.inc',
731
 
                     'maxconfigs.inc',
732
709
                     'pineappl_maxproc.inc',
733
710
                     'pineappl_maxproc.h',
734
711
                     'timing_variables.inc',
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)
849
 
 
850
 
#        # Write maxconfigs.inc based on max of ME's/subprocess groups
851
 
 
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())
855
826
        
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())
860
 
 
861
827
        # Touch "done" file
862
828
        os.system('touch %s/done' % os.path.join(self.dir_path,'SubProcesses'))
863
829
        
1096
1062
        writer.writelines(text)
1097
1063
 
1098
1064
 
 
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
 
1068
        tagged photons
 
1069
        """
 
1070
 
 
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
 
1077
 
 
1078
        text = 'logical  startfroma0\nparameter (startfroma0=%s)\n' % bool_dict[startfromalpha0]
 
1079
        writer.writelines(text)
 
1080
        return startfromalpha0
 
1081
 
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
1101
1084
        """
1105
1088
        writer.writelines(text)
1106
1089
 
1107
1090
 
 
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
 
1094
        """
 
1095
 
 
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]
 
1099
 
 
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']]):
 
1103
            to_check = []
 
1104
            expr = '1d0'
 
1105
            conv_pol = '0d0'
 
1106
            conv_fin = '0d0'
 
1107
        
 
1108
        elif startfroma0:
 
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'
 
1115
        else:
 
1116
            to_check = ['mdl_aew', 'mdl_aew0']
 
1117
            base = 'mdl_aew0/mdl_aew'
 
1118
            exp = 'ntag'
 
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'
 
1122
 
 
1123
        replace_dict = {'rescale_fact': expr,
 
1124
                        'virtual_a0Gmu_conv_finite': conv_fin,
 
1125
                        'virtual_a0Gmu_conv_pole': conv_pol}
 
1126
 
 
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)')
 
1133
 
 
1134
        file = open(os.path.join(_file_path, \
 
1135
                          'iolibs/template_files/rescale_alpha_tagged.inc')).read()
 
1136
        file = file % replace_dict
 
1137
        
 
1138
        # Write the file
 
1139
        writer.writelines(file)
 
1140
 
 
1141
 
1108
1142
 
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)
1584
1618
 
1585
1619
 
 
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)
 
1626
 
 
1627
 
 
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)
 
1633
 
 
1634
 
1586
1635
    def write_genps(self, writer, maxproc,ngraphs,ncolor,maxflow, fortran_model):
1587
1636
        """writes the genps.inc file
1588
1637
        """
1808
1857
        if 'sa_symmetry 'not  in self.opt:
1809
1858
            self.opt['sa_symmetry']=False
1810
1859
 
 
1860
 
 
1861
        # Add information relevant for FxFx matching:
 
1862
        # Maximum QCD power in all the contributions
 
1863
        max_qcd_order = 0
 
1864
        for diag in matrix_element.get('diagrams'):
 
1865
            orders = diag.calculate_orders()
 
1866
            if 'QCD' in 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))   
 
1876
 
1811
1877
        # Set lowercase/uppercase Fortran code
1812
1878
        writers.FortranWriter.downcase = False
1813
1879
 
1971
2037
        self.write_born_nhel_file(writers.FortranWriter(filename),
1972
2038
                           born_me, nflows, fortran_model)
1973
2039
 
1974
 
        filename = 'born_ngraphs.inc'
1975
 
        self.write_ngraphs_file(writers.FortranWriter(filename), nconfigs)
1976
 
 
1977
 
        filename = 'ncombs.inc'
1978
 
        self.write_ncombs_file(writers.FortranWriter(filename),
1979
 
                               born_me, fortran_model)
1980
 
 
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))    
2857
2917
            col_lines = []
2858
2918
            pdg_lines = []
2859
2919
            charge_lines = []
 
2920
            tag_lines = []
2860
2921
            fks_j_from_i_lines = []
2861
2922
            split_type_lines = []
2862
2923
            for i, info in enumerate(fks_info_list):
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) ))
 
2934
                tag_lines.append( \
 
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],\
2874
2938
                                                i + 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]
2887
2952
 
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)
2935
3003
 
3226
3294
        writer.writelines(lines_P)
3227
3295
 
3228
3296
    
3229
 
 
3230
3297
    
3231
3298
    #===============================================================================
3232
3299
    # write_dname_file
3692
3759
        writer.writelines(file)
3693
3760
 
3694
3761
        return True
3695
 
 
3696
 
    #===============================================================================
3697
 
    # write_ncombs_file
3698
 
    #===============================================================================
3699
 
    def write_ncombs_file(self, writer, matrix_element, fortran_model):
3700
 
#        #test written
3701
 
        """Write the ncombs.inc file for MadEvent."""
3702
 
    
3703
 
        # Extract number of external particles
3704
 
        (nexternal, ninitial) = matrix_element.get_nexternal_ninitial()
3705
 
    
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))
3709
 
    
3710
 
        # Write the file
3711
 
        writer.writelines(file)
3712
 
   
3713
 
        return True
3714
 
    
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"""
3720
 
 
3721
 
        lines = []
3722
 
 
3723
 
        for iconfig in range(len(s_and_t_channels)):
3724
 
            lines.append("DATA CONFSUB(1,%d)/1/" % \
3725
 
                         (iconfig + 1))
3726
 
 
3727
 
        # Write the file
3728
 
        writer.writelines(lines)
3729
 
 
3730
 
        return True
3731
3762
    
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
3797
 
        get_color=0        
 
3828
        stop 1
 
3829
        return
 
3830
        endif
 
3831
        end
 
3832
        """
 
3833
        
 
3834
        lines+= """
 
3835
        function get_spin(ipdg)
 
3836
        implicit none
 
3837
        integer get_spin, ipdg
 
3838
 
 
3839
        if(ipdg.eq.%d)then
 
3840
        get_spin=%d
 
3841
        return
 
3842
        """ % (particle_ids[0], model.get_particle(particle_ids[0]).get('spin'))
 
3843
 
 
3844
        for part_id in particle_ids[1:]:
 
3845
            lines += """else if(ipdg.eq.%d)then
 
3846
            get_spin=%d
 
3847
            return
 
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
 
3853
            get_spin=-2
 
3854
            return
 
3855
            """ % model.get_first_non_pdg()
 
3856
        lines += """else
 
3857
        write(*,*)'Error: No spin given for pdg ',ipdg
 
3858
        stop 1
3798
3859
        return
3799
3860
        endif
3800
3861
        end