def setUp(self): """Charge a diagram to draw""" if not hasattr(self, 'store_diagram'): filehandler = open(os.path.join(_file_path, \ '../input_files/test_draw.obj'), 'rb') TestDrawingS_EPS.store_diagram = pickle.load(filehandler) try: _model except: define_model() self.diagram = base_objects.DiagramList() for i in range(7): self.diagram.append(self.store_diagram['t h > t g w+ w-'][i]) self.plot = draw_eps.MultiEpsDiagramDrawer(self.diagram, '__testdiag__.eps', \ model=_model, amplitude='')
def __init__(self, diagramlist=None, filename='diagram.eps', \ model=None, amplitude=None, legend='',diagram_type=''): """Define basic variable and store some global information all argument are optional diagramlist : are the list of object to draw. item should inherit from either base_objects.Diagram or drawing_lib.FeynmanDiagram filename: filename of the file to write model: model associate to the diagram. In principle use only if diagram inherit from base_objects.Diagram amplitude: amplitude associate to the diagram. NOT USE for the moment. In future you could pass the amplitude associate to the object in order to adjust fermion flow in case of Majorana fermion.""" #use standard initialization but without any diagram super(MultiEpsDiagramDrawer, self).__init__(None, filename , model, \ amplitude) self.legend = legend #additional information self.block_nb = 0 # keep track of the number of diagram already written self.curr_page = 0 # keep track of the page position self.block_in_page = 0 #ckeep track of the block in a page #compute the number of pages self.npage = 1 self.diagram_type = diagram_type diagramlist = [d for d in diagramlist if not (isinstance(d, loop_objects.LoopUVCTDiagram) or \ (isinstance(d, loop_objects.LoopDiagram) and d.get('type') < 0))] diagramlist = base_objects.DiagramList(diagramlist) limit = self.lower_scale * self.nb_col * self.nb_line if len(diagramlist) < limit: self.npage += (len(diagramlist) - 1) // (self.nb_col * self.nb_line) else: add = (len(diagramlist) - limit -1) // \ (self.second_scale['nb_col'] * self.second_scale['nb_line']) self.npage += self.lower_scale + add if diagramlist: # diagramlist Argument should be a DiagramList object assert (isinstance(diagramlist, base_objects.DiagramList)) self.diagramlist = diagramlist else: self.diagramlist = None
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)