~madteam/mg5amcnlo/series2.0

« back to all changes in this revision

Viewing changes to madgraph/iolibs/export_v4.py

  • Committer: olivier Mattelaer
  • Date: 2015-03-05 00:14:16 UTC
  • mfrom: (258.1.9 2.3)
  • mto: (258.8.1 2.3)
  • mto: This revision was merged to the branch mainline in revision 259.
  • Revision ID: olivier.mattelaer@uclouvain.be-20150305001416-y9mzeykfzwnl9t0j
partial merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
import madgraph.iolibs.helas_call_writers as helas_call_writers
45
45
import madgraph.various.diagram_symmetry as diagram_symmetry
46
46
import madgraph.various.misc as misc
 
47
import madgraph.various.banner as banner_mod
47
48
import madgraph.various.process_checks as process_checks
 
49
import madgraph.loop.loop_diagram_generation as loop_diagram_generation
48
50
import aloha.create_aloha as create_aloha
49
51
import models.import_ufo as import_ufo
50
52
import models.write_param_card as param_writer
51
53
import models.check_param_card as check_param_card
52
54
 
 
55
 
53
56
from madgraph import MadGraph5Error, MG5DIR, ReadWrite
54
57
from madgraph.iolibs.files import cp, ln, mv
55
58
 
78
81
        self.opt = dict(self.default_opt)
79
82
        if opt:
80
83
            self.opt.update(opt)
81
 
 
82
 
 
 
84
        
 
85
        #place holder to pass information to the run_interface
 
86
        self.proc_characteristic = banner_mod.ProcCharacteristic()
 
87
        
 
88
        
 
89
    #===========================================================================
 
90
    # process exporter fortran switch between group and not grouped
 
91
    #===========================================================================
 
92
    def export_processes(self, matrix_elements, fortran_model):
 
93
        """Make the switch between grouped and not grouped output"""
 
94
        
 
95
        calls = 0
 
96
        if isinstance(matrix_elements, group_subprocs.SubProcessGroupList):
 
97
            for (group_number, me_group) in enumerate(matrix_elements):
 
98
                calls = calls + self.generate_subprocess_directory_v4(\
 
99
                                          me_group, fortran_model, group_number)
 
100
        else:
 
101
            for me_number, me in enumerate(matrix_elements.get_matrix_elements()):
 
102
                calls = calls + self.generate_subprocess_directory_v4(\
 
103
                                                   me, fortran_model, me_number)    
 
104
                        
 
105
        return calls    
 
106
        
 
107
 
 
108
 
 
109
    #===========================================================================
 
110
    #  create the run_card 
 
111
    #===========================================================================
 
112
    def create_run_card(self, matrix_elements, history):
 
113
        """ """
 
114
 
 
115
        run_card = banner_mod.RunCard()
 
116
        
 
117
        
 
118
        default=True
 
119
        if isinstance(matrix_elements, group_subprocs.SubProcessGroupList):            
 
120
            processes = [me.get('processes')  for megroup in matrix_elements 
 
121
                                        for me in megroup['matrix_elements']]
 
122
        elif matrix_elements:
 
123
            processes = [me.get('processes') 
 
124
                                 for me in matrix_elements['matrix_elements']]
 
125
        else:
 
126
            default =False
 
127
    
 
128
        if default:
 
129
            run_card.create_default_for_process(self.proc_characteristic, 
 
130
                                            history,
 
131
                                            processes)
 
132
          
 
133
    
 
134
        run_card.write(pjoin(self.dir_path, 'Cards', 'run_card_default.dat'))
 
135
        run_card.write(pjoin(self.dir_path, 'Cards', 'run_card.dat'))
 
136
        
 
137
        
83
138
    #===========================================================================
84
139
    # copy the Template in a new directory.
85
140
    #===========================================================================
87
142
        """create the directory run_name as a copy of the MadEvent
88
143
        Template, and clean the directory
89
144
        """
90
 
        
 
145
 
91
146
        #First copy the full template tree if dir_path doesn't exit
92
147
        if not os.path.isdir(self.dir_path):
93
148
            assert self.mgme_dir, \
100
155
            dir_util.copy_tree(pjoin(self.mgme_dir, 'Template/Common'), 
101
156
                               self.dir_path)
102
157
            # Duplicate run_card and plot_card
103
 
            for card in ['run_card', 'plot_card']:
 
158
            for card in ['plot_card']:
104
159
                try:
105
160
                    shutil.copy(pjoin(self.dir_path, 'Cards',
106
161
                                             card + '.dat'),
167
222
        # add the makefile in Source directory 
168
223
        filename = pjoin(self.dir_path,'Source','makefile')
169
224
        self.write_source_makefile(writers.FileWriter(filename))
 
225
        
 
226
        # add the DiscreteSampler information
 
227
        files.cp(pjoin(MG5DIR,'vendor', 'DiscreteSampler', 'DiscreteSampler.f'), 
 
228
                 pjoin(self.dir_path, 'Source'))
 
229
        files.cp(pjoin(MG5DIR,'vendor', 'DiscreteSampler', 'StringCast.f'), 
 
230
                 pjoin(self.dir_path, 'Source'))
 
231
        
170
232
            
171
233
    #===========================================================================
172
234
    # write a procdef_mg5 (an equivalent of the MG4 proc_card.dat)
215
277
                              online = False, compiler='g77'):
216
278
        """Function to finalize v4 directory, for inheritance.
217
279
        """
 
280
        
 
281
        self.create_run_card(matrix_elements, history)
 
282
        
218
283
        pass
219
 
    
 
284
 
 
285
    #===========================================================================
 
286
    # Create the proc_characteristic file passing information to the run_interface
 
287
    #===========================================================================
 
288
    def create_proc_charac(self, matrix_elements=None, history= "", **opts):
 
289
        
 
290
        self.proc_characteristic.write(pjoin(self.dir_path, 'SubProcesses', 'proc_characteristics'))
 
291
 
220
292
    #===========================================================================
221
293
    # write_matrix_element_v4
222
294
    #===========================================================================
276
348
        
277
349
    def make_source_links(self):
278
350
        """ Create the links from the files in sources """
 
351
 
279
352
        ln(self.dir_path + '/Source/run.inc', self.dir_path + '/SubProcesses', log=False)
280
353
        ln(self.dir_path + '/Source/maxparticles.inc', self.dir_path + '/SubProcesses', log=False)
281
354
        ln(self.dir_path + '/Source/run_config.inc', self.dir_path + '/SubProcesses', log=False)
321
394
        pass
322
395
 
323
396
    #===========================================================================
 
397
    # get_source_libraries_list
 
398
    #===========================================================================
 
399
    def get_source_libraries_list(self):
 
400
        """ Returns the list of libraries to be compiling when compiling the
 
401
        SOURCE directory. It is different for loop_induced processes and 
 
402
        also depends on the value of the 'output_dependencies' option"""
 
403
        
 
404
        return ['$(LIBDIR)libdhelas.$(libext)',
 
405
                '$(LIBDIR)libpdf.$(libext)',
 
406
                '$(LIBDIR)libmodel.$(libext)',
 
407
                '$(LIBDIR)libcernlib.$(libext)']
 
408
 
 
409
    #===========================================================================
324
410
    # write_source_makefile
325
411
    #===========================================================================
326
412
    def write_source_makefile(self, writer):
327
413
        """Write the nexternal.inc file for MG4"""
328
414
 
329
 
 
330
415
        path = pjoin(_file_path,'iolibs','template_files','madevent_makefile_source')
331
 
        set_of_lib = '$(LIBRARIES) $(LIBDIR)libdhelas.$(libext) $(LIBDIR)libpdf.$(libext) $(LIBDIR)libmodel.$(libext) $(LIBDIR)libcernlib.$(libext)'
 
416
        set_of_lib = ' '.join(['$(LIBRARIES)']+self.get_source_libraries_list())
332
417
        if self.opt['model'] == 'mssm' or self.opt['model'].startswith('mssm-'):
333
418
            model_line='''$(LIBDIR)libmodel.$(libext): MODEL param_card.inc\n\tcd MODEL; make
334
419
MODEL/MG5_param.dat: ../Cards/param_card.dat\n\t../bin/madevent treatcards param
576
661
 
577
662
        return True
578
663
 
 
664
 
 
665
 
 
666
 
 
667
 
579
668
    #===========================================================================
580
669
    # Routines to output UFO models in MG4 format
581
670
    #===========================================================================
590
679
 
591
680
        # create the MODEL
592
681
        write_dir=pjoin(self.dir_path, 'Source', 'MODEL')
593
 
        model_builder = UFO_model_to_mg4(model, write_dir, self.opt)
 
682
        model_builder = UFO_model_to_mg4(model, write_dir, self.opt + self.proc_characteristic)
594
683
        model_builder.build(wanted_couplings)
595
684
 
596
685
        # Backup the loop mode, because it can be changed in what follows.
799
888
 
800
889
        # Only want to include leading color flows, so find max_Nc
801
890
        color_basis = matrix_element.get('color_basis')
802
 
        max_Nc = max(sum([[v[4] for v in val] for val in color_basis.values()],
803
 
                         []))
 
891
        
 
892
        # We don't want to include the power of Nc's which come from the potential
 
893
        # loop color trace (i.e. in the case of a closed fermion loop for example)
 
894
        # so we subtract it here when computing max_Nc
 
895
        max_Nc = max(sum([[(v[4]-v[5]) for v in val] for val in 
 
896
                                                      color_basis.values()],[]))
804
897
 
805
898
        # Crate dictionary between diagram number and JAMP number
806
899
        diag_jamp = {}
807
900
        for ijamp, col_basis_elem in \
808
901
                enumerate(sorted(matrix_element.get('color_basis').keys())):
809
902
            for diag_tuple in matrix_element.get('color_basis')[col_basis_elem]:
810
 
                # Only use color flows with Nc == max_Nc
811
 
                if diag_tuple[4] == max_Nc:
 
903
                # Only use color flows with Nc == max_Nc. However, notice that
 
904
                # we don't want to include the Nc power coming from the loop
 
905
                # in this counting.
 
906
                if (diag_tuple[4]-diag_tuple[5]) == max_Nc:
812
907
                    diag_num = diag_tuple[0] + 1
813
908
                    # Add this JAMP number to this diag_num
814
909
                    diag_jamp[diag_num] = diag_jamp.setdefault(diag_num, []) + \
815
910
                                          [ijamp+1]
816
911
 
817
912
        colamps = ijamp + 1
818
 
 
819
913
        for iconfig, num_diag in enumerate(mapconfigs):        
820
914
            if num_diag == 0:
821
915
                continue
822
916
 
823
917
            # List of True or False 
824
 
            bool_list = [(i + 1 in diag_jamp[num_diag]) for i in \
825
 
                              range(colamps)]
 
918
            bool_list = [(i + 1 in diag_jamp[num_diag]) for i in range(colamps)]
826
919
            # Add line
827
920
            ret_list.append("DATA(icolamp(i,%d,%d),i=1,%d)/%s/" % \
828
921
                                (iconfig+1, num_matrix_element, colamps,
1629
1722
    #=========================================================================== 
1630
1723
    def export_model_files(self, model_path):
1631
1724
        """export the model dependent files for V4 model"""
1632
 
        
 
1725
 
1633
1726
        super(ProcessExporterFortranSA,self).export_model_files(model_path)
1634
1727
        # Add the routine update_as_param in v4 model 
1635
1728
        # This is a function created in the UFO 
1671
1764
        if history and os.path.isdir(pjoin(self.dir_path, 'Cards')):
1672
1765
            output_file = pjoin(self.dir_path, 'Cards', 'proc_card_mg5.dat')
1673
1766
            history.write(output_file)
 
1767
        
 
1768
        ProcessExporterFortran.finalize_v4_directory(self, matrix_elements, history, makejpg, online, compiler)
1674
1769
 
1675
1770
    def compiler_choice(self, compiler):
1676
1771
        """ Different daughter classes might want different compilers.
1811
1906
    def write_source_makefile(self, writer):
1812
1907
        """Write the nexternal.inc file for MG4"""
1813
1908
 
1814
 
 
1815
1909
        path = pjoin(_file_path,'iolibs','template_files','madevent_makefile_source')
1816
1910
        set_of_lib = '$(LIBDIR)libdhelas.$(libext) $(LIBDIR)libmodel.$(libext)'
1817
1911
        model_line='''$(LIBDIR)libmodel.$(libext): MODEL\n\t cd MODEL; make\n'''
1828
1922
        """Export a matrix element to a matrix.f file in MG4 standalone format
1829
1923
        if write is on False, just return the replace_dict and not write anything."""
1830
1924
 
 
1925
 
1831
1926
        if not matrix_element.get('processes') or \
1832
1927
               not matrix_element.get('diagrams'):
1833
1928
            return 0
1834
1929
 
1835
1930
        if not isinstance(writer, writers.FortranWriter):
1836
1931
            raise writers.FortranWriter.FortranWriterError(\
1837
 
                "writer not FortranWriter")
 
1932
                "writer not FortranWriter but %s" % type(writer))
1838
1933
            
1839
1934
        if not self.opt.has_key('sa_symmetry'):
1840
1935
            self.opt['sa_symmetry']=False
1939
2034
            # The original driver still works and is compiled with 'make' while
1940
2035
            # the splitOrders one is compiled with 'make check_sa_born_splitOrders'
1941
2036
            check_sa_writer=writers.FortranWriter('check_sa_born_splitOrders.f')
1942
 
            self.write_check_sa_splitOrders(\
1943
 
                                    squared_orders,split_orders,check_sa_writer)
 
2037
            self.write_check_sa_splitOrders(squared_orders,split_orders,
 
2038
              nexternal,ninitial,proc_prefix,check_sa_writer)
1944
2039
 
1945
2040
        if write:
1946
2041
            writers.FortranWriter('nsqso_born.inc').writelines(
1986
2081
            replace_dict['return_value'] = len(filter(lambda call: call.find('#') != 0, helas_calls))
1987
2082
            return replace_dict # for subclass update
1988
2083
 
1989
 
    def write_check_sa_splitOrders(self,squared_orders, split_orders, writer):
 
2084
    def write_check_sa_splitOrders(self,squared_orders, split_orders, nexternal,
 
2085
                                                nincoming, proc_prefix, writer):
1990
2086
        """ Write out a more advanced version of the check_sa drivers that
1991
2087
        individually returns the matrix element for each contributing squared
1992
2088
        order."""
2004
2100
        printout_sq_orders='\n'.join(printout_sq_orders)
2005
2101
        writer.writelines(check_sa_content%{\
2006
2102
                                    'printout_sqorders':printout_sq_orders, 
2007
 
                                    'nSplitOrders':len(squared_orders)})
 
2103
                                    'nSplitOrders':len(squared_orders),
 
2104
                                    'nexternal':nexternal,
 
2105
                                    'nincoming':nincoming,
 
2106
                                    'proc_prefix':proc_prefix})
2008
2107
 
2009
2108
 
2010
2109
class ProcessExporterFortranMatchBox(ProcessExporterFortranSA):
2224
2323
        cp(_file_path+'/__init__.py', self.dir_path+'/bin/internal/__init__.py')
2225
2324
        cp(_file_path+'/various/lhe_parser.py', 
2226
2325
                                self.dir_path+'/bin/internal/lhe_parser.py')         
2227
 
        #cp(_file_path+'/various/gen_crossxhtml.py', 
2228
 
        #                        self.dir_path+'/bin/internal/gen_crossxhtml.py')                
 
2326
 
2229
2327
        cp(_file_path+'/various/banner.py', 
2230
2328
                                   self.dir_path+'/bin/internal/banner.py')
2231
2329
        cp(_file_path+'/various/cluster.py', 
2232
2330
                                       self.dir_path+'/bin/internal/cluster.py') 
2233
 
        #cp(_file_path+'/various/sum_html.py', 
2234
 
        #                               self.dir_path+'/bin/internal/sum_html.py') 
2235
 
        #cp(_file_path+'/various/combine_runs.py', 
2236
 
        #                               self.dir_path+'/bin/internal/combine_runs.py')
2237
2331
        
2238
2332
        # logging configuration
2239
2333
        cp(_file_path+'/interface/.mg5_logging.conf', 
2327
2421
    def finalize_v4_directory(self, matrix_elements, history, makejpg = False,
2328
2422
                              online = False, compiler='g77'):
2329
2423
        """Finalize Standalone MG4 directory by generation proc_card_mg5.dat"""
2330
 
        
 
2424
 
 
2425
        #proc_charac
 
2426
        self.create_proc_charac()
 
2427
 
2331
2428
        # Write maxparticles.inc based on max of ME's/subprocess groups
2332
2429
        filename = pjoin(self.dir_path,'Source','maxparticles.inc')
2333
2430
        self.write_maxparticles_file(writers.FortranWriter(filename),
2345
2442
            output_file = os.path.join(self.dir_path, 'Cards', 'proc_card_mg5.dat')
2346
2443
            history.write(output_file)
2347
2444
 
 
2445
        ProcessExporterFortran.finalize_v4_directory(self, matrix_elements, history, makejpg, online, compiler)
 
2446
 
 
2447
 
 
2448
    #===========================================================================
 
2449
    # create the run_card for MW
 
2450
    #=========================================================================== 
 
2451
    def create_run_card(self, matrix_elements, history):
 
2452
        """ """
 
2453
 
 
2454
        run_card = banner_mod.RunCard()
 
2455
    
 
2456
        # pass to default for MW
 
2457
        run_card["run_tag"] = "\'not_use\'"
 
2458
        run_card["fixed_ren_scale"] = "T"
 
2459
        run_card["fixed_fac_scale"] = "T"
 
2460
        run_card.remove_all_cut()
 
2461
                  
 
2462
        run_card.write(pjoin(self.dir_path, 'Cards', 'run_card_default.dat'),
 
2463
                       template=pjoin(MG5DIR, 'Template', 'MadWeight', 'Cards', 'run_card.dat'),
 
2464
                       python_template=True)
 
2465
        run_card.write(pjoin(self.dir_path, 'Cards', 'run_card.dat'),
 
2466
                       template=pjoin(MG5DIR, 'Template', 'MadWeight', 'Cards', 'run_card.dat'),
 
2467
                       python_template=True)
 
2468
 
 
2469
 
2348
2470
    #===========================================================================
2349
2471
    # export model files
2350
2472
    #=========================================================================== 
2876
2998
        # Add the symmetry.f 
2877
2999
        filename = pjoin(self.dir_path,'SubProcesses','symmetry.f')
2878
3000
        self.write_symmetry(writers.FortranWriter(filename))
2879
 
        # Add the driver.f 
2880
 
        filename = pjoin(self.dir_path,'SubProcesses','driver.f')
2881
 
        self.write_driver(writers.FortranWriter(filename))
2882
3001
        #
2883
3002
        filename = pjoin(self.dir_path,'SubProcesses','addmothers.f')
2884
3003
        self.write_addmothers(writers.FortranWriter(filename))
2911
3030
        #model file                        
2912
3031
        cp(_file_path+'../models/check_param_card.py', 
2913
3032
                              self.dir_path+'/bin/internal/check_param_card.py')   
2914
 
                
 
3033
        
 
3034
        #copy all the file present in madevent directory
 
3035
        for name in os.listdir(pjoin(_file_path, 'madevent')):
 
3036
            if name not in ['__init__.py'] and name.endswith('.py'):
 
3037
                cp(_file_path+'/madevent/'+name, self.dir_path+'/bin/internal/')
 
3038
        
2915
3039
        #madevent file
2916
3040
        cp(_file_path+'/__init__.py', self.dir_path+'/bin/internal/__init__.py')
2917
3041
        cp(_file_path+'/various/lhe_parser.py', 
2918
 
                                self.dir_path+'/bin/internal/lhe_parser.py')         
2919
 
        cp(_file_path+'/various/gen_crossxhtml.py', 
2920
 
                                self.dir_path+'/bin/internal/gen_crossxhtml.py')                
 
3042
                                self.dir_path+'/bin/internal/lhe_parser.py')                        
2921
3043
        cp(_file_path+'/various/banner.py', 
2922
3044
                                   self.dir_path+'/bin/internal/banner.py')
2923
3045
        cp(_file_path+'/various/cluster.py', 
2924
3046
                                       self.dir_path+'/bin/internal/cluster.py') 
2925
 
        cp(_file_path+'/various/sum_html.py', 
2926
 
                                       self.dir_path+'/bin/internal/sum_html.py') 
2927
 
        cp(_file_path+'/various/combine_runs.py', 
 
3047
        cp(_file_path+'/madevent/combine_runs.py', 
2928
3048
                                       self.dir_path+'/bin/internal/combine_runs.py')
2929
3049
        # logging configuration
2930
3050
        cp(_file_path+'/interface/.mg5_logging.conf', 
2968
3088
    #=========================================================================== 
2969
3089
    def export_model_files(self, model_path):
2970
3090
        """export the model dependent files"""
2971
 
        
 
3091
 
2972
3092
        super(ProcessExporterFortranME,self).export_model_files(model_path)
2973
3093
        
2974
3094
        # Add the routine update_as_param in v4 model 
2987
3107
        filename = pjoin(self.dir_path,'SubProcesses','symmetry.f')
2988
3108
        self.write_symmetry(writers.FortranWriter(filename), v5=False)
2989
3109
        
2990
 
        # Add the driver.f 
2991
 
        filename = pjoin(self.dir_path,'SubProcesses','driver.f')
2992
 
        self.write_driver(writers.FortranWriter(filename), v5=False)
2993
 
        
2994
3110
        # Modify setrun.f
2995
3111
        text = open(pjoin(self.dir_path,'Source','setrun.f')).read()
2996
3112
        text = text.replace('call setpara(param_card_name)', 'call setpara(param_card_name, .true.)')
3039
3155
        # Extract number of external particles
3040
3156
        (nexternal, ninitial) = matrix_element.get_nexternal_ninitial()
3041
3157
 
 
3158
        # Add the driver.f 
 
3159
        ncomb = matrix_element.get_helicity_combinations()
 
3160
        filename = pjoin(Ppath,'driver.f')
 
3161
        self.write_driver(writers.FortranWriter(filename),ncomb,n_grouped_proc=1)
 
3162
 
3042
3163
        # Create the matrix.f file, auto_dsig.f file and all inc files
3043
3164
        filename = pjoin(Ppath, 'matrix.f')
3044
3165
        calls, ncolor = \
3045
3166
               self.write_matrix_element_v4(writers.FortranWriter(filename),
3046
 
                                                matrix_element,
3047
 
                                                fortran_model)
 
3167
                      matrix_element, fortran_model, subproc_number = me_number)
3048
3168
 
3049
3169
        filename = pjoin(Ppath, 'auto_dsig.f')
3050
3170
        self.write_auto_dsig_file(writers.FortranWriter(filename),
3144
3264
                     matrix_element.get('processes')[0].nice_string())
3145
3265
        plot.draw()
3146
3266
 
3147
 
        #import genps.inc and maxconfigs.inc into Subprocesses
3148
 
        ln(self.dir_path + '/Source/genps.inc', self.dir_path + '/SubProcesses', log=False)
3149
 
        ln(self.dir_path + '/Source/maxconfigs.inc', self.dir_path + '/SubProcesses', log=False)
3150
 
 
3151
 
        linkfiles = ['addmothers.f',
3152
 
                     'cluster.f',
3153
 
                     'cluster.inc',
3154
 
                     'coupl.inc',
3155
 
                     'cuts.f',
3156
 
                     'cuts.inc',
3157
 
                     'driver.f',
3158
 
                     'genps.f',
3159
 
                     'genps.inc',
3160
 
                     'idenparts.f',
3161
 
                     'initcluster.f',
3162
 
                     'makefile',
3163
 
                     'message.inc',
3164
 
                     'myamp.f',
3165
 
                     'reweight.f',
3166
 
                     'run.inc',
3167
 
                     'maxconfigs.inc',
3168
 
                     'maxparticles.inc',
3169
 
                     'run_config.inc',
3170
 
                     'setcuts.f',
3171
 
                     'setscales.f',
3172
 
                     'sudakov.inc',
3173
 
                     'symmetry.f',
3174
 
                     'unwgt.f']
3175
 
 
3176
 
        for file in linkfiles:
3177
 
            ln('../' + file , cwd=Ppath)
 
3267
        self.link_files_in_SubProcess(Ppath)
3178
3268
 
3179
3269
        #import nexternal/leshouche in Source
3180
3270
        ln(pjoin(Ppath,'nexternal.inc'), pjoin(self.dir_path,'Source'), log=False)
3200
3290
            calls = 0
3201
3291
        return calls
3202
3292
 
 
3293
    def link_files_in_SubProcess(self, Ppath):
 
3294
        """ Create the necessary links in the P* directory path Ppath"""
 
3295
        
 
3296
        #import genps.inc and maxconfigs.inc into Subprocesses
 
3297
        ln(self.dir_path + '/Source/genps.inc', 
 
3298
                                     self.dir_path + '/SubProcesses', log=False)
 
3299
        ln(self.dir_path + '/Source/maxconfigs.inc',
 
3300
                                     self.dir_path + '/SubProcesses', log=False)
 
3301
 
 
3302
        linkfiles = ['addmothers.f',
 
3303
                     'cluster.f',
 
3304
                     'cluster.inc',
 
3305
                     'coupl.inc',
 
3306
                     'cuts.f',
 
3307
                     'cuts.inc',
 
3308
                     'genps.f',
 
3309
                     'genps.inc',
 
3310
                     'idenparts.f',
 
3311
                     'initcluster.f',
 
3312
                     'makefile',
 
3313
                     'message.inc',
 
3314
                     'myamp.f',
 
3315
                     'reweight.f',
 
3316
                     'run.inc',
 
3317
                     'maxconfigs.inc',
 
3318
                     'maxparticles.inc',
 
3319
                     'run_config.inc',
 
3320
                     'setcuts.f',
 
3321
                     'setscales.f',
 
3322
                     'sudakov.inc',
 
3323
                     'symmetry.f',
 
3324
                     'unwgt.f']
 
3325
 
 
3326
        for file in linkfiles:
 
3327
            ln('../' + file , cwd=Ppath)    
 
3328
 
3203
3329
    def finalize_v4_directory(self, matrix_elements, history, makejpg = False,
3204
3330
                              online = False, compiler='gfortran'):
3205
3331
        """Finalize ME v4 directory by creating jpeg diagrams, html
3206
3332
        pages,proc_card_mg5.dat and madevent.tar.gz."""
3207
 
      
 
3333
 
 
3334
        # indicate that the output type is not grouped
 
3335
        if  not isinstance(self, ProcessExporterFortranMEGroup):
 
3336
            self.proc_characteristic['grouped_matrix'] = False
 
3337
 
3208
3338
        modelname = self.opt['model']
3209
3339
        if modelname == 'mssm' or modelname.startswith('mssm-'):
3210
3340
            param_card = pjoin(self.dir_path, 'Cards','param_card.dat')
3267
3397
        if online:
3268
3398
            nb_channel = obj.rep_rule['nb_gen_diag']
3269
3399
            open(pjoin(self.dir_path, 'Online'),'w').write(str(nb_channel))
 
3400
        #add the information to proc_charac
 
3401
        self.proc_characteristic['nb_channel'] = obj.rep_rule['nb_gen_diag']
3270
3402
        
3271
3403
        # Write command history as proc_card_mg5
3272
3404
        if os.path.isdir(pjoin(self.dir_path,'Cards')):
3276
3408
        misc.call([pjoin(self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')],
3277
3409
                        stdout = devnull)
3278
3410
 
 
3411
        #crate the proc_characteristic file 
 
3412
        self.create_proc_charac(matrix_elements, history)
 
3413
 
 
3414
        # create the run_card
 
3415
        ProcessExporterFortran.finalize_v4_directory(self, matrix_elements, history, makejpg, online, compiler)
 
3416
 
 
3417
        misc.call([pjoin(self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')],
 
3418
                        stdout = devnull)
 
3419
        
3279
3420
        # Run "make" to generate madevent.tar.gz file
3280
3421
        if os.path.exists(pjoin(self.dir_path,'SubProcesses', 'subproc.mg')):
3281
3422
            if os.path.exists(pjoin(self.dir_path,'madevent.tar.gz')):
3283
3424
            misc.call([os.path.join(self.dir_path, 'bin', 'internal', 'make_madevent_tar')],
3284
3425
                        stdout = devnull, cwd=self.dir_path)
3285
3426
 
3286
 
        misc.call([pjoin(self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')],
3287
 
                        stdout = devnull)
 
3427
 
 
3428
 
 
3429
 
 
3430
 
 
3431
 
 
3432
 
3288
3433
 
3289
3434
        #return to the initial dir
3290
3435
        #os.chdir(old_pos)               
3293
3438
    # write_matrix_element_v4
3294
3439
    #===========================================================================
3295
3440
    def write_matrix_element_v4(self, writer, matrix_element, fortran_model,
3296
 
                                proc_id = "", config_map = []):
 
3441
                           proc_id = "", config_map = [], subproc_number = ""):
3297
3442
        """Export a matrix element to a matrix.f file in MG4 madevent format"""
3298
3443
 
3299
3444
        if not matrix_element.get('processes') or \
3419
3564
                [amp_order[0] for amp_order in amp_orders],'AMPSPLITORDERS')
3420
3565
        sqamp_so = self.get_split_orders_lines(squared_orders,'SQSPLITORDERS')
3421
3566
        replace_dict['ampsplitorders']='\n'.join(amp_so)
3422
 
        replace_dict['sqsplitorders']='\n'.join(sqamp_so)         
 
3567
        replace_dict['sqsplitorders']='\n'.join(sqamp_so)
 
3568
        
 
3569
        
3423
3570
        # Extract JAMP lines
3424
3571
        # If no split_orders then artificiall add one entry called 'ALL_ORDERS'
3425
3572
        jamp_lines = self.get_JAMP_lines_split_order(\
3429
3576
 
3430
3577
        file = open(pjoin(_file_path, \
3431
3578
                          'iolibs/template_files/%s' % self.matrix_file)).read()
 
3579
            
3432
3580
        file = file % replace_dict
3433
3581
        
3434
3582
        # Add the split orders helper functions.
3452
3600
            return 0
3453
3601
 
3454
3602
        nexternal, ninitial = matrix_element.get_nexternal_ninitial()
 
3603
        self.proc_characteristic['ninitial'] = ninitial
 
3604
        self.proc_characteristic['nexternal'] = max(self.proc_characteristic['nexternal'], nexternal)
3455
3605
 
3456
3606
        if ninitial < 1 or ninitial > 2:
3457
3607
            raise writers.FortranWriter.FortranWriterError, \
3505
3655
            replace_dict['define_subdiag_lines'] = ""
3506
3656
            replace_dict['cutsdone'] = "      cutsdone=.false.\n       cutspassed=.false."
3507
3657
 
 
3658
        if not isinstance(self, ProcessExporterFortranMEGroup):
 
3659
            ncomb=matrix_element.get_helicity_combinations()
 
3660
            replace_dict['read_write_good_hel'] = self.read_write_good_hel(ncomb)
 
3661
        else:
 
3662
            replace_dict['read_write_good_hel'] = ""
 
3663
        
 
3664
        
 
3665
 
3508
3666
        file = open(pjoin(_file_path, \
3509
3667
                          'iolibs/template_files/auto_dsig_v4.inc')).read()
3510
3668
        file = file % replace_dict
3511
3669
 
3512
3670
        # Write the file
3513
 
        writer.writelines(file)
 
3671
        writer.writelines(file, context={'read_write_good_hel':True})
3514
3672
 
3515
3673
    #===========================================================================
3516
3674
    # write_coloramps_file
3624
3782
        writer.writelines(lines)
3625
3783
 
3626
3784
        return True
3627
 
 
3628
 
 
 
3785
    
 
3786
    #===========================================================================
 
3787
    # read_write_good_hel
 
3788
    #===========================================================================
 
3789
    def read_write_good_hel(self, ncomb):
 
3790
        """return the code to read/write the good_hel common_block"""    
 
3791
 
 
3792
        convert = {'ncomb' : ncomb}
 
3793
        output = """
 
3794
        subroutine write_good_hel(stream_id)
 
3795
        implicit none
 
3796
        integer stream_id
 
3797
        INTEGER                 NCOMB
 
3798
        PARAMETER (             NCOMB=%(ncomb)d)
 
3799
        LOGICAL GOODHEL(NCOMB)
 
3800
        INTEGER NTRY
 
3801
        common/BLOCK_GOODHEL/NTRY,GOODHEL
 
3802
        write(stream_id,*) GOODHEL
 
3803
        return
 
3804
        end
 
3805
        
 
3806
        
 
3807
        subroutine read_good_hel(stream_id)
 
3808
        implicit none
 
3809
        include 'genps.inc'
 
3810
        integer stream_id
 
3811
        INTEGER                 NCOMB
 
3812
        PARAMETER (             NCOMB=%(ncomb)d)
 
3813
        LOGICAL GOODHEL(NCOMB)
 
3814
        INTEGER NTRY
 
3815
        common/BLOCK_GOODHEL/NTRY,GOODHEL
 
3816
        read(stream_id,*) GOODHEL
 
3817
        NTRY = MAXTRIES + 1
 
3818
        return
 
3819
        end 
 
3820
        
 
3821
        subroutine init_good_hel()
 
3822
        implicit none
 
3823
        INTEGER                 NCOMB
 
3824
        PARAMETER (             NCOMB=%(ncomb)d)
 
3825
        LOGICAL GOODHEL(NCOMB)        
 
3826
        INTEGER NTRY
 
3827
        INTEGER I
 
3828
        
 
3829
        do i=1,NCOMB
 
3830
            GOODHEL(I) = .false.
 
3831
        enddo
 
3832
        NTRY = 0
 
3833
        end
 
3834
        
 
3835
        integer function get_maxsproc()
 
3836
        implicit none
 
3837
        get_maxsproc = 1
 
3838
        return 
 
3839
        end
 
3840
        
 
3841
        """ % convert
 
3842
        
 
3843
        return output
3629
3844
                                
3630
3845
    #===========================================================================
3631
3846
    # write_config_subproc_map_file
3669
3884
    def write_run_config_file(self, writer):
3670
3885
        """Write the run_configs.inc file for MadEvent"""
3671
3886
 
3672
 
        path = pjoin(_file_path,'iolibs','template_files','madevent_run_config.inc') 
3673
 
        text = open(path).read() % {'chanperjob':'5'} 
 
3887
        path = pjoin(_file_path,'iolibs','template_files','madevent_run_config.inc')
 
3888
        
 
3889
        if self.proc_characteristic['loop_induced']:
 
3890
            job_per_chan = 1
 
3891
        else: 
 
3892
           job_per_chan = 5
 
3893
        text = open(path).read() % {'chanperjob': job_per_chan} 
3674
3894
        writer.write(text)
3675
3895
        return True
3676
3896
 
3851
4071
    #===========================================================================
3852
4072
    # write_driver
3853
4073
    #===========================================================================
3854
 
    def write_driver(self, writer, v5=True):
 
4074
    def write_driver(self, writer, ncomb, n_grouped_proc, v5=True):
3855
4075
        """Write the SubProcess/driver.f file for MG4"""
3856
4076
 
3857
4077
        path = pjoin(_file_path,'iolibs','template_files','madevent_driver.f')
3859
4079
        if self.model_name == 'mssm' or self.model_name.startswith('mssm-'):
3860
4080
            card = 'Source/MODEL/MG5_param.dat'
3861
4081
        else:
3862
 
            card = 'param_card.dat' 
 
4082
            card = 'param_card.dat'
 
4083
        # Requiring each helicity configuration to be probed by 10 points for 
 
4084
        # matrix element before using the resulting grid for MC over helicity
 
4085
        # sampling.
 
4086
        # We multiply this by 2 because each grouped subprocess is called at most
 
4087
        # twice for each IMIRROR.
 
4088
        replace_dict = {'param_card_name':card, 
 
4089
                        'ncomb':ncomb,
 
4090
                        'hel_init_points':n_grouped_proc*10*2}
3863
4091
        if v5:
3864
 
            text = open(path).read() % {'param_card_name':card, 'secondparam':''} 
 
4092
            replace_dict['secondparam']=',.true.'
3865
4093
        else:
3866
 
            text = open(path).read() % {'param_card_name':card, 
3867
 
                                        'secondparam': ',.true.'} 
 
4094
            replace_dict['secondparam']=''            
 
4095
 
 
4096
        text = open(path).read() % replace_dict
 
4097
 
3868
4098
        writer.write(text)
3869
4099
        
3870
4100
        return True
4166
4396
 
4167
4397
        matrix_elements = subproc_group.get('matrix_elements')
4168
4398
 
 
4399
        # Add the driver.f, all grouped ME's must share the same number of 
 
4400
        # helicity configuration
 
4401
        ncomb = matrix_elements[0].get_helicity_combinations()
 
4402
        for me in matrix_elements[1:]:
 
4403
            if ncomb!=me.get_helicity_combinations():
 
4404
                raise MadGraph5Error, "All grouped processes must share the "+\
 
4405
                                       "same number of helicity configurations."                
 
4406
 
 
4407
        filename = 'driver.f'
 
4408
        self.write_driver(writers.FortranWriter(filename),ncomb,
 
4409
                                  n_grouped_proc=len(matrix_elements), v5=False)
 
4410
 
4169
4411
        for ime, matrix_element in \
4170
4412
                enumerate(matrix_elements):
4171
4413
            filename = 'matrix%d.f' % (ime+1)
4172
4414
            calls, ncolor = \
4173
4415
               self.write_matrix_element_v4(writers.FortranWriter(filename), 
4174
 
                                                matrix_element,
4175
 
                                                fortran_model,
4176
 
                                                str(ime+1),
4177
 
                                                subproc_group.get('diagram_maps')[\
4178
 
                                                                              ime])
 
4416
                            matrix_element,
 
4417
                            fortran_model,
 
4418
                            proc_id=str(ime+1),
 
4419
                            config_map=subproc_group.get('diagram_maps')[ime],
 
4420
                            subproc_number=group_number)
4179
4421
 
4180
4422
            filename = 'auto_dsig%d.f' % (ime+1)
4181
4423
            self.write_auto_dsig_file(writers.FortranWriter(filename),
4206
4448
        # Generate a list of diagrams corresponding to each configuration
4207
4449
        # [[d1, d2, ...,dn],...] where 1,2,...,n is the subprocess number
4208
4450
        # If a subprocess has no diagrams for this config, the number is 0
4209
 
 
4210
4451
        subproc_diagrams_for_config = subproc_group.get('diagrams_for_configs')
4211
4452
 
4212
4453
        filename = 'auto_dsig.f'
4313
4554
        # Generate jpgs -> pass in make_html
4314
4555
        #os.system(pjoin('..', '..', 'bin', 'gen_jpeg-pl'))
4315
4556
 
4316
 
        #import genps.inc and maxconfigs.inc into
4317
 
        ln(self.dir_path + '/Source/genps.inc', self.dir_path + '/SubProcesses', log=False)
4318
 
        ln(self.dir_path + '/Source/maxconfigs.inc', self.dir_path + '/SubProcesses', log=False)
4319
 
 
4320
 
        linkfiles = ['addmothers.f',
4321
 
                     'cluster.f',
4322
 
                     'cluster.inc',
4323
 
                     'coupl.inc',
4324
 
                     'cuts.f',
4325
 
                     'cuts.inc',
4326
 
                     'driver.f',
4327
 
                     'genps.f',
4328
 
                     'genps.inc',
4329
 
                     'idenparts.f',
4330
 
                     'initcluster.f',
4331
 
                     'makefile',
4332
 
                     'message.inc',
4333
 
                     'myamp.f',
4334
 
                     'reweight.f',
4335
 
                     'run.inc',
4336
 
                     'maxconfigs.inc',
4337
 
                     'maxparticles.inc',
4338
 
                     'run_config.inc',
4339
 
                     'setcuts.f',
4340
 
                     'setscales.f',
4341
 
                     'sudakov.inc',
4342
 
                     'symmetry.f',
4343
 
                     'unwgt.f']
4344
 
 
4345
 
        for file in linkfiles:
4346
 
            ln('../' + file , '.')
 
4557
        self.link_files_in_SubProcess(pjoin(pathdir,subprocdir))
4347
4558
 
4348
4559
        #import nexternal/leshouch in Source
4349
4560
        ln('nexternal.inc', '../../Source', log=False)
4358
4569
        files.append_to_file(filename,
4359
4570
                             self.write_subproc,
4360
4571
                             subprocdir)
4361
 
        
4362
 
        # Generate info page
4363
 
        gen_infohtml.make_info_html(os.path.pardir)
4364
 
        
 
4572
                
4365
4573
        # Return to original dir
4366
4574
        os.chdir(cwd)
4367
4575
 
4409
4617
                 "proc": matrix_elements[iproc].get('processes')[0].base_string()})
4410
4618
        replace_dict['call_dsig_proc_lines'] = "\n".join(call_dsig_proc_lines)
4411
4619
 
 
4620
        ncomb=matrix_elements[0].get_helicity_combinations()
 
4621
        replace_dict['read_write_good_hel'] = self.read_write_good_hel(ncomb)
 
4622
        
4412
4623
        file = open(pjoin(_file_path, \
4413
4624
                       'iolibs/template_files/super_auto_dsig_group_v4.inc')).read()
4414
4625
        file = file % replace_dict
4504
4715
        return True
4505
4716
 
4506
4717
    #===========================================================================
 
4718
    # read_write_good_hel
 
4719
    #===========================================================================
 
4720
    def read_write_good_hel(self, ncomb):
 
4721
        """return the code to read/write the good_hel common_block"""    
 
4722
 
 
4723
        convert = {'ncomb' : ncomb}
 
4724
 
 
4725
        output = """
 
4726
        subroutine write_good_hel(stream_id)
 
4727
        implicit none
 
4728
        integer stream_id
 
4729
        INTEGER                 NCOMB
 
4730
        PARAMETER (             NCOMB=%(ncomb)d)
 
4731
        LOGICAL GOODHEL(NCOMB, 2)
 
4732
        INTEGER NTRY(2)
 
4733
        common/BLOCK_GOODHEL/NTRY,GOODHEL
 
4734
        write(stream_id,*) GOODHEL
 
4735
        return
 
4736
        end
 
4737
        
 
4738
        
 
4739
        subroutine read_good_hel(stream_id)
 
4740
        implicit none
 
4741
        include 'genps.inc'
 
4742
        integer stream_id
 
4743
        INTEGER                 NCOMB
 
4744
        PARAMETER (             NCOMB=%(ncomb)d)
 
4745
        LOGICAL GOODHEL(NCOMB, 2)
 
4746
        INTEGER NTRY(2)
 
4747
        common/BLOCK_GOODHEL/NTRY,GOODHEL
 
4748
        read(stream_id,*) GOODHEL
 
4749
        NTRY(1) = MAXTRIES + 1
 
4750
        NTRY(2) = MAXTRIES + 1
 
4751
        return
 
4752
        end 
 
4753
        
 
4754
        subroutine init_good_hel()
 
4755
        implicit none
 
4756
        INTEGER                 NCOMB
 
4757
        PARAMETER (             NCOMB=%(ncomb)d)
 
4758
        LOGICAL GOODHEL(NCOMB, 2)        
 
4759
        INTEGER NTRY(2)
 
4760
        INTEGER I
 
4761
        
 
4762
        do i=1,NCOMB
 
4763
            GOODHEL(I,1) = .false.
 
4764
            GOODHEL(I,2) = .false.
 
4765
        enddo
 
4766
        NTRY(1) = 0
 
4767
        NTRY(2) = 0
 
4768
        end
 
4769
        
 
4770
        integer function get_maxsproc()
 
4771
        implicit none
 
4772
        include 'maxamps.inc'
 
4773
        
 
4774
        get_maxsproc = maxsproc
 
4775
        return 
 
4776
        end
 
4777
                
 
4778
        """ % convert
 
4779
        
 
4780
        return output
 
4781
                           
 
4782
 
 
4783
 
 
4784
    #===========================================================================
4507
4785
    # write_configs_file
4508
4786
    #===========================================================================
4509
4787
    def write_configs_file(self, writer, subproc_group, diagrams_for_config):
4545
4823
    def write_run_config_file(self, writer):
4546
4824
        """Write the run_configs.inc file for MadEvent"""
4547
4825
 
4548
 
        path = pjoin(_file_path,'iolibs','template_files','madevent_run_config.inc') 
4549
 
        text = open(path).read() % {'chanperjob':'2'} 
 
4826
        path = pjoin(_file_path,'iolibs','template_files','madevent_run_config.inc')
 
4827
        if self.proc_characteristic['loop_induced']:
 
4828
            job_per_chan = 1
 
4829
        else: 
 
4830
            job_per_chan = 2
 
4831
        text = open(path).read() % {'chanperjob':job_per_chan} 
4550
4832
        writer.write(text)
4551
4833
        return True
4552
4834
 
4569
4851
 
4570
4852
        return True
4571
4853
 
 
4854
 
 
4855
 
 
4856
    def finalize_v4_directory(self,*args, **opts):
 
4857
 
 
4858
 
 
4859
        
 
4860
        super(ProcessExporterFortranMEGroup, self).finalize_v4_directory(*args, **opts)
 
4861
        #ensure that the grouping information is on the correct value
 
4862
        self.proc_characteristic['grouped_matrix'] = True        
 
4863
 
 
4864
        
4572
4865
#===============================================================================
4573
4866
# UFO_model_to_mg4
4574
4867
#===============================================================================
 
4868
 
4575
4869
python_to_fortran = lambda x: parsers.UFOExpressionParserFortran().parse(x)
4576
4870
 
4577
4871
class UFO_model_to_mg4(object):
4598
4892
        if opt:
4599
4893
            self.opt = opt
4600
4894
        else:
4601
 
            self.opt = {'complex_mass': False, 'export_format': 'madevent', 'mp':True}
 
4895
            self.opt = {'complex_mass': False, 'export_format': 'madevent', 'mp':True,
 
4896
                        'loop_induced': False}
4602
4897
            
4603
4898
        self.coups_dep = []    # (name, expression, type)
4604
4899
        self.coups_indep = []  # (name, expression, type)
4791
5086
            includes.extend(["include \'mp_coupl.inc\'","include \'mp_input.inc\'"])
4792
5087
        # In standalone and madloop we do no use the compiled param card but
4793
5088
        # still parse the .dat one so we must load it.
4794
 
        if self.opt['export_format'] in ['madloop','madloop_optimized','madloop_matchbox']:
 
5089
        if self.opt['loop_induced']:
 
5090
            #loop induced follow MadEvent way to handle the card.
 
5091
            load_card = ''
 
5092
            lha_read_filename='lha_read.f'            
 
5093
        elif self.opt['export_format'] in ['madloop','madloop_optimized', 'madloop_matchbox']:
4795
5094
            load_card = 'call LHA_loadcard(param_name,npara,param,value)'
4796
5095
            lha_read_filename='lha_read_mp.f'
4797
5096
        elif self.opt['export_format'].startswith('standalone') or self.opt['export_format'] in ['madweight']\
4810
5109
        writer.writelines(file)
4811
5110
        writer.close()
4812
5111
 
4813
 
        if self.opt['export_format'] in ['madevent', 'FKS5_default', 'FKS5_optimized']:
 
5112
        if self.opt['export_format'] in ['madevent', 'FKS5_default', 'FKS5_optimized'] \
 
5113
            or self.opt['loop_induced']:
4814
5114
            cp( MG5DIR + '/models/template_files/fortran/makefile_madevent', 
4815
5115
                self.dir_path + '/makefile')
4816
5116
            if self.opt['export_format'] in ['FKS5_default', 'FKS5_optimized']:
4846
5146
                double precision MU_R
4847
5147
                common/rscale/ MU_R
4848
5148
 
4849
 
                """        
4850
 
 
4851
 
        header = header+"""double precision Nf
 
5149
                double precision Nf
4852
5150
                parameter(Nf=%d)
4853
5151
                """ % self.model.get_nflav()
4854
5152
                
4863
5161
                    
4864
5162
                    %(complex_mp_format)s %(mp_prefix)sMU_R
4865
5163
                    common/MP_rscale/ %(mp_prefix)sMU_R
4866
 
                    """        
4867
 
                              
 
5164
 
 
5165
                """
 
5166
 
 
5167
 
 
5168
 
 
5169
 
4868
5170
            mp_fsock.writelines(header%{'real_mp_format':self.mp_real_format,
4869
5171
                                  'complex_mp_format':self.mp_complex_format,
4870
5172
                                  'mp_prefix':self.mp_prefix})
5523
5825
    def create_param_read(self):    
5524
5826
        """create param_read"""
5525
5827
        
5526
 
        if self.opt['export_format'] in ['madevent', 'FKS5_default', 'FKS5_optimized']:
 
5828
        if self.opt['export_format'] in ['madevent', 'FKS5_default', 'FKS5_optimized'] \
 
5829
            or self.opt['loop_induced']:
5527
5830
            fsock = self.open('param_read.inc', format='fortran')
5528
5831
            fsock.writelines(' include \'../param_card.inc\'')
5529
5832
            return
5601
5904
        and 'default' for tree-level outputs."""
5602
5905
 
5603
5906
    group_subprocesses = cmd.options['group_subprocesses']
5604
 
    
5605
 
    # First treat the MadLoop5 standalone case
 
5907
 
 
5908
    # First treat the MadLoop5 standalone case       
 
5909
    MadLoop_SA_options = {'clean': not noclean, 
 
5910
      'complex_mass':cmd.options['complex_mass_scheme'],
 
5911
      'export_format':'madloop', 
 
5912
      'mp':True,
 
5913
      'loop_dir': os.path.join(cmd._mgme_dir,'Template','loop_material'),
 
5914
      'cuttools_dir': cmd._cuttools_dir,
 
5915
      'iregi_dir':cmd._iregi_dir,
 
5916
      'pjfry_dir':cmd.options["pjfry"],
 
5917
      'golem_dir':cmd.options["golem"],
 
5918
      'fortran_compiler':cmd.options['fortran_compiler'],
 
5919
      'output_dependencies':cmd.options['output_dependencies'],
 
5920
      'SubProc_prefix':'P',
 
5921
      'compute_color_flows':cmd.options['loop_color_flows']}
 
5922
 
5606
5923
    if output_type.startswith('madloop'):
5607
5924
        import madgraph.loop.loop_exporters as loop_exporters
5608
5925
        if os.path.isdir(os.path.join(cmd._mgme_dir, 'Template/loop_material')):
5609
5926
            ExporterClass=None
5610
 
            options = {'clean': not noclean, 
5611
 
              'complex_mass':cmd.options['complex_mass_scheme'],
5612
 
              'export_format':'madloop', 
5613
 
              'mp':True,
5614
 
              'loop_dir': os.path.join(cmd._mgme_dir, 'Template/loop_material'),
5615
 
              'cuttools_dir': cmd._cuttools_dir,
5616
 
              'iregi_dir':cmd._iregi_dir,
5617
 
              'pjfry_dir':cmd.options["pjfry"],
5618
 
              'golem_dir':cmd.options["golem"],
5619
 
              'fortran_compiler':cmd.options['fortran_compiler'],
5620
 
              'output_dependencies':cmd.options['output_dependencies']}
5621
 
 
5622
5927
            if not cmd.options['loop_optimized_output']:
5623
5928
                ExporterClass=loop_exporters.LoopProcessExporterFortranSA
5624
5929
            else:
5625
 
                if all([amp['process']['has_born'] for amp in cmd._curr_amps]):
5626
 
                    if output_type == "madloop":
5627
 
                        ExporterClass=loop_exporters.LoopProcessOptimizedExporterFortranSA
5628
 
                        options['export_format'] = 'madloop_optimized'
5629
 
                    elif output_type == "madloop_matchbox":
5630
 
                        ExporterClass=loop_exporters.LoopProcessExporterFortranMatchBox
5631
 
                        options['export_format'] = 'madloop_matchbox'
5632
 
                    else:
5633
 
                        raise Exception, "output_type not recognize %s" % output_type
5634
 
                    
 
5930
                if output_type == "madloop":
 
5931
                    ExporterClass=loop_exporters.LoopProcessOptimizedExporterFortranSA
 
5932
                    MadLoop_SA_options['export_format'] = 'madloop_optimized'
 
5933
                elif output_type == "madloop_matchbox":
 
5934
                    ExporterClass=loop_exporters.LoopProcessExporterFortranMatchBox
 
5935
                    MadLoop_SA_options['export_format'] = 'madloop_matchbox'
5635
5936
                else:
5636
 
                    logger.warning('ML5 can only exploit the optimized output for '+\
5637
 
                                   ' processes with born diagrams. The optimization '+\
5638
 
                                   ' option is therefore turned off for this process.')
5639
 
                    ExporterClass=loop_exporters.LoopProcessExporterFortranSA
5640
 
                    options['export_format'] = 'madloop_default'
5641
 
            return ExporterClass(cmd._mgme_dir, cmd._export_dir, options)
 
5937
                    raise Exception, "output_type not recognize %s" % output_type
 
5938
            return ExporterClass(cmd._mgme_dir, cmd._export_dir, MadLoop_SA_options)
5642
5939
        else:
5643
5940
            raise MadGraph5Error('MG5_aMC cannot find the \'loop_material\' directory'+\
5644
5941
                                 ' in %s'%str(cmd._mgme_dir))
5647
5944
    elif output_type=='amcatnlo':
5648
5945
        import madgraph.iolibs.export_fks as export_fks
5649
5946
        ExporterClass=None
5650
 
        options = {'clean': not noclean, 
5651
 
              'complex_mass':cmd.options['complex_mass_scheme'],
5652
 
              'export_format':'madloop', 
5653
 
              #use MP for HELAS only if there are virtual amps 
5654
 
              'mp':len(cmd._fks_multi_proc.get_virt_amplitudes()) > 0,
5655
 
              'loop_dir': os.path.join(cmd._mgme_dir,'Template','loop_material'),
5656
 
              'cuttools_dir': cmd._cuttools_dir,
5657
 
              'iregi_dir':cmd._iregi_dir,
5658
 
              'pjfry_dir':cmd.options["pjfry"],
5659
 
              'golem_dir':cmd.options["golem"],
5660
 
              'fortran_compiler':cmd.options['fortran_compiler'],
5661
 
              'output_dependencies':cmd.options['output_dependencies']}
 
5947
        amcatnlo_options = MadLoop_SA_options
 
5948
        amcatnlo_options['mp'] = len(cmd._fks_multi_proc.get_virt_amplitudes()) > 0
5662
5949
        if not cmd.options['loop_optimized_output']:
5663
5950
            logger.info("Writing out the aMC@NLO code")
5664
5951
            ExporterClass = export_fks.ProcessExporterFortranFKS
5665
 
            options['export_format']='FKS5_default'
 
5952
            amcatnlo_options['export_format']='FKS5_default'
5666
5953
        else:
5667
5954
            logger.info("Writing out the aMC@NLO code, using optimized Loops")
5668
5955
            ExporterClass = export_fks.ProcessOptimizedExporterFortranFKS
5669
 
            options['export_format']='FKS5_optimized'
5670
 
        return ExporterClass(cmd._mgme_dir, cmd._export_dir, options)
 
5956
            amcatnlo_options['export_format']='FKS5_optimized'
 
5957
        return ExporterClass(cmd._mgme_dir, cmd._export_dir, amcatnlo_options)
5671
5958
 
5672
5959
    # Then the default tree-level output
5673
5960
    elif output_type=='default':
 
5961
 
5674
5962
        #check if we need to group processes
5675
5963
        if cmd.options['group_subprocesses'] == 'Auto':
5676
5964
            if cmd._curr_amps[0].get_ninitial()  == 2:
5692
5980
        if format in ['standalone_msP', 'standalone_msF', 'standalone_rw']:
5693
5981
            opt['sa_symmetry'] = True        
5694
5982
    
 
5983
        loop_induced_opt = MadLoop_SA_options
 
5984
        loop_induced_opt['export_format'] = 'madloop_optimized'
 
5985
        loop_induced_opt['SubProc_prefix'] = 'PV'
 
5986
        # For loop_induced output with MadEvent, we must have access to the 
 
5987
        # color flows.
 
5988
        loop_induced_opt['compute_color_flows'] = True
 
5989
        for key in opt:
 
5990
            if key not in loop_induced_opt:
 
5991
                loop_induced_opt[key] = opt[key]
 
5992
    
5695
5993
        if format == 'matrix' or format.startswith('standalone'):
5696
5994
            return ProcessExporterFortranSA(cmd._mgme_dir, cmd._export_dir, opt,
5697
5995
                                            format=format)
5698
5996
        
5699
5997
        elif format in ['madevent'] and group_subprocesses:
5700
 
            return  ProcessExporterFortranMEGroup(cmd._mgme_dir, cmd._export_dir,
5701
 
                                                                            opt)
 
5998
            if isinstance(cmd._curr_amps[0], 
 
5999
                                         loop_diagram_generation.LoopAmplitude):
 
6000
                import madgraph.loop.loop_exporters as loop_exporters
 
6001
                return  loop_exporters.LoopInducedExporterMEGroup(cmd._mgme_dir, 
 
6002
                                               cmd._export_dir,loop_induced_opt)
 
6003
            else:
 
6004
                return  ProcessExporterFortranMEGroup(cmd._mgme_dir, 
 
6005
                                                            cmd._export_dir,opt)                
5702
6006
        elif format in ['madevent']:
5703
 
            return ProcessExporterFortranME(cmd._mgme_dir, cmd._export_dir,opt)
 
6007
            if isinstance(cmd._curr_amps[0], 
 
6008
                                         loop_diagram_generation.LoopAmplitude):
 
6009
                import madgraph.loop.loop_exporters as loop_exporters
 
6010
                return  loop_exporters.LoopInducedExporterMENoGroup(cmd._mgme_dir, 
 
6011
                                               cmd._export_dir,loop_induced_opt)
 
6012
            else:
 
6013
                return  ProcessExporterFortranME(cmd._mgme_dir, 
 
6014
                                                            cmd._export_dir,opt)
5704
6015
        elif format in ['matchbox']:
5705
6016
            return ProcessExporterFortranMatchBox(cmd._mgme_dir, cmd._export_dir,opt)
5706
6017
        elif cmd._export_format in ['madweight'] and group_subprocesses: