def setUp(self):
        """load the model"""

        import madgraph.interface.master_interface as interface
        cmd = interface.MasterCmd()
        cmd.do_import('model sm')

        self.mybasemodel = cmd._curr_model
        self.mybasemodel.change_mass_to_complex_scheme()

        leg1 = base_objects.Leg({'id': 22, 'state': False})
        leg2 = base_objects.Leg({'id': 24, 'state': False})
        leg3 = base_objects.Leg({'id': 22, 'state': True})
        leg4 = base_objects.Leg({'id': 24, 'state': True})
        leg5 = base_objects.Leg({'id': 23, 'state': True})

        legList1 = base_objects.LegList([leg1, leg2, leg3, leg4, leg5])

        myproc = base_objects.Process({
            'legs': legList1,
            'model': self.mybasemodel
        })

        myamplitude = diagram_generation.Amplitude({'process': myproc})

        self.mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)
Exemple #2
0
    def __init__(self, fksproc=None, real_me_list =[], real_amp_list=[], 
            loop_optimized = False, **opts):#test written
        """ constructor, starts from a FKSProcess, 
        sets reals and color links. Real_me_list and real_amp_list are the lists of pre-genrated
        matrix elements in 1-1 correspondence with the amplitudes"""
        
        if fksproc != None:
            self.born_matrix_element = helas_objects.HelasMatrixElement(
                                    fksproc.born_amp, **opts)
            self.real_processes = []
            self.orders = fksproc.born_proc.get('orders')
            self.perturbation = fksproc.perturbation
            real_amps_new = []
            # combine for example u u~ > t t~ and d d~ > t t~
            for proc in fksproc.real_amps:
                fksreal_me = FKSHelasRealProcess(proc, real_me_list, real_amp_list, **opts)
                try:
                    other = self.real_processes[self.real_processes.index(fksreal_me)]
                    other.matrix_element.get('processes').extend(\
                            fksreal_me.matrix_element.get('processes') )
                except ValueError:
                    if fksreal_me.matrix_element.get('processes') and \
                            fksreal_me.matrix_element.get('diagrams'):
                        self.real_processes.append(fksreal_me)
                        real_amps_new.append(proc)
            fksproc.real_amps = real_amps_new
            if fksproc.virt_amp:
                self.virt_matrix_element = \
                  loop_helas_objects.LoopHelasMatrixElement(fksproc.virt_amp, 
                          optimized_output = loop_optimized)
            else: 
                self.virt_matrix_element = None
#            self.color_links_info = fksproc.find_color_links()
            self.color_links = []
Exemple #3
0
    def __init__(self, fksrealproc=None, real_me_list = [], real_amp_list =[], **opts):
        """constructor, starts from a fksrealproc and then calls the
        initialization for HelasMatrixElement.
        Sets i/j fks and the permutation.
        real_me_list and real_amp_list are the lists of pre-generated matrix elements in 1-1 
        correspondance with the amplitudes"""
        
        if fksrealproc != None:
            self.isfinite = False
            self.colors = fksrealproc.colors
            self.charges = fksrealproc.charges
            self.fks_infos = fksrealproc.fks_infos
            self.is_to_integrate = fksrealproc.is_to_integrate

            if len(real_me_list) != len(real_amp_list):
                raise fks_common.FKSProcessError(
                        'not same number of amplitudes and matrix elements: %d, %d' % \
                                (len(real_amp_list), len(real_me_list)))
            if real_me_list and real_amp_list:
                self.matrix_element = copy.deepcopy(real_me_list[real_amp_list.index(fksrealproc.amplitude)])
                self.matrix_element['processes'] = copy.deepcopy(self.matrix_element['processes'])
            else:
                logger.info('generating matrix element...')
                self.matrix_element = helas_objects.HelasMatrixElement(
                                                  fksrealproc.amplitude, **opts)
                #generate the color for the real
                self.matrix_element.get('color_basis').build(
                                    self.matrix_element.get('base_amplitude'))
                self.matrix_element.set('color_matrix',
                                 color_amp.ColorMatrix(
                                    self.matrix_element.get('color_basis')))
            #self.fks_j_from_i = fksrealproc.find_fks_j_from_i()
            self.fks_j_from_i = fksrealproc.fks_j_from_i
    def test_uu_to_six_g(self):
        """Test the process u u > six g against literature expression"""

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id':2,
                                           'state':False,
                                           'number': 1}))
        myleglist.append(base_objects.Leg({'id':2,
                                           'state':False,
                                           'number': 2}))
        myleglist.append(base_objects.Leg({'id':9000006,
                                           'state':True,
                                           'number': 3}))
        myleglist.append(base_objects.Leg({'id':21,
                                           'state':True,
                                           'number': 4}))

        myproc = base_objects.Process({'legs':myleglist,
                                       'model':self.base_model})

        evaluator = process_checks.MatrixElementEvaluator(self.base_model,
                                                          reuse = False)
        
        p, w_rambo = evaluator.get_momenta(myproc)

        amplitude = diagram_generation.Amplitude(myproc)
        matrix_element = helas_objects.HelasMatrixElement(amplitude)

        mg5_me_value, amp2 = evaluator.evaluate_matrix_element(matrix_element,
                                                               p)

        comparison_value = uu_Dg(p, 6, evaluator.full_model)

        self.assertAlmostEqual(mg5_me_value, comparison_value, 12)
    def test_get_s_and_t_ub_tdg(self):
        """test that for the single-top (ub>tdg) the s-and t-channels are correctly
        returned"""

        myleglist = MG.LegList()
        myleglist.append(MG.Leg({'id': 2, 'state': False}))
        myleglist.append(MG.Leg({'id': 5, 'state': False}))
        myleglist.append(MG.Leg({'id': 6, 'state': True}))
        myleglist.append(MG.Leg({'id': 1, 'state': True}))
        myleglist.append(MG.Leg({'id': 21, 'state': True}))
        proc = MG.Process({
            'legs': myleglist,
            'model': self.base_model,
            'orders': {
                'QCD': 1,
                'QED': 2
            }
        })
        me = helas_objects.HelasMatrixElement(
            diagram_generation.Amplitude(proc))

        #without flipping: s-and-t channel legs
        # note that leg 2 never appears
        target = [[[1, 4, -1], [-1, 3, -2], [-2, 5, -3]],
                  [[5, 3, -1], [1, 4, -2], [-2, -1, -3]],
                  [[1, 5, -1], [-1, 4, -2], [-2, 3, -3]],
                  [[5, 4, -1], [1, -1, -2], [-2, 3, -3]]]

        #if we flip the s-and-t channel legs should be
        # note that leg 1 never appears
        target_flip = [[[2, 5, -1], [-1, 3, -2], [-2, 4, -3]],
                       [[5, 3, -1], [2, -1, -2], [-2, 4, -3]],
                       [[2, 3, -1], [-1, 4, -2], [-2, 5, -3]],
                       [[5, 4, -1], [2, 3, -2], [-2, -1, -3]]]

        for id, diag in enumerate(me.get('diagrams')):
            s_ch, t_ch = diag.get('amplitudes')[0].get_s_and_t_channels(
                ninitial=2,
                model=self.base_model,
                new_pdg=7,
                reverse_t_ch=False)
            self.assertEqual( [ [l['number'] for l in v['legs']] for v in s_ch] + \
                              [ [l['number'] for l in v['legs']] for v in t_ch] ,
                              target[id])

        for id, diag in enumerate(me.get('diagrams')):
            s_ch, t_ch = diag.get('amplitudes')[0].get_s_and_t_channels(
                ninitial=2,
                model=self.base_model,
                new_pdg=7,
                reverse_t_ch=True)
            self.assertEqual( [ [l['number'] for l in v['legs']] for v in s_ch] + \
                              [ [l['number'] for l in v['legs']] for v in t_ch] ,
                              target_flip[id])
Exemple #6
0
    def test_fks_helas_process_init(self):
        """tests the correct initialization of a FKSHelasProcess object.
        in particular checks:
        -- born ME
        -- list of FKSHelasRealProcesses
        -- color links
        -- fks_infos
        """
        #ug> ug
        fks1 = fks_base.FKSProcess(self.myproc1)
        #uu~> dd~
        fks3 = fks_base.FKSProcess(self.myproc3)

        pdg_list1 = []
        real_amp_list1 = diagram_generation.AmplitudeList()
        pdg_list3 = []
        real_amp_list3 = diagram_generation.AmplitudeList()
        fks1.generate_reals(pdg_list1, real_amp_list1)
        fks3.generate_reals(pdg_list3, real_amp_list3)

        me_list = []
        me_id_list = []
        me_list3 = []
        me_id_list3 = []
        res_me_list = []
        res_me_id_list = []

        helas_born_proc = fks_helas.FKSHelasProcess(fks1, me_list, me_id_list)
        helas_born_proc3 = fks_helas.FKSHelasProcess(fks3, me_list3,
                                                     me_id_list3)

        self.assertEqual(helas_born_proc.born_matrix_element,
                         helas_objects.HelasMatrixElement(fks1.born_amp))
        res_reals = []
        for real in fks1.real_amps:
            res_reals.append(
                fks_helas.FKSHelasRealProcess(real, res_me_list,
                                              res_me_id_list))
            # the process u g > u g g corresponds to 4 fks configs
            if real.pdgs == array.array('i', [2, 21, 2, 21, 21]):
                self.assertEqual(len(real.fks_infos), 4)
            else:
                # any other process has only 1 fks config
                self.assertEqual(len(real.fks_infos), 1)

        self.assertEqual(me_list, res_me_list)
        self.assertEqual(me_id_list, res_me_id_list)
        self.assertEqual(8, len(helas_born_proc.real_processes))
        self.assertNotEqual(helas_born_proc.born_matrix_element,
                            helas_born_proc3.born_matrix_element)
        for a, b in zip(helas_born_proc3.real_processes,
                        helas_born_proc.real_processes):
            self.assertNotEqual(a, b)
Exemple #7
0
    def test_fks_helas_real_process_init(self):
        """tests the correct initialization of an FKSHelasRealProcess, from a 
        FKSRealProc. The process uu~>dd~ is used as born.
        For the real we use uu~>dd~(j) g(i).
        We test The correct initialization of:
        --i/j fks
        --permutation
        --matrix element
        """
        #uu~> dd~
        fks3 = fks_base.FKSProcess(self.myproc3)

        fksleglist = copy.copy(
            fks_common.to_fks_legs(self.myleglist3, self.mymodel))
        amplist = []
        amp_id_list = []
        me_list = []
        me_id_list = []

        fksleglist.append(
            fks_common.to_fks_leg(
                MG.Leg({
                    'id': 21,
                    'state': True,
                    'number': 5,
                    'from_group': True
                }), self.mymodel))
        fksleglist[0]['fks'] = 'n'
        fksleglist[1]['fks'] = 'n'
        fksleglist[2]['fks'] = 'n'
        fksleglist[3]['fks'] = 'j'
        fksleglist[4]['fks'] = 'i'

        real_proc = fks_base.FKSRealProcess(fks3.born_proc, fksleglist, 4, 0)
        real_proc.generate_real_amplitude()
        helas_real_proc = fks_helas.FKSHelasRealProcess(
            real_proc, me_list, me_id_list)
        self.assertEqual(helas_real_proc.fks_infos, [{
            'i': 5,
            'j': 4,
            'ij': 4,
            'ij_glu': 0,
            'need_color_links': True
        }])
        target_me = helas_objects.HelasMatrixElement(real_proc.amplitude)
        self.assertEqual(helas_real_proc.matrix_element, target_me)
        self.assertEqual(helas_real_proc.matrix_element.get('color_matrix'),
                         target_me.get('color_matrix'))
Exemple #8
0
    def test_find_symmetry_epem_aaa(self):
        """Test the find_symmetry function"""

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id':-11,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':11,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':22,
                                           'state':True}))
        myleglist.append(base_objects.Leg({'id':22,
                                           'state':True}))
        myleglist.append(base_objects.Leg({'id':22,
                                           'state':True}))

        myproc = base_objects.Process({'legs':myleglist,
                                       'model':self.base_model})

        myamplitude = diagram_generation.Amplitude(myproc)

        matrix_element = helas_objects.HelasMatrixElement(myamplitude)

        symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(matrix_element)

        self.assertEqual(symmetry, [6,-1,-1,-1,-1,-1])

        # Check that the momentum assignments work
        process = matrix_element.get('processes')[0]

        evaluator = process_checks.MatrixElementEvaluator(self.base_model,
                                                          auth_skipping = True,
                                                          reuse = True)
        
        p, w_rambo = evaluator.get_momenta(process)
        me_value, amp2_org = evaluator.evaluate_matrix_element(\
                                          matrix_element, p)

        for isym, (sym, perm) in enumerate(zip(symmetry, perms)):
            new_p = [p[i] for i in perm]
            if sym >= 0:
                continue
            me_value, amp2 = evaluator.evaluate_matrix_element(matrix_element,
                                                               new_p)
            self.assertAlmostEqual(amp2[isym], amp2_org[-sym-1])
def async_generate_real(args):
    i = args[0]
    real_amp = args[1]

    #amplitude generation
    amplitude = real_amp.generate_real_amplitude()
    helasreal = helas_objects.HelasMatrixElement(amplitude)
    logger.info('Generating real %s' % \
            real_amp.process.nice_string(print_weighted=False).replace('Process', 'process'))

    # Keep track of already generated color objects, to reuse as
    # much as possible
    list_colorize = []
    list_color_basis = []
    list_color_matrices = []

    # Now this keeps track of the color matrices created from the loop-born
    # color basis. Keys are 2-tuple with the index of the loop and born basis
    # in the list above and the value is the resulting matrix.
    dict_loopborn_matrices = {}
    # The dictionary below is simply a container for convenience to be
    # passed to the function process_color.
    color_information = {
        'list_colorize': list_colorize,
        'list_color_basis': list_color_basis,
        'list_color_matrices': list_color_matrices,
        'dict_loopborn_matrices': dict_loopborn_matrices
    }

    helas_objects.HelasMultiProcess.process_color(helasreal, color_information)

    outdata = [amplitude, helasreal]

    output = tempfile.NamedTemporaryFile(delete=False)
    cPickle.dump(outdata, output, protocol=2)
    output.close()

    return [
        output.name,
        helasreal.get_num_configs(),
        helasreal.get_nexternal_ninitial()[0]
    ]
Exemple #10
0
    def test_rotate_momenta(self):
        """Test that matrix element and amp2 identical for rotated momenta"""

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id':2,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':-2,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':2,
                                           'state':True}))
        myleglist.append(base_objects.Leg({'id':-2,
                                           'state':True}))
        myleglist.append(base_objects.Leg({'id':21,
                                           'state':True}))

        myproc = base_objects.Process({'legs':myleglist,
                                       'model':self.base_model})

        myamp = diagram_generation.Amplitude(myproc)

        matrix_element = helas_objects.HelasMatrixElement(myamp)

        evaluator = process_checks.MatrixElementEvaluator(self.base_model,
                                                          auth_skipping = True,
                                                          reuse = True)
        p, w_rambo = evaluator.get_momenta(myproc)

        me_val, amp2 = evaluator.evaluate_matrix_element(\
                                          matrix_element,p)
        # Rotate momenta around x axis
        for mom in p:
            mom[2] = -mom[2]
            mom[3] = -mom[3]

        new_me_val, new_amp2 = evaluator.evaluate_matrix_element(\
                                          matrix_element, p)

        self.assertAlmostEqual(me_val, new_me_val, 10)

        for amp, new_amp in zip(amp2, new_amp2):
            self.assertAlmostEqual(amp, new_amp, 10)
    def uu_to_ttng_test(self, nglue = 0):
        """Test the process u u > t t g for 4fermion models"""

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id':2,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':2,
                                           'state':False}))
        myleglist.append(base_objects.Leg({'id':6}))
        myleglist.append(base_objects.Leg({'id':6}))
        myleglist.extend([base_objects.Leg({'id':21}) for i in range(nglue)])

        values = {}
        p = None
        for model in 'scalar', '4ferm':

            base_model = eval('self.base_model_%s' % model)
            full_model = eval('self.full_model_%s' % model)
            myproc = base_objects.Process({'legs':myleglist,
                                           'model':base_model})

            evaluator = process_checks.MatrixElementEvaluator(base_model,
                                                                  reuse = False)
            evaluator.full_model = full_model
            
            if not p:
                p, w_rambo = evaluator.get_momenta(myproc)

            amplitude = diagram_generation.Amplitude(myproc)

            matrix_element = helas_objects.HelasMatrixElement(amplitude)

            stored_quantities = {}

            values[model] = evaluator.evaluate_matrix_element(matrix_element,
                                                              p)[0]

            
        self.assertAlmostEqual(values['scalar'], values['4ferm'], 3)
    def test_triplet_color_flow_output(self):
        """Test the color flow output for color triplets"""

        # Test u u > trip~ g

        myleglist = base_objects.LegList()

        myleglist.append(
            base_objects.Leg({
                'id': 2,
                'state': False,
                'number': 1
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 6,
                'state': False,
                'number': 2
            }))
        myleglist.append(
            base_objects.Leg({
                'id': -9000006,
                'state': True,
                'number': 3
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 21,
                'state': True,
                'number': 4
            }))

        myproc = base_objects.Process({
            'legs': myleglist,
            'model': self.base_model
        })

        myamp = diagram_generation.Amplitude(myproc)
        matrix_element = helas_objects.HelasMatrixElement(myamp)

        # First build a color representation dictionnary
        repr_dict = {}
        for l in myleglist:
            repr_dict[l.get('number')] = \
                self.base_model.get_particle(l.get('id')).get_color()

        # Get the color flow decomposition
        col_flow = \
           matrix_element.get('color_basis').color_flow_decomposition(repr_dict,
                                                                      2)
        self.assertEqual(col_flow, [{
            1: [501, 0],
            2: [502, 0],
            3: [0, 504],
            4: [504, 503]
        }, {
            1: [501, 0],
            2: [504, 0],
            3: [0, 502],
            4: [504, 503]
        }, {
            1: [504, 0],
            2: [501, 0],
            3: [0, 502],
            4: [504, 503]
        }])

        # Test u u > trip~ > u u g

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id': 2, 'state': False}))
        myleglist.append(base_objects.Leg({'id': 6, 'state': False}))
        myleglist.append(base_objects.Leg({'id': 2, 'state': True}))
        myleglist.append(base_objects.Leg({'id': 6, 'state': True}))
        myleglist.append(base_objects.Leg({'id': 21, 'state': True}))

        myproc = base_objects.Process({
            'legs': myleglist,
            'model': self.base_model,
            'required_s_channels': [[-9000006]]
        })

        myamp = diagram_generation.Amplitude(myproc)
        self.assertEqual(len(myamp.get('diagrams')), 5)
        matrix_element = helas_objects.HelasMatrixElement(myamp)

        # First build a color representation dictionnary
        repr_dict = {}
        for l in myleglist:
            repr_dict[l.get('number')] = \
                self.base_model.get_particle(l.get('id')).get_color()

        # Get the color flow decomposition
        col_flow = \
           matrix_element.get('color_basis').color_flow_decomposition(repr_dict,
                                                                      2)
        self.assertEqual(col_flow, [{
            1: [501, 0],
            2: [502, 0],
            3: [504, 0],
            4: [505, 0],
            5: [506, 503]
        }, {
            1: [501, 0],
            2: [503, 0],
            3: [501, 0],
            4: [502, 0],
            5: [503, 502]
        }, {
            1: [503, 0],
            2: [501, 0],
            3: [501, 0],
            4: [502, 0],
            5: [503, 502]
        }, {
            1: [502, 0],
            2: [503, 0],
            3: [501, 0],
            4: [502, 0],
            5: [503, 501]
        }, {
            1: [503, 0],
            2: [502, 0],
            3: [501, 0],
            4: [502, 0],
            5: [503, 501]
        }])
    def setUp(self):
        # Set up model

        mypartlist = base_objects.ParticleList()
        myinterlist = base_objects.InteractionList()

        # A photon
        mypartlist.append(
            base_objects.Particle({
                'name': 'a',
                'antiname': 'a',
                'spin': 3,
                'color': 1,
                'mass': 'zero',
                'width': 'zero',
                'texname': '\gamma',
                'antitexname': '\gamma',
                'line': 'wavy',
                'charge': 0.,
                'pdg_code': 22,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))
        a = mypartlist[len(mypartlist) - 1]

        # W+ and W-
        mypartlist.append(
            base_objects.Particle({
                'name': 'w+',
                'antiname': 'w-',
                'spin': 3,
                'color': 1,
                'mass': 'wmas',
                'width': 'wwid',
                'texname': 'W^+',
                'antitexname': 'W^-',
                'line': 'wavy',
                'charge': 1.,
                'pdg_code': 24,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        wplus = mypartlist[len(mypartlist) - 1]
        wminus = copy.copy(wplus)
        wminus.set('is_part', False)

        # Z
        mypartlist.append(
            base_objects.Particle({
                'name': 'z',
                'antiname': 'z',
                'spin': 3,
                'color': 1,
                'mass': 'zmas',
                'width': 'zwid',
                'texname': 'Z',
                'antitexname': 'Z',
                'line': 'wavy',
                'charge': 1.,
                'pdg_code': 23,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))
        z = mypartlist[len(mypartlist) - 1]

        # a-a-w+w- 4-vertex
        myinterlist.append(base_objects.Interaction({
                      'id': 1,
                      'particles': base_objects.ParticleList(\
                                            [a, \
                                             a,
                                             wminus,
                                             wplus]),
                      'color': [],
                      'lorentz':['VVVV1'],
                      'couplings':{(0, 0):'GC_51'},
                      'orders':{'QED':2}}))

        # w+w-z vertex
        myinterlist.append(base_objects.Interaction({
                      'id': 2,
                      'particles': base_objects.ParticleList(\
                                            [wminus,
                                             wplus,
                                             z]),
                      'color': [],
                      'lorentz':['VVV1'],
                      'couplings':{(0, 0):'GC_12'},
                      'orders':{'QED':1}}))

        self.mybasemodel.set('particles', mypartlist)
        self.mybasemodel.set('interactions', myinterlist)
        self.mybasemodel.set('name', 'sm')

        #import madgraph.interface.cmd_interface as cmd
        #CMD = cmd.MadGraphCmdShell()
        #CMD._curr_model = self.mybasemodel
        #CMD._curr_fortran_model = helas_call_writers.FortranUFOHelasCallWriter
        #CMD.do_generate('a w- > w- a z')
        #CMD.do_export('matrix_v4 /tmp/')

        leg1 = base_objects.Leg({'id': 22, 'state': False})
        leg2 = base_objects.Leg({'id': 24, 'state': False})
        leg3 = base_objects.Leg({'id': 22, 'state': True})
        leg4 = base_objects.Leg({'id': 24, 'state': True})
        leg5 = base_objects.Leg({'id': 23, 'state': True})

        legList1 = base_objects.LegList([leg1, leg2, leg3, leg4, leg5])

        myproc = base_objects.Process({
            'legs': legList1,
            'model': self.mybasemodel
        })

        myamplitude = diagram_generation.Amplitude({'process': myproc})

        self.mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)
class IOExportPythonTest(unittest.TestCase):
    """Test class for the export v4 module"""

    mymodel = base_objects.Model()
    mymatrixelement = helas_objects.HelasMatrixElement()

    def setUp(self):

        # Set up model
        mypartlist = base_objects.ParticleList()
        myinterlist = base_objects.InteractionList()

        # u and c quarkd and their antiparticles
        mypartlist.append(
            base_objects.Particle({
                'name': 'u',
                'antiname': 'u~',
                'spin': 2,
                'color': 3,
                'mass': 'ZERO',
                'width': 'ZERO',
                'texname': 'u',
                'antitexname': '\bar u',
                'line': 'straight',
                'charge': 2. / 3.,
                'pdg_code': 2,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        u = mypartlist[len(mypartlist) - 1]
        antiu = copy.copy(u)
        antiu.set('is_part', False)

        mypartlist.append(
            base_objects.Particle({
                'name': 'c',
                'antiname': 'c~',
                'spin': 2,
                'color': 3,
                'mass': 'MC',
                'width': 'ZERO',
                'texname': 'c',
                'antitexname': '\bar c',
                'line': 'straight',
                'charge': 2. / 3.,
                'pdg_code': 4,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        c = mypartlist[len(mypartlist) - 1]
        antic = copy.copy(c)
        antic.set('is_part', False)

        # A gluon
        mypartlist.append(
            base_objects.Particle({
                'name': 'g',
                'antiname': 'g',
                'spin': 3,
                'color': 8,
                'mass': 'ZERO',
                'width': 'ZERO',
                'texname': 'g',
                'antitexname': 'g',
                'line': 'curly',
                'charge': 0.,
                'pdg_code': 21,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))

        g = mypartlist[len(mypartlist) - 1]

        # A photon
        mypartlist.append(
            base_objects.Particle({
                'name': 'Z',
                'antiname': 'Z',
                'spin': 3,
                'color': 1,
                'mass': 'MZ',
                'width': 'WZ',
                'texname': 'Z',
                'antitexname': 'Z',
                'line': 'wavy',
                'charge': 0.,
                'pdg_code': 23,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))
        z = mypartlist[len(mypartlist) - 1]

        # Gluon couplings to quarks
        myinterlist.append(base_objects.Interaction({
                      'id': 1,
                      'particles': base_objects.ParticleList(\
                                            [antiu, \
                                             u, \
                                             g]),
                      'color': [color.ColorString([color.T(2, 1, 0)])],
                      'lorentz':['FFV1'],
                      'couplings':{(0, 0):'GC_10'},
                      'orders':{'QCD':1}}))

        # Gamma couplings to quarks
        myinterlist.append(base_objects.Interaction({
                      'id': 2,
                      'particles': base_objects.ParticleList(\
                                            [antiu, \
                                             u, \
                                             z]),
                      'color': [color.ColorString([color.T(1, 0)])],
                      'lorentz':['FFV2', 'FFV5'],
                      'couplings':{(0,0): 'GC_35', (0,1): 'GC_47'},
                      'orders':{'QED':1}}))

        self.mymodel.set('particles', mypartlist)
        self.mymodel.set('interactions', myinterlist)
        self.mymodel.set('name', 'sm')

        self.mypythonmodel = helas_call_writers.PythonUFOHelasCallWriter(
            self.mymodel)

        myleglist = base_objects.LegList()

        myleglist.append(base_objects.Leg({'id': 2, 'state': False}))
        myleglist.append(base_objects.Leg({'id': -2, 'state': False}))
        myleglist.append(base_objects.Leg({'id': 2, 'state': True}))
        myleglist.append(base_objects.Leg({'id': -2, 'state': True}))

        myproc = base_objects.Process({
            'legs': myleglist,
            'model': self.mymodel
        })

        myamplitude = diagram_generation.Amplitude({'process': myproc})

        self.mymatrixelement = helas_objects.HelasMultiProcess(myamplitude)

        myleglist = base_objects.LegList()

        myleglist.append(
            base_objects.Leg({
                'id': 4,
                'state': False,
                'number': 1
            }))
        myleglist.append(
            base_objects.Leg({
                'id': -4,
                'state': False,
                'number': 2
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 4,
                'state': True,
                'number': 3
            }))
        myleglist.append(
            base_objects.Leg({
                'id': -4,
                'state': True,
                'number': 4
            }))

        myproc = base_objects.Process({
            'legs': myleglist,
            'model': self.mymodel
        })

        self.mymatrixelement.get('matrix_elements')[0].\
                                               get('processes').append(myproc)

        self.exporter = export_python.ProcessExporterPython(\
            self.mymatrixelement, self.mypythonmodel)

    def test_python_export_functions(self):
        """Test functions used by the Python export"""

        # Test the exporter setup
        self.assertEqual(self.exporter.model, self.mymodel)
        self.assertEqual(self.exporter.matrix_elements,
                         self.mymatrixelement.get('matrix_elements'))

    def test_get_python_matrix_methods(self):
        """Test getting the matrix methods for Python for a matrix element."""

        goal_method = (\
"""class Matrix_0_uux_uux(object):

    def __init__(self):
        \"\"\"define the object\"\"\"
        self.clean()

    def clean(self):
        self.jamp = []

    def smatrix(self,p, model):
        #  
        #  MadGraph5_aMC@NLO v. %(version)s, %(date)s
        #  By the MadGraph5_aMC@NLO Development Team
        #  Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
        # 
        # MadGraph5_aMC@NLO StandAlone Version
        # 
        # Returns amplitude squared summed/avg over colors
        # and helicities
        # for the point in phase space P(0:3,NEXTERNAL)
        #  
        # Process: u u~ > u u~
        # Process: c c~ > c c~
        #  
        # Clean additional output
        #
        self.clean()
        #  
        # CONSTANTS
        #  
        nexternal = 4
        ndiags = 4
        ncomb = 16
        #  
        # LOCAL VARIABLES 
        #  
        helicities = [ \\
        [-1,-1,-1,-1],
        [-1,-1,-1,1],
        [-1,-1,1,-1],
        [-1,-1,1,1],
        [-1,1,-1,-1],
        [-1,1,-1,1],
        [-1,1,1,-1],
        [-1,1,1,1],
        [1,-1,-1,-1],
        [1,-1,-1,1],
        [1,-1,1,-1],
        [1,-1,1,1],
        [1,1,-1,-1],
        [1,1,-1,1],
        [1,1,1,-1],
        [1,1,1,1]]
        denominator = 36
        # ----------
        # BEGIN CODE
        # ----------
        self.amp2 = [0.] * ndiags
        self.helEvals = []
        ans = 0.
        for hel in helicities:
            t = self.matrix(p, hel, model)
            ans = ans + t
            self.helEvals.append([hel, t.real / denominator ])
        ans = ans / denominator
        return ans.real

    def matrix(self, p, hel, model):
        #  
        #  MadGraph5_aMC@NLO v. %(version)s, %(date)s
        #  By the MadGraph5_aMC@NLO Development Team
        #  Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
        #
        # Returns amplitude squared summed/avg over colors
        # for the point with external lines W(0:6,NEXTERNAL)
        #
        # Process: u u~ > u u~
        # Process: c c~ > c c~
        #  
        #  
        # Process parameters
        #  
        ngraphs = 4
        nexternal = 4
        nwavefuncs = 5
        ncolor = 2
        ZERO = 0.
        #  
        # Color matrix
        #  
        denom = [1,1];
        cf = [[9,3],
        [3,9]];
        #
        # Model parameters
        #
        WZ = model.get('parameter_dict')["WZ"]
        MZ = model.get('parameter_dict')["MZ"]
        GC_47 = model.get('coupling_dict')["GC_47"]
        GC_35 = model.get('coupling_dict')["GC_35"]
        GC_10 = model.get('coupling_dict')["GC_10"]
        # ----------
        # Begin code
        # ----------
        amp = [None] * ngraphs
        w = [None] * nwavefuncs
        w[0] = ixxxxx(p[0],ZERO,hel[0],+1)
        w[1] = oxxxxx(p[1],ZERO,hel[1],-1)
        w[2] = oxxxxx(p[2],ZERO,hel[2],+1)
        w[3] = ixxxxx(p[3],ZERO,hel[3],-1)
        w[4]= FFV1_3(w[0],w[1],GC_10,ZERO,ZERO)
        # Amplitude(s) for diagram number 1
        amp[0]= FFV1_0(w[3],w[2],w[4],GC_10)
        w[4]= FFV2_5_3(w[0],w[1],GC_35,GC_47,MZ,WZ)
        # Amplitude(s) for diagram number 2
        amp[1]= FFV2_5_0(w[3],w[2],w[4],GC_35,GC_47)
        w[4]= FFV1_3(w[0],w[2],GC_10,ZERO,ZERO)
        # Amplitude(s) for diagram number 3
        amp[2]= FFV1_0(w[3],w[1],w[4],GC_10)
        w[4]= FFV2_5_3(w[0],w[2],GC_35,GC_47,MZ,WZ)
        # Amplitude(s) for diagram number 4
        amp[3]= FFV2_5_0(w[3],w[1],w[4],GC_35,GC_47)

        jamp = [None] * ncolor
        jamp[0] = +1./6.*amp[0]-amp[1]+1./2.*amp[2]
        jamp[1] = -1./2.*amp[0]-1./6.*amp[2]+amp[3]

        self.amp2[0]+=abs(amp[0]*amp[0].conjugate())
        self.amp2[1]+=abs(amp[1]*amp[1].conjugate())
        self.amp2[2]+=abs(amp[2]*amp[2].conjugate())
        self.amp2[3]+=abs(amp[3]*amp[3].conjugate())

        matrix = 0.
        for i in range(ncolor):
            ztemp = 0
            for j in range(ncolor):
                ztemp = ztemp + cf[i][j]*jamp[j]
            matrix = matrix + ztemp * jamp[i].conjugate()/denom[i]   
        self.jamp.append(jamp)
        return matrix
""" % misc.get_pkg_info()).split('\n')

        exporter = export_python.ProcessExporterPython(self.mymatrixelement,
                                                       self.mypythonmodel)

        matrix_methods = exporter.get_python_matrix_methods()["0_uux_uux"].\
                          split('\n')

        self.assertEqual(matrix_methods, goal_method)

    def test_run_python_matrix_element(self):
        """Test a complete running of a Python matrix element without
        writing any files"""

        # Import the SM
        sm_path = import_ufo.find_ufo_path('sm')
        model = import_ufo.import_model(sm_path)

        myleglist = base_objects.LegList()

        myleglist.append(
            base_objects.Leg({
                'id': -11,
                'state': False,
                'number': 1
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 11,
                'state': False,
                'number': 2
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 3
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 4
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 5
            }))

        myproc = base_objects.Process({'legs': myleglist, 'model': model})

        myamplitude = diagram_generation.Amplitude({'process': myproc})

        mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)

        # Create only the needed aloha routines
        wanted_lorentz = mymatrixelement.get_used_lorentz()

        aloha_model = create_aloha.AbstractALOHAModel(model.get('name'))
        aloha_model.compute_subset(wanted_lorentz)

        # Write out the routines in Python
        aloha_routines = []
        for routine in aloha_model.values():
            aloha_routines.append(routine.write(output_dir = None,
                                                language = 'Python').\
                                  replace('import wavefunctions',
                                          'import aloha.template_files.wavefunctions as wavefunctions'))
        # Define the routines to be available globally
        for routine in aloha_routines:
            exec(routine, globals())

        # Write the matrix element(s) in Python
        mypythonmodel = helas_call_writers.PythonUFOHelasCallWriter(\
                                                             model)
        exporter = export_python.ProcessExporterPython(\
                                                     mymatrixelement,
                                                     mypythonmodel)
        matrix_methods = exporter.get_python_matrix_methods()

        # Calculate parameters and couplings
        full_model = model_reader.ModelReader(model)

        full_model.set_parameters_and_couplings()

        # Define a momentum
        p = [[
            0.5000000e+03, 0.0000000e+00, 0.0000000e+00, 0.5000000e+03,
            0.0000000e+00
        ],
             [
                 0.5000000e+03, 0.0000000e+00, 0.0000000e+00, -0.5000000e+03,
                 0.0000000e+00
             ],
             [
                 0.4585788e+03, 0.1694532e+03, 0.3796537e+03, -0.1935025e+03,
                 0.6607249e-05
             ],
             [
                 0.3640666e+03, -0.1832987e+02, -0.3477043e+03, 0.1063496e+03,
                 0.7979012e-05
             ],
             [
                 0.1773546e+03, -0.1511234e+03, -0.3194936e+02, 0.8715287e+02,
                 0.1348699e-05
             ]]

        # Evaluate the matrix element for the given momenta

        answer = 1.39189717257175028e-007
        for process in matrix_methods.keys():
            # Define Python matrix element for process
            exec(matrix_methods[process])
            # Calculate the matrix element for the momentum p
            value = eval("Matrix_0_epem_aaa().smatrix(p, full_model)")
            self.assertTrue(abs(value-answer)/answer < 1e-6,
                            "Value is: %.9e should be %.9e" % \
                            (abs(value), answer))

    def test_export_matrix_element_python_madevent_group(self):
        """Test the result of exporting a subprocess group matrix element"""

        # Setup a model

        mypartlist = base_objects.ParticleList()
        myinterlist = base_objects.InteractionList()

        # A gluon
        mypartlist.append(
            base_objects.Particle({
                'name': 'g',
                'antiname': 'g',
                'spin': 3,
                'color': 8,
                'mass': 'zero',
                'width': 'zero',
                'texname': 'g',
                'antitexname': 'g',
                'line': 'curly',
                'charge': 0.,
                'pdg_code': 21,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))

        g = mypartlist[-1]

        # A quark U and its antiparticle
        mypartlist.append(
            base_objects.Particle({
                'name': 'u',
                'antiname': 'u~',
                'spin': 2,
                'color': 3,
                'mass': 'zero',
                'width': 'zero',
                'texname': 'u',
                'antitexname': '\bar u',
                'line': 'straight',
                'charge': 2. / 3.,
                'pdg_code': 2,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        u = mypartlist[-1]
        antiu = copy.copy(u)
        antiu.set('is_part', False)

        # A quark D and its antiparticle
        mypartlist.append(
            base_objects.Particle({
                'name': 'd',
                'antiname': 'd~',
                'spin': 2,
                'color': 3,
                'mass': 'zero',
                'width': 'zero',
                'texname': 'd',
                'antitexname': '\bar d',
                'line': 'straight',
                'charge': -1. / 3.,
                'pdg_code': 1,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        d = mypartlist[-1]
        antid = copy.copy(d)
        antid.set('is_part', False)

        # A photon
        mypartlist.append(
            base_objects.Particle({
                'name': 'a',
                'antiname': 'a',
                'spin': 3,
                'color': 1,
                'mass': 'zero',
                'width': 'zero',
                'texname': '\gamma',
                'antitexname': '\gamma',
                'line': 'wavy',
                'charge': 0.,
                'pdg_code': 22,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))

        a = mypartlist[-1]

        # A Z
        mypartlist.append(
            base_objects.Particle({
                'name': 'z',
                'antiname': 'z',
                'spin': 3,
                'color': 1,
                'mass': 'MZ',
                'width': 'WZ',
                'texname': 'Z',
                'antitexname': 'Z',
                'line': 'wavy',
                'charge': 0.,
                'pdg_code': 23,
                'propagating': True,
                'is_part': True,
                'self_antipart': True
            }))
        z = mypartlist[-1]

        # Gluon and photon couplings to quarks
        myinterlist.append(base_objects.Interaction({
                      'id': 1,
                      'particles': base_objects.ParticleList(\
                                            [antiu, \
                                             u, \
                                             g]),
                      'color': [],
                      'lorentz':['L1'],
                      'couplings':{(0, 0):'GQQ'},
                      'orders':{'QCD':1}}))

        myinterlist.append(base_objects.Interaction({
                      'id': 2,
                      'particles': base_objects.ParticleList(\
                                            [antiu, \
                                             u, \
                                             a]),
                      'color': [],
                      'lorentz':['L1'],
                      'couplings':{(0, 0):'GQED'},
                      'orders':{'QED':1}}))

        myinterlist.append(base_objects.Interaction({
                      'id': 3,
                      'particles': base_objects.ParticleList(\
                                            [antid, \
                                             d, \
                                             g]),
                      'color': [],
                      'lorentz':['L1'],
                      'couplings':{(0, 0):'GQQ'},
                      'orders':{'QCD':1}}))

        myinterlist.append(base_objects.Interaction({
                      'id': 4,
                      'particles': base_objects.ParticleList(\
                                            [antid, \
                                             d, \
                                             a]),
                      'color': [],
                      'lorentz':['L1'],
                      'couplings':{(0, 0):'GQED'},
                      'orders':{'QED':1}}))

        # 3 gluon vertiex
        myinterlist.append(base_objects.Interaction({
                      'id': 5,
                      'particles': base_objects.ParticleList(\
                                            [g] * 3),
                      'color': [],
                      'lorentz':['L1'],
                      'couplings':{(0, 0):'G'},
                      'orders':{'QCD':1}}))

        # Coupling of Z to quarks

        myinterlist.append(base_objects.Interaction({
                      'id': 6,
                      'particles': base_objects.ParticleList(\
                                            [antiu, \
                                             u, \
                                             z]),
                      'color': [],
                      'lorentz':['L1', 'L2'],
                      'couplings':{(0, 0):'GUZ1', (0, 1):'GUZ2'},
                      'orders':{'QED':1}}))

        myinterlist.append(base_objects.Interaction({
                      'id': 7,
                      'particles': base_objects.ParticleList(\
                                            [antid, \
                                             d, \
                                             z]),
                      'color': [],
                      'lorentz':['L1', 'L2'],
                      'couplings':{(0, 0):'GDZ1', (0, 0):'GDZ2'},
                      'orders':{'QED':1}}))

        mymodel = base_objects.Model()
        mymodel.set('particles', mypartlist)
        mymodel.set('interactions', myinterlist)

        procs = [[2, -2, 21, 21], [2, -2, 2, -2]]
        amplitudes = diagram_generation.AmplitudeList()

        for proc in procs:
            # Define the multiprocess
            my_leglist = base_objects.LegList([\
                base_objects.Leg({'id': id, 'state': True}) for id in proc])

            my_leglist[0].set('state', False)
            my_leglist[1].set('state', False)

            my_process = base_objects.Process({
                'legs': my_leglist,
                'model': mymodel
            })
            my_amplitude = diagram_generation.Amplitude(my_process)
            amplitudes.append(my_amplitude)

        # Calculate diagrams for all processes

        subprocess_group = group_subprocs.SubProcessGroup.\
                           group_amplitudes(amplitudes, "madevent")[0]

        # Test amp2 lines
        helas_writer = helas_call_writers.PythonUFOHelasCallWriter(mymodel)
        python_exporter = export_python.ProcessExporterPython(
            subprocess_group, helas_writer)

        amp2_lines = \
                 python_exporter.get_amp2_lines(subprocess_group.\
                                        get('matrix_elements')[0],
                                        subprocess_group.get('diagram_maps')[0])
        self.assertEqual(amp2_lines, [
            'self.amp2[0]+=abs(amp[0]*amp[0].conjugate())',
            'self.amp2[1]+=abs(amp[1]*amp[1].conjugate())',
            'self.amp2[2]+=abs(amp[2]*amp[2].conjugate())'
        ])
    def test_run_python_matrix_element(self):
        """Test a complete running of a Python matrix element without
        writing any files"""

        # Import the SM
        sm_path = import_ufo.find_ufo_path('sm')
        model = import_ufo.import_model(sm_path)

        myleglist = base_objects.LegList()

        myleglist.append(
            base_objects.Leg({
                'id': -11,
                'state': False,
                'number': 1
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 11,
                'state': False,
                'number': 2
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 3
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 4
            }))
        myleglist.append(
            base_objects.Leg({
                'id': 22,
                'state': True,
                'number': 5
            }))

        myproc = base_objects.Process({'legs': myleglist, 'model': model})

        myamplitude = diagram_generation.Amplitude({'process': myproc})

        mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)

        # Create only the needed aloha routines
        wanted_lorentz = mymatrixelement.get_used_lorentz()

        aloha_model = create_aloha.AbstractALOHAModel(model.get('name'))
        aloha_model.compute_subset(wanted_lorentz)

        # Write out the routines in Python
        aloha_routines = []
        for routine in aloha_model.values():
            aloha_routines.append(routine.write(output_dir = None,
                                                language = 'Python').\
                                  replace('import wavefunctions',
                                          'import aloha.template_files.wavefunctions as wavefunctions'))
        # Define the routines to be available globally
        for routine in aloha_routines:
            exec(routine, globals())

        # Write the matrix element(s) in Python
        mypythonmodel = helas_call_writers.PythonUFOHelasCallWriter(\
                                                             model)
        exporter = export_python.ProcessExporterPython(\
                                                     mymatrixelement,
                                                     mypythonmodel)
        matrix_methods = exporter.get_python_matrix_methods()

        # Calculate parameters and couplings
        full_model = model_reader.ModelReader(model)

        full_model.set_parameters_and_couplings()

        # Define a momentum
        p = [[
            0.5000000e+03, 0.0000000e+00, 0.0000000e+00, 0.5000000e+03,
            0.0000000e+00
        ],
             [
                 0.5000000e+03, 0.0000000e+00, 0.0000000e+00, -0.5000000e+03,
                 0.0000000e+00
             ],
             [
                 0.4585788e+03, 0.1694532e+03, 0.3796537e+03, -0.1935025e+03,
                 0.6607249e-05
             ],
             [
                 0.3640666e+03, -0.1832987e+02, -0.3477043e+03, 0.1063496e+03,
                 0.7979012e-05
             ],
             [
                 0.1773546e+03, -0.1511234e+03, -0.3194936e+02, 0.8715287e+02,
                 0.1348699e-05
             ]]

        # Evaluate the matrix element for the given momenta

        answer = 1.39189717257175028e-007
        for process in matrix_methods.keys():
            # Define Python matrix element for process
            exec(matrix_methods[process])
            # Calculate the matrix element for the momentum p
            value = eval("Matrix_0_epem_aaa().smatrix(p, full_model)")
            self.assertTrue(abs(value-answer)/answer < 1e-6,
                            "Value is: %.9e should be %.9e" % \
                            (abs(value), answer))
    def __init__(self, subproc_group, helicity_model, parent_folder, namespace):
    
        # Path to parent folder where the whole process is exported
        self.parent_folder = parent_folder

        # We want the leptons to be split, but still be inside the same class,
        # so we do the splitting here.
        # What we get is an instance of 'HelasMatrixElementList', which is just like a 
        # python list of 'HelasMatrixElement' objects
        
        if isinstance(subproc_group, group_subprocs.SubProcessGroupList):
            self.matrix_elements = subproc_group.split_lepton_grouping().get_matrix_elements()
        
        elif isinstance(subproc_group, group_subprocs.SubProcessGroup):
            temp_group = group_subprocs.SubProcessGroupList([subproc_group])
            self.matrix_elements = temp_group.split_lepton_grouping().get_matrix_elements()
        
        else:
            raise base_objects.PhysicsObject.PhysicsObjectError, "Wrong object type for subproc_group"

        self.processes = sum([me.get('processes') for \
                              me in self.matrix_elements], [])
        self.processes.extend(sum([me.get_mirror_processes() for \
                              me in self.matrix_elements], []))

        self.nprocesses = len(self.matrix_elements)
        self.nprocesses += sum([1 for me in self.matrix_elements if me.get('has_mirror_process')])

        self.process_string = self.processes[0].base_string()
        self.process_number = self.processes[0].get('id')

        # Retrieve model, set model name
        self.model = self.matrix_elements[0].get('processes')[0].get('model')
        self.model_name = OneProcessExporterMoMEMta.get_model_name(self.model.get('name'))

        # Namespace for the C++ code, ie the basename of the parent folder _ the model name
        self.namespace = namespace + "_" + self.model_name

        # Process name: string of type "pp_ttx_..."
        self.process_name = self.get_process_name()

        # C++ class for the whole process
        self.process_class = "P%d_%s" % (self.process_number, self.process_name)

        # Directory where all the files will be written
        self.path = os.path.join(parent_folder, 'SubProcesses', self.process_class)

        self.helas_call_writer = helicity_model

        if not isinstance(self.helas_call_writer, helas_call_writers.CPPUFOHelasCallWriter):
            raise self.OneProcessExporterMoMEMtaError, \
                "helas_call_writer not CPPUFOHelasCallWriter"

        self.nexternal, self.ninitial = \
                        self.matrix_elements[0].get_nexternal_ninitial()
        self.nfinal = self.nexternal - self.ninitial

        # Check if we can use the same helicities for all matrix elements
        hel_matrix = self.get_helicity_matrix(self.matrix_elements[0])
        for me in self.matrix_elements[1:]:
            if self.get_helicity_matrix(me) != hel_matrix:
                raise Exception('Multiple helicities are not supported in mode standalone_cpp_mem.')
            
        # Since all processes have the same helicity structure, this
        # allows us to reuse the same wavefunctions for the
        # different processes
        
        self.wavefunctions = []
        wf_number = 0

        for me in self.matrix_elements:
            for iwf, wf in enumerate(me.get_all_wavefunctions()):
                try:
                    old_wf = \
                           self.wavefunctions[self.wavefunctions.index(wf)]
                    wf.set('number', old_wf.get('number'))
                except ValueError:
                    wf_number += 1
                    wf.set('number', wf_number)
                    self.wavefunctions.append(wf)

        # Also combine amplitudes
        self.amplitudes = helas_objects.HelasAmplitudeList()
        amp_number = 0
        for me in self.matrix_elements:
            for iamp, amp in enumerate(me.get_all_amplitudes()):
                try:
                    old_amp = \
                           self.amplitudes[self.amplitudes.index(amp)]
                    amp.set('number', old_amp.get('number'))
                except ValueError:
                    amp_number += 1
                    amp.set('number', amp_number)
                    self.amplitudes.append(amp)
        diagram = helas_objects.HelasDiagram({'amplitudes': self.amplitudes})
        self.amplitudes = helas_objects.HelasMatrixElement({\
            'diagrams': helas_objects.HelasDiagramList([diagram])})