def def_pent(self):       
        """ Test the gg>gggg d*dx* tagging of a quark pentagon which is tagged"""

        # Five gluon legs with two initial states
        myleglist = base_objects.LegList([base_objects.Leg({'id':21,
                                              'number':num,
                                              'loop_line':False}) \
                                              for num in range(1, 7)])
        myleglist.append(base_objects.Leg({'id':1,'number':7,'loop_line':True}))
        myleglist.append(base_objects.Leg({'id':-1,'number':8,'loop_line':True}))                         
        l1=myleglist[0]
        l2=myleglist[1]
        l3=myleglist[2]
        l4=myleglist[3]
        l5=myleglist[4]
        l6=myleglist[5]
        l7=myleglist[6]
        l8=myleglist[7]

        # One way of constructing this diagram, with a three-point amplitude
        l17 = base_objects.Leg({'id':1,'number':1,'loop_line':True})
        l12 = base_objects.Leg({'id':1,'number':1,'loop_line':True})
        l68 = base_objects.Leg({'id':-1,'number':6,'loop_line':True}) 
        l56 = base_objects.Leg({'id':-1,'number':5,'loop_line':True})
        l34 = base_objects.Leg({'id':21,'number':3,'loop_line':False})

        self.myproc.set('legs',myleglist)

        vx17 = base_objects.Vertex({'legs':base_objects.LegList([l1, l7, l17]), 'id': 3})
        vx12 = base_objects.Vertex({'legs':base_objects.LegList([l17, l2, l12]), 'id': 3})
        vx68 = base_objects.Vertex({'legs':base_objects.LegList([l6, l8, l68]), 'id': 3})
        vx56 = base_objects.Vertex({'legs':base_objects.LegList([l5, l68, l56]), 'id': 3})
        vx34 = base_objects.Vertex({'legs':base_objects.LegList([l3, l4, l34]), 'id': 1})
        vx135 = base_objects.Vertex({'legs':base_objects.LegList([l12, l56, l34]), 'id': 3})

        myVertexList1=base_objects.VertexList([vx17,vx12,vx68,vx56,vx34,vx135])

        myPentaDiag1=loop_base_objects.LoopDiagram({'vertices':myVertexList1,'type':1})

        myStructRep=loop_base_objects.FDStructureList()
        
        myPentaDiag1.tag(myStructRep,7,8,self.myproc)
        
        return myPentaDiag1,myStructRep
Beispiel #2
0
def find_symmetry(matrix_element):
    """Find symmetries between amplitudes by comparing diagram tags
    for all the diagrams in the process. Identical diagram tags
    correspond to different external particle permutations of the same
    diagram.
    
    Return list of positive number corresponding to number of
    symmetric diagrams and negative numbers corresponding to the
    equivalent diagram (for e+e->3a, get [6, -1, -1, -1, -1, -1]),
    list of the corresponding permutations needed, and list of all
    permutations of identical particles."""

    if isinstance(matrix_element, group_subprocs.SubProcessGroup):
        return find_symmetry_subproc_group(matrix_element)

    nexternal, ninitial = matrix_element.get_nexternal_ninitial()

    # diagram_numbers is a list of all relevant diagram numbers
    diagram_numbers = []
    # Prepare the symmetry vector with non-used amp2s (due to
    # multiparticle vertices)
    symmetry = []
    permutations = []
    ident_perms = []
    process = matrix_element.get('processes')[0]
    base_model = process.get('model')

    if isinstance(matrix_element, loop_helas_objects.LoopHelasMatrixElement):
        # For loop induced processes we consider only the loops (no R2) and
        # the shrunk diagram instead of the lcut one.
        FDStructRepo = loop_base_objects.FDStructureList([])
        base_diagrams = base_objects.DiagramList(
                   [(d.get_contracted_loop_diagram(base_model,FDStructRepo) if
                   isinstance(d,loop_base_objects.LoopDiagram) else d) for d in
               matrix_element.get('base_amplitude').get('loop_diagrams') \
                                                            if d.get('type')>0])
        diagrams = matrix_element.get_loop_diagrams()
    else:
        diagrams = matrix_element.get('diagrams')
        base_diagrams = matrix_element.get_base_amplitude().get('diagrams')

    vert_list = [max(diag.get_vertex_leg_numbers()) for diag in diagrams if \
                                        diag.get_vertex_leg_numbers()!=[]]
    min_vert = min(vert_list) if vert_list != [] else 0

    for diag in diagrams:
        diagram_numbers.append(diag.get('number'))
        permutations.append(range(nexternal))
        if diag.get_vertex_leg_numbers()!=[] and \
                                  max(diag.get_vertex_leg_numbers()) > min_vert:
            # Ignore any diagrams with 4-particle vertices
            symmetry.append(0)
        else:
            symmetry.append(1)

    # Check for matrix elements with no identical particles
    if matrix_element.get("identical_particle_factor") == 1:
        return symmetry, \
               permutations,\
               [range(nexternal)]

    logger.info("Finding symmetric diagrams for process %s" % \
                 matrix_element.get('processes')[0].nice_string().\
                 replace("Process: ", ""))

    # diagram_tags is a list of unique tags
    diagram_tags = []
    # diagram_classes is a list of lists of diagram numbers belonging
    # to the different classes
    diagram_classes = []
    perms = []
    for diag, base_diagram in zip(diagrams, base_diagrams):
        if any([vert > min_vert for vert in diag.get_vertex_leg_numbers()]):
            # Only 3-vertices allowed in configs.inc
            continue

        tag = diagram_generation.DiagramTag(base_diagram)
        try:
            ind = diagram_tags.index(tag)
        except ValueError:
            diagram_classes.append([diag.get('number')])
            perms.append([tag.get_external_numbers()])
            diagram_tags.append(tag)
        else:
            diagram_classes[ind].append(diag.get('number'))
            perms[ind].append(tag.get_external_numbers())

    for inum, diag_number in enumerate(diagram_numbers):
        if symmetry[inum] == 0:
            continue
        idx1 = [i for i, d in enumerate(diagram_classes) if \
                diag_number in d][0]
        idx2 = diagram_classes[idx1].index(diag_number)
        if idx2 == 0:
            symmetry[inum] = len(diagram_classes[idx1])
        else:
            symmetry[inum] = -diagram_classes[idx1][0]
        # Order permutations according to how to reach the first perm
        permutations[inum] = diagram_generation.DiagramTag.reorder_permutation(
            perms[idx1][idx2], perms[idx1][0])
        # ident_perms ordered according to order of external momenta
        perm = diagram_generation.DiagramTag.reorder_permutation(
            perms[idx1][0], perms[idx1][idx2])
        if not perm in ident_perms:
            ident_perms.append(perm)

    return (symmetry, permutations, ident_perms)
    def find_mapping_diagrams(self):
        """Find all unique diagrams for all processes in this
        process class, and the mapping of their diagrams unto this
        unique diagram."""

        assert self.get('matrix_elements'), \
               "Need matrix elements to run find_mapping_diagrams"

        matrix_elements = self.get('matrix_elements')
        model = matrix_elements[0].get('processes')[0].get('model')
        # mapping_diagrams: The configurations for the non-reducable
        # diagram topologies
        mapping_diagrams = []
        # equiv_diags: Tags identifying diagrams that correspond to
        # the same configuration
        equiv_diagrams = []
        # diagram_maps: A dict from amplitude number to list of
        # diagram maps, pointing to the mapping_diagrams (starting at
        # 1). Diagrams with multi-particle vertices will have 0.
        diagram_maps = {}

        for ime, me in enumerate(matrix_elements):
            # Define here a FDStructure repository which will be used for the
            # tagging all the diagrams in get_contracted_loop_diagram. Remember
            # the the tagging of each loop updates the FDStructre repository
            # with the new structures identified.

            if isinstance(me, loop_helas_objects.LoopHelasMatrixElement):
                FDStructRepo = loop_base_objects.FDStructureList([])
                diagrams = [
                    (d.get_contracted_loop_diagram(model, FDStructRepo)
                     if isinstance(d, loop_base_objects.LoopDiagram) else d)
                    for d in me.get('base_amplitude').get('loop_diagrams')
                    if d.get('type') > 0
                ]
            else:
                diagrams = me.get('base_amplitude').get('diagrams')

            # Check the minimal number of legs we need to include in order
            # to make sure we'll have some valid configurations
            vert_list = [max(diag.get_vertex_leg_numbers()) for diag in \
                                  diagrams if diag.get_vertex_leg_numbers()!=[]]
            minvert = min(vert_list) if vert_list != [] else 0

            diagram_maps[ime] = []

            for diagram in diagrams:
                # Only use diagrams with all vertices == min_legs, but do not
                # consider artificial vertices, such as those coming from a
                # contracted loop for example, which should be considered as new
                # topologies (the contracted vertex has id == -2.)
                if diagram.get_vertex_leg_numbers()!=[] and \
                                max(diagram.get_vertex_leg_numbers()) > minvert:
                    diagram_maps[ime].append(0)
                    continue
                # Create the equivalent diagram, in the format
                # [[((ext_number1, mass_width_id1), ..., )],
                #  ...]                 (for each vertex)
                equiv_diag = IdentifyConfigTag(diagram, model)
                try:
                    diagram_maps[ime].append(equiv_diagrams.index(\
                                                                equiv_diag) + 1)
                except ValueError:
                    equiv_diagrams.append(equiv_diag)
                    mapping_diagrams.append(diagram)
                    diagram_maps[ime].append(equiv_diagrams.index(\
                                                                equiv_diag) + 1)
        return mapping_diagrams, diagram_maps