예제 #1
0
    def create_edge_variables(self, edge_ids, qn_dict):
        """
        Creates variables for the quantum numbers of the specified edges.

        Initial and final state edges just get a single domain value.
        Intermediate edges are initialized with the default domains of that
        quantum number.
        """
        variables = (set(), {})
        for edge_id in edge_ids:
            variables[1][edge_id] = []
            # if its a initial or final state edge we create a fixed var
            if (edge_id in get_initial_state_edges(self.graph)
                    or edge_id in get_final_state_edges(self.graph)):
                edge_props = self.graph.edge_props[edge_id]
                for qn_name, qn_domain in qn_dict.items():
                    value = get_particle_property(edge_props, qn_name)
                    if value is not None:
                        variables[1][edge_id].append((qn_name, value))
            else:
                for qn_name, qn_domain in qn_dict.items():
                    var_info = VariableInfo(graph_element_types.edge, edge_id,
                                            qn_name)
                    if qn_domain:
                        key = self.add_variable(var_info, qn_domain)
                        variables[0].add(key)
        return variables
예제 #2
0
def determine_attached_final_state(graph, edge_id):
    '''
    Determines all final state particles of a graph, which are attached
    downward (forward in time) for a given edge (resembling the root)

    Args:
        graph (:class:`.StateTransitionGraph`)
        edge_id (int): id of the edge, which is taken as the root
    Returns:
        list of final state edge ids ([int])
    '''
    final_state_edge_ids = []
    all_final_state_edges = get_final_state_edges(graph)
    current_edges = [edge_id]
    while current_edges:
        temp_current_edges = current_edges
        current_edges = []
        for curr_edge in temp_current_edges:
            if curr_edge in all_final_state_edges:
                final_state_edge_ids.append(curr_edge)
            else:
                node_id = graph.edges[curr_edge].ending_node_id
                current_edges.extend(get_edges_outgoing_to_node(
                    graph, node_id))
    return final_state_edge_ids
예제 #3
0
def generate_kinematics(graphs):
    tempdict = {
        # <PhspVolume>0.541493</PhspVolume>
        'InitialState': {
            'Particle': []
        },
        'FinalState': {
            'Particle': []
        }
    }
    is_edge_ids = get_initial_state_edges(graphs[0])
    counter = 0
    for x in is_edge_ids:
        tempdict['InitialState']['Particle'].append({
            '@Name':
            graphs[0].edge_props[x]['@Name'],
            '@Id':
            x,
            '@PositionIndex':
            counter
        })
        counter += 1
    fs_edge_ids = get_final_state_edges(graphs[0])
    counter = 0
    for x in fs_edge_ids:
        tempdict['FinalState']['Particle'].append({
            '@Name':
            graphs[0].edge_props[x]['@Name'],
            '@Id':
            x,
            '@PositionIndex':
            counter
        })
        counter += 1
    return {'HelicityKinematics': tempdict}
예제 #4
0
    def apply_solutions_to_graph(self, solutions):
        """
        Apply the CSP solutions to the graph instance.
        In other words attach the solution quantum numbers as properties to
        the edges. Also the solutions are filtered using the allowed
        intermediate particle list, to avoid large memory consumption.
        Args:
            solutions ([{constraint variables}]): solutions of the
                constraint (csp solving module).
        Returns:
            solution graphs ([:class:`.StateTransitionGraph`])
        """
        solution_graphs = []
        initial_edges = get_initial_state_edges(self.graph)
        final_edges = get_final_state_edges(self.graph)

        full_allowed_particle_list = initialize_allowed_particle_list(
            self.allowed_intermediate_particles)

        logging.info("attempting to filter " + str(len(solutions)) +
                     " solutions for allowed intermediate particles and"
                     " create a copy graph")
        bar = IncrementalBar('Filtering solutions', max=len(solutions))
        for solution in solutions:
            graph_copy = deepcopy(self.graph)
            for var_name, value in solution.items():
                var_info = decode_variable_name(
                    var_name, self.particle_variable_delimiter)
                ele_id = var_info.element_id

                if var_info.graph_element_type is graph_element_types.edge:
                    if ele_id in initial_edges or ele_id in final_edges:
                        # skip if its an initial or final state edge
                        continue

                add_qn_to_graph_element(graph_copy, var_info, value)

            solution_valid = True
            if self.allowed_intermediate_particles:
                for int_edge_id in get_intermediate_state_edges(graph_copy):
                    candidates = get_particle_candidates_for_state(
                        graph_copy.edge_props[int_edge_id],
                        full_allowed_particle_list)
                    if not candidates:
                        solution_valid = False
                        break
            if solution_valid:
                solution_graphs.append(graph_copy)
            bar.next()
        bar.finish()
        return solution_graphs
예제 #5
0
def initialize_graph(graph, initial_state, final_state, final_state_groupings):
    is_edges = get_initial_state_edges(graph)
    if len(initial_state) != len(is_edges):
        raise ValueError("The graph initial state and the supplied initial"
                         "state are of different size! (" +
                         str(len(is_edges)) + " != " +
                         str(len(initial_state)) + ")")
    fs_edges = get_final_state_edges(graph)
    if len(final_state) != len(fs_edges):
        raise ValueError("The graph final state and the supplied final"
                         "state are of different size! (" +
                         str(len(fs_edges)) + " != " + str(len(final_state)) +
                         ")")

    # check if all initial and final state particles have spin projections set
    initial_state = [check_if_spin_projections_set(x) for x in initial_state]
    final_state = [check_if_spin_projections_set(x) for x in final_state]

    attached_is_edges = [
        get_originating_initial_state_edges(graph, i) for i in graph.nodes
    ]
    is_edge_particle_pairs = calculate_combinatorics(is_edges, initial_state,
                                                     attached_is_edges)
    attached_fs_edges = [
        get_originating_final_state_edges(graph, i) for i in graph.nodes
    ]
    fs_edge_particle_pairs = calculate_combinatorics(fs_edges, final_state,
                                                     attached_fs_edges,
                                                     final_state_groupings)

    new_graphs = []
    for is_pair in is_edge_particle_pairs:
        for fs_pair in fs_edge_particle_pairs:
            merged_dicts = is_pair.copy()
            merged_dicts.update(fs_pair)
            new_graphs.extend(initialize_edges(graph, merged_dicts))

    return new_graphs
예제 #6
0
def group_graphs_same_initial_and_final(graphs):
    '''
    Each graph corresponds to a specific state transition amplitude.
    This function groups together graphs, which have the same initial and
    final state (including spin). This is needed to determine the coherency of
    the individual amplitude parts.

    Args:
        graphs ([:class:`.StateTransitionGraph`])
    Returns:
        graph groups ([[:class:`.StateTransitionGraph`]])
    '''
    graph_groups = dict()
    for graph in graphs:
        ise = get_final_state_edges(graph)
        fse = get_initial_state_edges(graph)
        ifsg = (tuple(sorted([json.dumps(graph.edge_props[x]) for x in ise])),
                tuple(sorted([json.dumps(graph.edge_props[x]) for x in fse])))
        if ifsg not in graph_groups:
            graph_groups[ifsg] = []
        graph_groups[ifsg].append(graph)

    graph_group_list = [graph_groups[x] for x in graph_groups.keys()]
    return graph_group_list
예제 #7
0
 def determine_node_settings(self, graphs):
     graph_node_setting_pairs = []
     for graph in graphs:
         final_state_edges = get_final_state_edges(graph)
         initial_state_edges = get_initial_state_edges(graph)
         node_settings = {}
         for node_id in graph.nodes:
             node_int_types = []
             out_edge_ids = get_edges_outgoing_to_node(graph, node_id)
             in_edge_ids = get_edges_outgoing_to_node(graph, node_id)
             in_edge_props = [graph.edge_props[edge_id] for edge_id in
                              [x for x in in_edge_ids
                               if x in initial_state_edges]]
             out_edge_props = [graph.edge_props[edge_id] for edge_id in
                               [x for x in out_edge_ids
                                if x in final_state_edges]]
             node_props = {}
             if node_id in graph.node_props:
                 node_props = graph.node_props[node_id]
             for int_det in self.interaction_determinators:
                 node_int_types.append(
                     int_det.check(in_edge_props,
                                   out_edge_props,
                                   node_props)
                 )
             node_int_types = filter_interaction_types(
                 node_int_types,
                 self.allowed_interaction_types)
             logging.debug(
                 "using " + str(node_int_types)
                 + " interaction order for node: " + str(node_id))
             node_settings[node_id] = [
                 deepcopy(self.interaction_type_settings[x])
                 for x in node_int_types]
         graph_node_setting_pairs.append((graph, node_settings))
     return graph_node_setting_pairs