def split_lepton_grouping(self):
        """Return a list of grouping where they are no groupoing over the leptons."""

        output = SubProcessGroupList()
        for group in self:
            new_mes = {}
            for me in group['matrix_elements']:
                tags = {}
                for proc in me['processes']:
                    ids = proc.get_final_ids_after_decay()
                    ids = tuple(
                        [t if abs(t) in [11, 13, 15] else 0 for t in ids])
                    if ids not in tags:
                        tags[ids] = base_objects.ProcessList()
                    tags[ids].append(proc)
                for tag in tags:
                    new_me = copy.copy(me)
                    new_me['processes'] = tags[tag]
                    if tag not in new_mes:
                        new_mes[tag] = helas_objects.HelasMatrixElementList()
                    new_mes[tag].append(new_me)
            for tag in tags:
                new_group = copy.copy(group)
                new_group['matrix_elements'] = new_mes[tag]
                new_group.set('name', new_group.generate_name(\
                                    new_group['matrix_elements'][0]['processes'][0],
                                    criteria='madweight'))
                output.append(new_group)
        return output
Esempio n. 2
0
def find_os_divergences(fksreal):
    """this function looks for possible on shell contributions 
    to be removed.
    In order to be agnostic on mass hierarchies all splittings
    1->2 3 are investigated, with m1 != 0, m2, m3 != m1
    since these resonances are introduced at the real-emission
    level, one must have m2=0 or m3=0
    """
    if type(fksreal) == fks_base.FKSRealProcess:
        process = fksreal.process
        amplitude = fksreal.amplitude
        from_helas = False

    elif type(fksreal) == fks_helas.FKSHelasRealProcess:
        process = fksreal.matrix_element['processes'][0]
        amplitude = fksreal.matrix_element['base_amplitude']
        from_helas = True

    else:
        raise MadSTRFKSError(
            "Unknown type of fksreal in find_os_divergences: " + type(fksreal))

    model = process['model']
    forbidden = process['forbidden_particles']
    # take account of the orders for the on shell processes
    weighted_order = process['orders']['WEIGHTED']

    fksreal.os_amplitudes = []
    fksreal.os_ids = []
    fksreal.os_daughter_pos = []
    fksreal.os_diagrams = []

    # this is a counter to be returned
    n_os = 0

    # focus only on final state legs
    final_legs = [copy.copy(l) for l in process['legs'] if l['state']]
    for leg_2 in final_legs:
        for leg_3 in [l for l in final_legs if l['number'] > leg_2['number']]:
            # one of the two legs must be massless
            if not leg_2['massless'] and not leg_3['massless']:
                continue
            # prepare the leglist for the 'on shell' process, which should
            # not contain leg_2 and leg_3, but should contain their mother particle
            # if it exists
            other_legs = [copy.copy(l) for l in process['legs'] if \
                    l != leg_2 and l != leg_3]
            assert (len(other_legs) == (len(process['legs']) - 2))
            leg_2_part = model.get('particle_dict')[leg_2['id']]
            leg_3_part = model.get('particle_dict')[leg_3['id']]
            interactions = [inte for inte in model.get('interaction_dict').values() \
                            if len(inte['particles']) == 3 and \
                                leg_2_part in inte['particles'] and \
                                leg_3_part in inte['particles']]

            for inte in interactions:
                particles = [copy.copy(p) for p in inte['particles']]
                try:
                    particles.remove(leg_2_part)
                    particles.remove(leg_3_part)
                except ValueError:
                    # this is when leg_2 and leg_3 are the same particle
                    # and it appears only once in the interacion, so
                    # the interaction has to be skipped
                    continue
                leg_1_part = particles[0]
                # check that it is massive and its mass it is different from
                # leg_2 and leg_3
                if leg_1_part['mass'].lower() == 'zero' or \
                   leg_1_part['mass'] == leg_2_part['mass'] or \
                   leg_1_part['mass'] == leg_3_part['mass']:
                    continue
                # check that it is not among the forbidden particles
                if leg_1_part.get_pdg_code() in forbidden or \
                   leg_1_part.get_anti_pdg_code() in forbidden:
                    continue
                # this should be the final particle (take the antiparticle as
                # it has to go "into" the interaction)

                leg_1 = MG.Leg({
                    'state': True,
                    'id': leg_1_part.get_anti_pdg_code(),
                    'number': leg_2['number']
                })

                os_legs = [copy.copy(l) for l in other_legs]
                os_legs.insert(leg_2['number'] - 1, leg_1)
                assert (len(os_legs) == (len(process['legs']) - 1))
                # count the occurences of leg 1 in the final state legs
                # only one of them has to be decayed
                nleg_1 = [l['id'] for l in os_legs].count(leg_1['id'])
                # construct the decay chain and the process
                # definition
                leg_1_decay = MG.Leg({'id': leg_1['id'], 'state': False})
                leg_2_decay = MG.Leg({'id': leg_2['id'], 'state': True})
                leg_3_decay = MG.Leg({'id': leg_3['id'], 'state': True})
                decay_chain_legs = MG.LegList(\
                                   [leg_1_decay, leg_2_decay, leg_3_decay])
                decay_chain = MG.Process(\
                              {'model': model,
                               'legs': MG.LegList(decay_chain_legs),
                               'is_decay_chain': True})

                # construct the 'trivial' decay chain to be used when leg_1
                # occurs more than once in the final state legs
                leg_1_decayed = MG.Leg({'id': leg_1['id'], 'state': True})
                trivial_decay_chain_legs = MG.LegList(\
                                   [leg_1_decay, leg_1_decayed])
                trivial_decay_chain = MG.Process(\
                              {'model': model,
                               'legs': MG.LegList(trivial_decay_chain_legs),
                               'is_decay_chain': True})

                decay_chains = MG.ProcessList([decay_chain] + \
                                    [trivial_decay_chain] * (nleg_1 - 1))

                for leg in os_legs:
                    leg['number'] = os_legs.index(leg) + 1
                # the orders in os_procdef refer only to the production process
                # so the orders of the splitting have to be subtracted
                prod_weighted_order = weighted_order - \
                        sum([v * model.get('order_hierarchy')[o] \
                             for o, v in inte['orders'].items()])
                # skip if prod_weighted_order is negative or zero
                # negative prod_weighted_order can lead to strange behaviours
                if prod_weighted_order < 0:
                    continue

                os_procdef =  MG.Process(\
                             {'model': model,
                              'legs': MG.LegList(os_legs),
                              'decay_chains': decay_chains,
                              'orders': {'WEIGHTED': prod_weighted_order}})
                # now generate the amplitude.
                # Do nothing if any InvalidCmd is raised (e.g. charge not conserved)
                # or if no diagrams are there
                # set the logger to CRITICAL in order not to warn about 1 -> 1
                # (trivial) decay chains

                loglevel = logging.getLogger(
                    'madgraph.diagram_generation').level
                logging.getLogger('madgraph.diagram_generation').setLevel(
                    logging.CRITICAL)
                try:
                    os_amp = diagram_generation.DecayChainAmplitude(os_procdef)
                except InvalidCmd:
                    continue
                logging.getLogger('madgraph.diagram_generation').setLevel(
                    loglevel)

                if not all([amp['diagrams'] for amp in os_amp['amplitudes']]):
                    continue
                logger.info(
                    'Process %s has been generated for on-shell subtraction' %
                    os_procdef.input_string())
                n_os += 1
                fksreal.os_amplitudes.append(os_amp)
                fksreal.os_ids.append([leg_1['id'], leg_2['id'], leg_3['id']])
                fksreal.os_daughter_pos.append(
                    [leg_2['number'] - 1, leg_3['number'] - 1])
                fksreal.os_diagrams.append(find_os_diagrams(\
                        amplitude, [leg_1, leg_2, leg_3], from_helas))
    return n_os
Esempio n. 3
0
    def setUp(self):
        if not hasattr(self, 'mymodel') or \
           not hasattr(self, 'myleglist3') or \
           not hasattr(self, 'myproc1') or \
           not hasattr(self, 'myproc3'):

            myleglist1 = MG.LegList()
            # PROCESS: u g > u g
            mylegs = [{
                'id': 2,
                'number': 1,
                'state': False
            }, {
                'id': 21,
                'number': 2,
                'state': False
            }, {
                'id': 2,
                'number': 3,
                'state': True
            }, {
                'id': 21,
                'number': 4,
                'state': True
            }]
            for i in mylegs:
                myleglist1.append(MG.Leg(i))

            myleglist3 = MG.LegList()
            # PROCESS: d d~ > u u~
            mylegs = [{
                'id': 1,
                'number': 1,
                'state': False
            }, {
                'id': -1,
                'number': 2,
                'state': False
            }, {
                'id': 2,
                'number': 3,
                'state': True
            }, {
                'id': -2,
                'number': 4,
                'state': True
            }]
            for i in mylegs:
                myleglist3.append(MG.Leg(i))

            mymodel = import_ufo.import_model('sm')

            dict1 = {
                'legs': myleglist1,
                'orders': {
                    'QCD': 10,
                    'QED': 0
                },
                'model': mymodel,
                'id': 1,
                'required_s_channels': [],
                'forbidden_s_channels': [],
                'forbidden_particles': [],
                'is_decay_chain': False,
                'orders': {
                    'QED': 0,
                    'WEIGHTED': 2
                },
                'perturbation_couplings': ['QCD'],
                'decay_chains': MG.ProcessList(),
                'overall_orders': {}
            }

            dict1_qed = {
                'legs': myleglist1,
                'orders': {
                    'QCD': 10,
                    'QED': 0
                },
                'model': mymodel,
                'id': 1,
                'required_s_channels': [],
                'forbidden_s_channels': [],
                'forbidden_particles': [],
                'is_decay_chain': False,
                'orders': {
                    'QED': 0,
                    'WEIGHTED': 2
                },
                'perturbation_couplings': ['QED'],
                'decay_chains': MG.ProcessList(),
                'overall_orders': {}
            }

            dict3 = {
                'legs': myleglist3,
                'orders': {
                    'QCD': 10,
                    'QED': 0
                },
                'model': mymodel,
                'id': 1,
                'required_s_channels': [],
                'forbidden_s_channels': [],
                'forbidden_particles': [],
                'is_decay_chain': False,
                'orders': {
                    'QED': 0,
                    'WEIGHTED': 2
                },
                'perturbation_couplings': ['QCD'],
                'decay_chains': MG.ProcessList(),
                'overall_orders': {}
            }

            dict3_qed = {
                'legs': myleglist3,
                'orders': {
                    'QCD': 10,
                    'QED': 0
                },
                'model': mymodel,
                'id': 1,
                'required_s_channels': [],
                'forbidden_s_channels': [],
                'forbidden_particles': [],
                'is_decay_chain': False,
                'orders': {
                    'QED': 0,
                    'WEIGHTED': 2
                },
                'perturbation_couplings': ['QED'],
                'decay_chains': MG.ProcessList(),
                'overall_orders': {}
            }

            testFKSHelasObjects.mymodel = mymodel
            testFKSHelasObjects.myleglist3 = myleglist3
            testFKSHelasObjects.myproc1 = MG.Process(dict1)
            testFKSHelasObjects.myproc3 = MG.Process(dict3)
            testFKSHelasObjects.myproc1_qed = MG.Process(dict1_qed)
            testFKSHelasObjects.myproc3_qed = MG.Process(dict3_qed)
Esempio n. 4
0
    def test_ungrouping_lepton(self):
        """check that the routines which ungroup the process for the muon/electron processes
        works as expected"""

        # Setup A simple model
        mypartlist = base_objects.ParticleList()
        myinterlist = base_objects.InteractionList()

        # 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 quark C and its antiparticle
        mypartlist.append(
            base_objects.Particle({
                'name': 'c',
                'antiname': 'c~',
                'spin': 2,
                'color': 3,
                'mass': 'zero',
                'width': 'zero',
                'texname': 'u',
                'antitexname': '\bar u',
                'line': 'straight',
                'charge': 2. / 3.,
                'pdg_code': 4,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        c = mypartlist[-1]
        antic = copy.copy(c)
        antic.set('is_part', False)

        # electron/positront
        mypartlist.append(
            base_objects.Particle({
                'name': 'e-',
                'antiname': 'e+',
                'spin': 2,
                'color': 1,
                'mass': 'zero',
                'width': 'zero',
                'texname': 'u',
                'antitexname': '\bar u',
                'line': 'straight',
                'charge': 1,
                'pdg_code': 11,
                'propagating': True,
                'is_part': True,
                'self_antipart': False
            }))
        e = mypartlist[-1]
        antie = copy.copy(e)
        mu = copy.copy(e)
        antie.set('is_part', False)
        mu.set('name', 'mu-')
        mu.set('antiname', 'mu+')
        mu.set('pdg_code', 13)
        mypartlist.append(mu)
        antimu = copy.copy(mu)
        antimu.set('is_part', False)

        # 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]

        # Coupling of Z to quarks

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

        myinterlist.append(base_objects.Interaction({
                      'id': 2,
                      'particles': base_objects.ParticleList(\
                                            [antid, \
                                             d, \
                                             z]),
                      'color': [color.ColorString([color.T(1,0)])],
                      'lorentz':['FFV1', 'FFV2'],
                      'couplings':{(0, 0):'GDZ1', (0, 1):'GDZ2'},
                      'orders':{'QED':1}}))

        myinterlist.append(base_objects.Interaction({
                      'id': 3,
                      'particles': base_objects.ParticleList(\
                                            [antic, \
                                             c, \
                                             z]),
                      'color': [color.ColorString([color.T(1,0)])],
                      'lorentz':['FFV1', 'FFV2'],
                      'couplings':{(0, 0):'GUZ1', (0, 1):'GUZ2'},
                      'orders':{'QED':1}}))

        # Coupling of Z to leptons
        myinterlist.append(base_objects.Interaction({
                      'id': 4,
                      'particles': base_objects.ParticleList(\
                                            [antie, \
                                             e, \
                                             z]),
                      'color': [color.ColorString()],
                      'lorentz':['FFV1', 'FFV2'],
                      'couplings':{(0, 0):'GLZ1', (0, 1):'GLZ2'},
                      'orders':{'QED':1}}))

        # Coupling of Z to leptons
        myinterlist.append(base_objects.Interaction({
                      'id': 5,
                      'particles': base_objects.ParticleList(\
                                            [antimu, \
                                             mu, \
                                             z]),
                      'color': [color.ColorString()],
                      'lorentz':['FFV1', 'FFV2'],
                      'couplings':{(0, 0):'GLZ1', (0, 1):'GLZ2'},
                      'orders':{'QED':1}}))

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

        procs = [[1, -1, 23], [2, -2, 23], [4, -4, 23]]
        decays = [[23, 11, -11], [23, 13, -13]]
        coreamplitudes = diagram_generation.AmplitudeList()
        decayamplitudes = diagram_generation.AmplitudeList()
        decayprocs = base_objects.ProcessList()

        #Building the basic objects
        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)
            my_amplitude.set('has_mirror_process', True)
            coreamplitudes.append(my_amplitude)

        for proc in decays:
            # 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_process = base_objects.Process({
                'legs': my_leglist,
                'model': mymodel,
                'is_decay_chain': True
            })
            my_amplitude = diagram_generation.Amplitude(my_process)
            decayamplitudes.append(my_amplitude)
            decayprocs.append(my_process)

        decays = diagram_generation.DecayChainAmplitudeList([\
                         diagram_generation.DecayChainAmplitude({\
                                            'amplitudes': decayamplitudes})])

        decay_chains = diagram_generation.DecayChainAmplitude({\
            'amplitudes': coreamplitudes,
            'decay_chains': decays})

        dc_subproc_group = group_subprocs.DecayChainSubProcessGroup.\
              group_amplitudes(\
                 diagram_generation.DecayChainAmplitudeList([decay_chains]))

        subproc_groups = \
                       dc_subproc_group.generate_helas_decay_chain_subproc_groups()

        ######################
        ##  Make the test!! ##
        ######################
        self.assertEqual(len(subproc_groups), 1)
        subproc_groups = subproc_groups.split_lepton_grouping()
        self.assertEqual(len(subproc_groups), 2)

        # check that indeed
        for group in subproc_groups:
            self.assertEqual(len(group['matrix_elements']), 2)
            has_muon = any(
                abs(l['id']) == 13 for l in group['matrix_elements'][0]
                ['processes'][0]['decay_chains'][0]['legs'])
            for me in group['matrix_elements']:
                if abs(me['processes'][0]['legs'][0]['id']) == 1:
                    self.assertEqual(len(me['processes']), 1)
                else:
                    self.assertEqual(len(me['processes']), 2)
                for proc in me['processes']:
                    for dec in proc['decay_chains']:
                        if has_muon:
                            self.assertFalse(
                                any(abs(l['id']) == 11 for l in dec['legs']))
                        else:
                            self.assertFalse(
                                any(abs(l['id']) == 13 for l in dec['legs']))

            self.assertNotEqual(group['name'], 'qq_z_z_ll')
            if has_muon:
                self.assertEqual(group['name'], 'qq_z_z_mummup')
            else:
                self.assertEqual(group['name'], 'qq_z_z_emep')
            group['name']