def test_set_color_links(self):
     """tests that the set_color_links of a FKSHelasProcess
     returns the correct list of color_links."""
     #ug> ug
     fks1 = fks_base.FKSProcess(self.myproc1)
     #ug>gu
     fks1_qed = fks_base.FKSProcess(self.myproc1_qed)
     me_list = []
     me_list_qed = []
     me_id_list = []
     me_id_list_qed = []
     pdg_list1 = []
     pdg_list1_qed = []
     real_amp_list1 = diagram_generation.AmplitudeList()
     real_amp_list1_qed = diagram_generation.AmplitudeList()
     fks1.generate_reals(pdg_list1, real_amp_list1)
     fks1_qed.generate_reals(pdg_list1_qed, real_amp_list1_qed)
     helas_born_proc = fks_helas.FKSHelasProcess(fks1, me_list, me_id_list)
     helas_born_proc_qed = fks_helas.FKSHelasProcess(\
                                 fks1_qed,me_list_qed,me_id_list_qed)
     helas_born_proc.set_color_links()
     helas_born_proc_qed.set_color_links()
     legpair = [link['link'] for link in helas_born_proc.color_links]
     legpair_qed = [
         link['link'] for link in helas_born_proc_qed.color_links
     ]
     tar_legpair = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
     tar_legpair_qed = [[1, 4]]
     self.assertEqual(legpair, tar_legpair)
     self.assertEqual(legpair_qed, tar_legpair_qed)
Beispiel #2
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)
Beispiel #3
0
    def group_amplitudes(amplitudes, criteria='madevent', matrix_elements_opts={}):
        """Return a SubProcessGroupList with the amplitudes divided
        into subprocess groups"""

        assert isinstance(amplitudes, diagram_generation.AmplitudeList), \
                  "Argument to group_amplitudes must be AmplitudeList"

        if not criteria:
            criteria = 'madevent'
        assert criteria in ['madevent', 'madweight']

        logger.info("Organizing processes into subprocess groups")

        process_classes = SubProcessGroup.find_process_classes(amplitudes,criteria)
        ret_list = SubProcessGroupList()
        process_class_numbers = sorted(list(set(process_classes.values())))
        for num in process_class_numbers:
            amp_nums = [key for (key, val) in process_classes.items() if \
                          val == num]
            group = SubProcessGroup({'matrix_element_opts':matrix_elements_opts})
            group.set('amplitudes',
                      diagram_generation.AmplitudeList([amplitudes[i] for i in \
                                                        amp_nums]))
            group.set('number', group.get('amplitudes')[0].get('process').\
                                                                     get('id'))
            group.set('name', group.generate_name(\
                                    group.get('amplitudes')[0].get('process'),
                                    criteria=criteria))
            ret_list.append(group)

        return ret_list
Beispiel #4
0
    def setup(self):
        """ Special tasks when switching to this interface """

        # Refresh all the interface stored value as things like generated
        # processes and amplitudes are not to be reused in between different
        # interfaces
        # Clear history, amplitudes and matrix elements when a model is imported
        # Remove previous imports, generations and outputs from history
        self.history.clean(remove_bef_last='import',
                           to_keep=['set','load','import', 'define'])
        # Reset amplitudes and matrix elements
        self._done_export=False
        self._curr_amps = diagram_generation.AmplitudeList()
        self._curr_matrix_elements = helas_objects.HelasMultiProcess()
        self._v4_export_formats = []
        self._nlo_modes_for_completion = ['all','real']
        self._export_formats = [ 'madevent', 'aloha' ]
        # Do not force NLO model as the user might have asked for reals only.
        # It will anyway be forced later if he attempts virt= or all=.
        self.validate_model(loop_type='real_init', stop=False)
        # Set where to look for CutTools installation.
        # In further versions, it will be set in the same manner as _mgme_dir so that
        # the user can chose its own CutTools distribution.
        self._cuttools_dir=str(pjoin(self._mgme_dir,'vendor','CutTools'))
        if not os.path.isdir(pjoin(self._cuttools_dir, 'src','cts')):
            logger.warning(('Warning: Directory %s is not a valid CutTools directory.'+\
                           'Using default CutTools instead.') % \
                             self._cuttools_dir)
            self._cuttools_dir=str(pjoin(self._mgme_dir,'vendor','CutTools'))
    def generate_matrix_elements(self):
        """Create a HelasMultiProcess corresponding to the amplitudes
        in self"""

        if not self.get('amplitudes'):
            raise self.PhysicsObjectError, \
                  "Need amplitudes to generate matrix_elements"

        amplitudes = copy.copy(self.get('amplitudes'))

        # The conditional statement tests whether we are dealing with a
        # loop induced process. We must set compute_loop_nc to True here
        # since the knowledge of the power of Nc coming from potential
        # loop color trace is necessary for the loop induced output with MadEvent
        if isinstance(amplitudes[0], loop_diagram_generation.LoopAmplitude):
            self.set(
                'matrix_elements',
                loop_helas_objects.LoopHelasProcess.generate_matrix_elements(
                    amplitudes,
                    compute_loop_nc=True,
                    matrix_element_opts=self['matrix_element_opts']))
        else:
            self.set('matrix_elements',
                 helas_objects.HelasMultiProcess.\
                                   generate_matrix_elements(amplitudes))

        self.set('amplitudes', diagram_generation.AmplitudeList())
Beispiel #6
0
    def group_amplitudes(decay_chain_amps, criteria='madevent', matrix_elements_opts={}):
        """Recursive function. Starting from a DecayChainAmplitude,
        return a DecayChainSubProcessGroup with the core amplitudes
        and decay chains divided into subprocess groups"""

        assert isinstance(decay_chain_amps, diagram_generation.DecayChainAmplitudeList), \
                  "Argument to group_amplitudes must be DecayChainAmplitudeList"
        if criteria in ['matrix', 'standalone','pythia8','standalone_cpp', False]:
            criteria = 'madevent'
        assert criteria in ['madevent', 'madweight']
        
        # Collect all amplitudes
        amplitudes = diagram_generation.AmplitudeList()
        for amp in decay_chain_amps:
            amplitudes.extend(amp.get('amplitudes'))

        # Determine core process groups
        core_groups = SubProcessGroup.group_amplitudes(amplitudes, criteria)

        dc_subproc_group = DecayChainSubProcessGroup(\
            {'core_groups': core_groups,
             'decay_chain_amplitudes': decay_chain_amps})

        decays = diagram_generation.DecayChainAmplitudeList()

        # Recursively determine decay chain groups
        for decay_chain_amp in decay_chain_amps:
            decays.extend(decay_chain_amp.get('decay_chains'))
                          
        if decays:
            dc_subproc_group.get('decay_groups').append(\
                DecayChainSubProcessGroup.group_amplitudes(decays, criteria))

        return dc_subproc_group
    def test_find_symmetry_uu_tt_with_subprocess_group(self):
        """Test the find_symmetry function for subprocess groups"""

        procs = [[2,2,6,6]]
        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':self.base_model_4ferm})
            my_amplitude = diagram_generation.Amplitude(my_process)
            amplitudes.append(my_amplitude)

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

        symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\
                                                                  subproc_group)

        self.assertEqual(len([s for s in symmetry if s > 0]), 1)

        self.assertEqual(symmetry,
                         [1])

        return
Beispiel #8
0
 def default_setup(self):
     """Default values for all properties"""
     super(FKSMultiProcess, self).default_setup()
     self['real_amplitudes'] = diagram_generation.AmplitudeList()
     self['pdgs'] = []
     self['born_processes'] = FKSProcessList()
     if not 'OLP' in list(self.keys()):
         self['OLP'] = 'MadLoop'
         self['ncores_for_proc_gen'] = 0
Beispiel #9
0
    def test_find_symmetry_qq_qqg_with_subprocess_group(self):
        """Test the find_symmetry function for subprocess groups"""

        procs = [[2,-2,2,-2,21], [2,2,2,2,21]]
        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':self.base_model})
            my_amplitude = diagram_generation.Amplitude(my_process)
            amplitudes.append(my_amplitude)

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

        symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\
                                                subproc_group)

        self.assertEqual(len([s for s in symmetry if s > 0]), 19)

        self.assertEqual(symmetry,[1, 1, 1, 1, -2, -3, -4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -8, -9, -10, -11, -12, -13, -14, -18, -19])

        return

        # The test below doesn't apply with the new way of determining
        # config symmetry for subprocess groups, since we don't demand
        # that symmetric diagrams have identical particles.

        # Check that the momentum assignments work
        matrix_element = \
                     subproc_group.get('matrix_elements')[1]
        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
            iamp = subproc_group.get('diagram_maps')[1].index(isym+1)
            isymamp = subproc_group.get('diagram_maps')[1].index(-sym)
            me_value, amp2 = evaluator.evaluate_matrix_element(\
                                              matrix_element, new_p)
            self.assertAlmostEqual(amp2[iamp], amp2_org[isymamp])
Beispiel #10
0
    def default_setup(self):
        """Define object and give default values"""

        self['number'] = 0
        self['name'] = ""
        self['amplitudes'] = diagram_generation.AmplitudeList()
        self['matrix_elements'] = helas_objects.HelasMatrixElementList()
        self['mapping_diagrams'] = []
        self['diagram_maps'] = {}
        self['diagrams_for_configs'] = []
        self['amplitude_map'] = {}
Beispiel #11
0
    def test_find_symmetry_decay_chain_with_subprocess_group(self):
        """Test the find_symmetry function for subprocess groups"""

        procs = [[2, -1, 24, 21, 21], [-3, 4, 24, 21, 21]]
        decays = [[24, -11, 12], [24, -13, 14]]
        amplitudes = diagram_generation.AmplitudeList()
        decay_amps = diagram_generation.DecayChainAmplitudeList()

        for proc, decay in zip(procs, 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_leglist[1].set('state', False)

            my_decaylegs = base_objects.LegList([\
                base_objects.Leg({'id': id, 'state': True}) for id in decay])

            my_decaylegs[0].set('state', False)
            my_process = base_objects.Process({
                'legs': my_leglist,
                'model': self.base_model
            })
            my_decay_proc = base_objects.Process({
                'legs': my_decaylegs,
                'model': self.base_model,
                'is_decay_chain': True
            })
            my_amplitude = diagram_generation.Amplitude(my_process)
            my_decay = diagram_generation.DecayChainAmplitude(my_decay_proc)
            amplitudes.append(my_amplitude)
            decay_amps.append(my_decay)

        amplitudes = diagram_generation.DecayChainAmplitudeList([\
                diagram_generation.DecayChainAmplitude({\
                        'amplitudes': amplitudes,
                        'decay_chains': decay_amps})])

        subproc_groups = \
                  group_subprocs.DecayChainSubProcessGroup.group_amplitudes(\
                         amplitudes,"madevent").generate_helas_decay_chain_subproc_groups()
        self.assertEqual(len(subproc_groups), 1)

        subproc_group = subproc_groups[0]
        self.assertEqual(len(subproc_group.get('matrix_elements')), 2)

        symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\
                                                subproc_group)

        self.assertEqual(len([s for s in symmetry if s > 0]), 5)

        self.assertEqual(symmetry, [1, -1, 1, 1, 1, -4, -5, 1])
Beispiel #12
0
    def generate_matrix_elements(self):
        """Create a HelasMultiProcess corresponding to the amplitudes
        in self"""

        if not self.get('amplitudes'):
            raise self.PhysicsObjectError, \
                  "Need amplitudes to generate matrix_elements"

        amplitudes = copy.copy(self.get('amplitudes'))

        self.set('matrix_elements',
                 helas_objects.HelasMultiProcess.\
                                   generate_matrix_elements(amplitudes))

        self.set('amplitudes', diagram_generation.AmplitudeList())
Beispiel #13
0
    def generate_helas_decay_chain_subproc_groups(self):
        """Combine core_groups and decay_groups to give
        HelasDecayChainProcesses and new diagram_maps.
        """

        # Combine decays
        matrix_elements = \
                helas_objects.HelasMultiProcess.generate_matrix_elements(\
                              diagram_generation.AmplitudeList(\
                                            self.get('decay_chain_amplitudes')))


        # For each matrix element, check which group it should go into and
        # calculate diagram_maps
        me_assignments = {}
        for me in matrix_elements:
            group_assignment = self.assign_group_to_decay_process(\
                                    me.get('processes')[0])
            assert group_assignment
            try:
                me_assignments[group_assignment].append(me)
            except KeyError:
                me_assignments[group_assignment] = [me]

        # Create subprocess groups corresponding to the different
        # group_assignments

        subproc_groups = SubProcessGroupList()
        for key in sorted(me_assignments.keys()):
            group = SubProcessGroup()
            group.set('matrix_elements', helas_objects.HelasMatrixElementList(\
                me_assignments[key]))
            group.set('number', group.get('matrix_elements')[0].\
                                      get('processes')[0].get('id'))
            group.set('name', group.generate_name(\
                              group.get('matrix_elements')[0].\
                                    get('processes')[0]))
            subproc_groups.append(group)
        
        return subproc_groups
Beispiel #14
0
 def get_virt_amplitudes(self):
     """return an amplitudelist with the virt amplitudes"""
     return diagram_generation.AmplitudeList([born.virt_amp \
             for born in self['born_processes'] if born.virt_amp])
Beispiel #15
0
    def do_display(self, line, output=sys.stdout):
        # if we arrive here it means that a _fks_display_opts has been chosen
        args = self.split_arg(line)
        #check the validity of the arguments
        self.check_display(args)

        if args[0] in ['diagrams', 'processes', 'diagrams_text']:
            get_amps_dict = {
                'real': self._fks_multi_proc.get_real_amplitudes,
                'born': self._fks_multi_proc.get_born_amplitudes,
                'loop': self._fks_multi_proc.get_virt_amplitudes
            }
            if args[0] == 'diagrams':
                if len(args) >= 2 and args[1] in list(get_amps_dict.keys()):
                    get_amps = get_amps_dict[args[1]]
                    self._curr_amps = get_amps()
                    #check that if one requests the virt diagrams, there are virt_amplitudes
                    if args[1] == 'loop' and len(self._curr_amps) == 0:
                        raise self.InvalidCmd(
                            'No virtuals have been generated')
                    self.draw(' '.join(args[2:]), type=args[1])
                else:
                    for diag_type, get_amps in get_amps_dict.items():
                        self._curr_amps = get_amps()
                        self.draw(' '.join(args[1:]), Dtype=diag_type)
                # set _curr_amps back to empty
                self._curr_amps = diagram_generation.AmplitudeList()

            if args[0] == 'diagrams_text':
                if len(args) >= 2 and args[1] in list(get_amps_dict.keys()):
                    get_amps = get_amps_dict[args[1]]
                    self._curr_amps = get_amps()
                    #check that if one requests the virt diagrams, there are virt_amplitudes
                    if args[1] in ['virt', 'loop'] and len(
                            self._curr_amps) == 0:
                        raise self.InvalidCmd(
                            'No virtuals have been generated')
                    text = "\n".join(
                        [amp.nice_string() for amp in self._curr_amps])
                else:
                    text = 'Born diagrams:\n'
                    text += '\n'.join(amp.nice_string()
                                      for amp in get_amps_dict['born']())
                    text += '\n\nReal diagrams:'
                    text += '\n'.join(amp.nice_string()
                                      for amp in get_amps_dict['real']())
                    text += '\n\nLoop diagrams:\n'
                    text += '\n'.join(amp.nice_string()
                                      for amp in get_amps_dict['loop']())
                pydoc.pager(text)

                # set _curr_amps back to empty
                self._curr_amps = diagram_generation.AmplitudeList()

            elif args[0] == 'processes':
                if len(args) >= 2 and args[1] in list(get_amps_dict.keys()):
                    get_amps = get_amps_dict[args[1]]
                    self._curr_amps = get_amps()
                    #check that if one requests the virt diagrams, there are virt_amplitudes
                    if args[1] in ['virt', 'loop'] and len(
                            self._curr_amps) == 0:
                        raise self.InvalidCmd(
                            'No virtuals have been generated')
                    print('\n'.join(amp.nice_string_processes()
                                    for amp in self._curr_amps))
                else:
                    print('Born processes:')
                    print('\n'.join(amp.nice_string_processes()
                                    for amp in get_amps_dict['born']()))
                    print('Real processes:')
                    print('\n'.join(amp.nice_string_processes()
                                    for amp in get_amps_dict['real']()))
                    print('Loop processes:')
                    print('\n'.join(amp.nice_string_processes()
                                    for amp in get_amps_dict['loop']()))
                # set _curr_amps back to empty
                self._curr_amps = diagram_generation.AmplitudeList()

        else:
            mg_interface.MadGraphCmd.do_display(self, line, output)
Beispiel #16
0
    def ML5export(self, nojpeg=False, main_file_name=""):
        """Export a generated amplitude to file"""
        def generate_matrix_elements(self):
            """Helper function to generate the matrix elements before exporting"""

            # Sort amplitudes according to number of diagrams,
            # to get most efficient multichannel output
            self._curr_amps.sort(lambda a1, a2: a2.get_number_of_diagrams() - \
                                 a1.get_number_of_diagrams())

            cpu_time1 = time.time()
            ndiags = 0
            if not self._curr_matrix_elements.get_matrix_elements():
                self._curr_matrix_elements = \
                    loop_helas_objects.LoopHelasProcess(self._curr_amps,
                    optimized_output = self.options['loop_optimized_output'])
                ndiags = sum([len(me.get('diagrams')) for \
                              me in self._curr_matrix_elements.\
                              get_matrix_elements()])
                # assign a unique id number to all process
                uid = 0
                for me in self._curr_matrix_elements.get_matrix_elements():
                    uid += 1  # update the identification number
                    me.get('processes')[0].set('uid', uid)

            cpu_time2 = time.time()
            return ndiags, cpu_time2 - cpu_time1

        # Start of the actual routine
        ndiags, cpu_time = generate_matrix_elements(self)

        calls = 0

        path = self._export_dir
        if self._export_format in self.supported_ML_format:
            path = pjoin(path, 'SubProcesses')

        cpu_time1 = time.time()

        # Pick out the matrix elements in a list
        matrix_elements = \
                        self._curr_matrix_elements.get_matrix_elements()

        # Fortran MadGraph5_aMC@NLO Standalone
        if self._export_format in self.supported_ML_format:
            for me in matrix_elements:
                calls = calls + \
                        self._curr_exporter.generate_subprocess_directory_v4(\
                            me, self._curr_fortran_model)
            # If all ME's do not share the same maximum loop vertex rank and the
            # same loop maximum wavefunction size, we need to set the maximum
            # in coef_specs.inc of the HELAS Source. The SubProcesses/P* directory
            # all link this file, so it should be properly propagated
            if self.options['loop_optimized_output'] and len(
                    matrix_elements) > 1:
                max_lwfspins = [m.get_max_loop_particle_spin() for m in \
                                                                matrix_elements]
                max_loop_vert_ranks = [me.get_max_loop_vertex_rank() for me in \
                                                                matrix_elements]
                if len(set(max_lwfspins)) > 1 or len(
                        set(max_loop_vert_ranks)) > 1:
                    self._curr_exporter.fix_coef_specs(max(max_lwfspins),\
                                                       max(max_loop_vert_ranks))

        # Just the matrix.f files
        if self._export_format == 'matrix':
            for me in matrix_elements:
                filename = pjoin(path, 'matrix_' + \
                           me.get('processes')[0].shell_string() + ".f")
                if os.path.isfile(filename):
                    logger.warning("Overwriting existing file %s" % filename)
                else:
                    logger.info("Creating new file %s" % filename)
                calls = calls + self._curr_exporter.write_matrix_element_v4(\
                    writers.FortranWriter(filename),\
                    me, self._curr_fortran_model)

        cpu_time2 = time.time() - cpu_time1

        logger.info(("Generated helas calls for %d subprocesses " + \
              "(%d diagrams) in %0.3f s") % \
              (len(matrix_elements),
               ndiags, cpu_time))

        if calls:
            if "cpu_time2" in locals():
                logger.info("Wrote files for %d OPP calls in %0.3f s" % \
                            (calls, cpu_time2))
            else:
                logger.info("Wrote files for %d OPP calls" % \
                            (calls))

        # Replace the amplitudes with the actual amplitudes from the
        # matrix elements, which allows proper diagram drawing also of
        # decay chain processes
        self._curr_amps = diagram_generation.AmplitudeList(\
               [me.get('base_amplitude') for me in \
                matrix_elements])
Beispiel #17
0
    def test_find_symmetry_gg_tt_fullylept(self):
        """Test the find_symmetry function for subprocess groups"""

        procs = [[21,21, 6, -6]]
        decayt = [[6,5,-11,12],[6, 5,-13, 14]]
        decaytx = [[-6,-5,11,-12],[-6, -5, 13,-14]]
        amplitudes = diagram_generation.AmplitudeList()
        decay_amps = diagram_generation.DecayChainAmplitudeList()

        proc = procs[0]
        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':self.base_model})
        my_amplitude = diagram_generation.Amplitude(my_process)
        amplitudes.append(my_amplitude)
        
        for dect in decayt:
            my_top_decaylegs = base_objects.LegList([\
                base_objects.Leg({'id': id, 'state': True}) for id in dect])
            my_top_decaylegs[0].set('state', False)
            my_decayt_proc = base_objects.Process({'legs':my_top_decaylegs,
                                                  'model':self.base_model,
                                                  'is_decay_chain': True})
            my_decayt = diagram_generation.DecayChainAmplitude(my_decayt_proc)
            decay_amps.append(my_decayt)
            
        for dectx in decaytx:
            # Define the multiprocess
            my_topx_decaylegs = base_objects.LegList([\
               base_objects.Leg({'id': id, 'state': True}) for id in dectx])
            my_topx_decaylegs[0].set('state', False)
            my_decaytx_proc = base_objects.Process({'legs':my_topx_decaylegs,
                                              'model':self.base_model,
                                              'is_decay_chain': True}) 
            
            my_decaytx = diagram_generation.DecayChainAmplitude(my_decaytx_proc)
            decay_amps.append(my_decaytx)                   
                
                

        amplitudes = diagram_generation.DecayChainAmplitudeList([\
                diagram_generation.DecayChainAmplitude({\
                        'amplitudes': amplitudes,
                        'decay_chains': decay_amps})])

        subproc_groups = \
                  group_subprocs.DecayChainSubProcessGroup.group_amplitudes(\
                         amplitudes).generate_helas_decay_chain_subproc_groups()
        self.assertEqual(len(subproc_groups), 1)

        subproc_group = subproc_groups[0]
        self.assertEqual(len(subproc_group.get('matrix_elements')), 1)

        symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\
                                                subproc_group)
        
        sol_perms = [list(range(8)), list(range(8)), [0,1,5,6,7,2,3,4]]  

        self.assertEqual(len([s for s in symmetry if s > 0]), 2)
        self.assertEqual(symmetry, [1, 1, -2])

        self.assertEqual(perms, sol_perms)
    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())'
        ])
Beispiel #19
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']
    def test_get_fks_info_list(self):
        """tests that the get_fks_info_list of a FKSHelasProcess 
        returns the correct list of configurations/fks_configs"""

        #ug> ug
        fks1 = fks_base.FKSProcess(self.myproc1)
        me_list = []
        me_id_list = []
        pdg_list1 = []
        real_amp_list1 = diagram_generation.AmplitudeList()
        fks1.generate_reals(pdg_list1, real_amp_list1)
        helas_born_proc = fks_helas.FKSHelasProcess(fks1, me_list, me_id_list)
        goal = \
            [
             {'n_me' : 1, 'pdgs':[2,21,2,21,21], \
                 'fks_info': {'i':5, 'j':1, 'ij':1, 'ij_glu':0, 'need_color_links':True,
                              'rb_links': [{'born_conf': 0, 'real_conf': 11},
                                           {'born_conf': 1, 'real_conf': 10},
                                           {'born_conf': 2, 'real_conf': 9}]}},
             {'n_me' : 1, 'pdgs':[2,21,2,21,21], \
                 'fks_info': {'i':5, 'j':2, 'ij':2, 'ij_glu':2, 'need_color_links':True,
                              'rb_links': [{'born_conf': 0, 'real_conf': 14},
                                           {'born_conf': 1, 'real_conf': 4},
                                           {'born_conf': 2, 'real_conf': 7}]}},
             {'n_me' : 1, 'pdgs':[2,21,2,21,21], \
                 'fks_info': {'i':5, 'j':3, 'ij':3, 'ij_glu':0, 'need_color_links':True,
                              'rb_links': [{'born_conf': 0, 'real_conf': 1},
                                           {'born_conf': 1, 'real_conf': 13},
                                           {'born_conf': 2, 'real_conf': 8}]}},
             {'n_me' : 1, 'pdgs':[2,21,2,21,21], \
                 'fks_info': {'i':5, 'j':4, 'ij':4, 'ij_glu':4, 'need_color_links':True,
                              'rb_links': [{'born_conf': 0, 'real_conf': 2},
                                           {'born_conf': 1, 'real_conf': 5},
                                           {'born_conf': 2, 'real_conf': 12}]}},
             {'n_me' : 2, 'pdgs':[21,21,2,-2,21], \
                 'fks_info': {'i':4, 'j':1, 'ij':1, 'ij_glu':0, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 8},
                                           {'born_conf': 1, 'real_conf': 7},
                                           {'born_conf': 2, 'real_conf': 6}]}},
             {'n_me' : 3, 'pdgs':[2,-1,2,-1,21], \
                 'fks_info': {'i':4, 'j':2, 'ij':2, 'ij_glu':2, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 4},
                                           {'born_conf': 1, 'real_conf': 0},
                                           {'born_conf': 2, 'real_conf': 3}]}},
             {'n_me' : 4, 'pdgs':[2,1,2,1,21], \
                 'fks_info': {'i':4, 'j':2, 'ij':2, 'ij_glu':2, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 4},
                                           {'born_conf': 1, 'real_conf': 0},
                                           {'born_conf': 2, 'real_conf': 3}]}},
             {'n_me' : 5, 'pdgs':[2,-2,2,-2,21], \
                 'fks_info': {'i':4, 'j':2, 'ij':2, 'ij_glu':2, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 8},
                                           {'born_conf': 1, 'real_conf': 3},
                                           {'born_conf': 2, 'real_conf': 6}]}},
             {'n_me' : 6, 'pdgs':[2,2,2,2,21], \
                 'fks_info': {'i':4, 'j':2, 'ij':2, 'ij_glu':2, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 9},
                                           {'born_conf': 1, 'real_conf': 0},
                                           {'born_conf': 2, 'real_conf': 7}]}},
             {'n_me' : 7, 'pdgs':[2,21,2,1,-1], \
                 'fks_info': {'i':5, 'j':4, 'ij':4, 'ij_glu':4, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 0},
                                           {'born_conf': 1, 'real_conf': 3},
                                           {'born_conf': 2, 'real_conf': 4}]}},
             {'n_me' : 8, 'pdgs':[2,21,2,2,-2], \
                 'fks_info': {'i':5, 'j':4, 'ij':4, 'ij_glu':4, 'need_color_links':False,
                              'rb_links': [{'born_conf': 0, 'real_conf': 1},
                                           {'born_conf': 1, 'real_conf': 4},
                                           {'born_conf': 2, 'real_conf': 8}]}},
             ]
        for a, b in zip(goal, helas_born_proc.get_fks_info_list()):
            self.assertEqual(a, b)

        self.assertEqual(goal, helas_born_proc.get_fks_info_list())
Beispiel #21
0
    def __init__(self, *arguments, **options):
        """Initializes the original multiprocess, then generates the amps for the 
        borns, then generate the born processes and the reals.
        Real amplitudes are stored in real_amplitudes according on the pdgs of their
        legs (stored in pdgs, so that they need to be generated only once and then reicycled
        """

        #swhich the other loggers off
        loggers_off = [
            logging.getLogger('madgraph.diagram_generation'),
            logging.getLogger('madgraph.loop_diagram_generation')
        ]
        old_levels = [logg.level for logg in loggers_off]
        for logg in loggers_off:
            logg.setLevel(logging.WARNING)

        self['real_amplitudes'] = diagram_generation.AmplitudeList()
        self['pdgs'] = []

        if 'OLP' in options.keys():
            self['OLP'] = options['OLP']
            del options['OLP']

        try:
            # Now generating the borns for the first time.
            super(FKSMultiProcess, self).__init__(*arguments, **options)
        except diagram_generation.NoDiagramException as error:
            # If no born, then this process most likely does not have any.
            raise NoBornException, "Born diagrams could not be generated for the "+\
               self['process_definitions'][0].nice_string().replace('Process',\
               'process')+". Notice that aMC@NLO does not handle loop-induced"+\
               " processes yet, but you can still use MadLoop if you want to "+\
               "only generate them."+\
               " For this, use the 'virt=' mode, without multiparticle labels."

        #check limitation of FKS
        if arguments and isinstance(arguments, MG.Process):
            myprocdef = arguments[0]
            misc.sprint(myprocdef.keys())
            if myprocdef['perturbation_couplings'] != ['QCD']:
                raise InvalidCmd("FKS for reals only available in QCD for now, you asked %s" \
                            % ', '.join(myprocdef['perturbation_couplings']))
            elif myprocdef.get_ninitial() == 1:
                raise InvalidCmd("At this stage aMC@NLO cannot handle decay process.\n"+\
                 "   Only Leading Order (loop-induced and tree level) decay are supported.")

        #check process definition(s):
        # a process such as g g > g g will lead to real emissions
        #   (e.g: u g > u g g ) which will miss some corresponding born,
        #   leading to non finite results
        perturbation = []
        for procdef in self['process_definitions']:
            soft_particles = []
            # do not warn for decay processes
            if [i['state'] for i in procdef['legs']].count(False) == 1:
                continue
            for pert in procdef['perturbation_couplings']:
                if pert not in perturbation:
                    perturbation.append(pert)
                soft_particles.extend(\
                        fks_common.find_pert_particles_interactions(\
                    procdef['model'], pert)['soft_particles'])
                soft_particles_string = ', '.join( \
                    [procdef['model'].get('particle_dict')[id][\
                    {True:'name', False:'antiname'}[id >0] ] \
                    for id in sorted(soft_particles, reverse=True)])
            for leg in procdef['legs']:
                if any([id in soft_particles for id in leg['ids']]) \
                        and sorted(leg['ids']) != soft_particles:
                    logger.warning(('%s can have real emission processes ' + \
            'which are not finite.\nTo avoid this, please use multiparticles ' + \
            'when generating the process and be sure to include all the following ' + \
            'particles in the multiparticle definition:\n %s' ) \
               % (procdef.nice_string(), soft_particles_string) )
                    break
        for procdef in self['process_definitions']:
            procdef.set(
                'orders',
                diagram_generation.MultiProcess.find_optimal_process_orders(
                    procdef))

        amps = self.get('amplitudes')
        for i, amp in enumerate(amps):
            logger.info("Generating FKS-subtracted matrix elements for born process%s (%d / %d)" \
                % (amp['process'].nice_string(print_weighted=False).replace(\
                                                                 'Process', ''),
                 i + 1, len(amps)))

            born = FKSProcess(amp)
            self['born_processes'].append(born)
            born.generate_reals(self['pdgs'], self['real_amplitudes'])

        born_pdg_list = [[l['id'] for l in born.born_proc['legs']] \
                for born in self['born_processes'] ]

        for born in self['born_processes']:
            for real in born.real_amps:
                real.find_fks_j_from_i(born_pdg_list)

        if amps:
            if self['process_definitions'][0].get('NLO_mode') == 'all':
                self.generate_virtuals()

            elif not self['process_definitions'][0].get('NLO_mode') in [
                    'all', 'real', 'LOonly'
            ]:
                raise fks_common.FKSProcessError(\
                   "Not a valid NLO_mode for a FKSMultiProcess: %s" % \
                   self['process_definitions'][0].get('NLO_mode'))

            # now get the total number of diagrams
            n_diag_born = sum([
                len(amp.get('diagrams')) for amp in self.get_born_amplitudes()
            ])
            n_diag_real = sum([
                len(amp.get('diagrams')) for amp in self.get_real_amplitudes()
            ])
            n_diag_virt = sum([
                len(amp.get('loop_diagrams'))
                for amp in self.get_virt_amplitudes()
            ])

            if n_diag_virt == 0 and n_diag_real ==0 and \
                    not self['process_definitions'][0].get('NLO_mode') == 'LOonly':
                raise fks_common.FKSProcessError(
                        'This process does not have any correction up to NLO in %s'\
                        %','.join(perturbation))

            logger.info(('Generated %d subprocesses with %d real emission diagrams, ' + \
                        '%d born diagrams and %d virtual diagrams') % \
                                (len(self['born_processes']), n_diag_real, n_diag_born, n_diag_virt))

        for i, logg in enumerate(loggers_off):
            logg.setLevel(old_levels[i])

        self['has_isr'] = any([proc.isr for proc in self['born_processes']])
        self['has_fsr'] = any([proc.fsr for proc in self['born_processes']])
Beispiel #22
0
 def get_born_amplitudes(self):
     """return an amplitudelist with the born amplitudes"""
     return diagram_generation.AmplitudeList([born.born_amp \
             for born in self['born_processes']])