Beispiel #1
0
def join_overlapping_vertices(graph: Graph, vertex1, vertex2, layer):
    """
    Joins two vertices by moving all edges from vertex2 to vertex1 .
    and then removes vertex2.

    'vertex1', 'vertex2' - vertices to join, should be overlapping

    Returns vertex1 if joined.
    Returns None if vertices are not overlapped.
    """

    vertex1_x, vertex1_y = graph.nodes()[vertex1]['position']
    vertex2_x, vertex2_y = graph.nodes()[vertex2]['position']

    if math.isclose(vertex1_x, vertex2_x) \
            and math.isclose(vertex1_y, vertex2_y):

        vertex1_neighbours = get_neighbors_at(graph, vertex1, layer)
        vertex2_neighbours = get_neighbors_at(graph, vertex2, layer)

        for vertex2_neighbour in vertex2_neighbours:
            if vertex2_neighbour not in vertex1_neighbours:
                graph.add_edge(vertex1, vertex2_neighbour)
        graph.remove_node(vertex2)
        return vertex1

    return None
Beispiel #2
0
def join_overlapping_vertices(graph: Graph, vertex1, vertex2, layer):
    """
    Joins two vertices by moving all edges from `vertex2` to `vertex1`,
    then it removes `vertex2`.

    'vertex1', 'vertex2' - vertices to join, should be overlapping

    Returns vertex1 if joined.
    Returns None if vertices are not overlapping.
    """

    v1_pos = graph.nodes()[vertex1]['position']
    v2_pos = graph.nodes()[vertex2]['position']

    if is_close(v1_pos, v2_pos):
        vertex1_neighbors = get_neighbors_at(graph, vertex1, layer)
        vertex2_neighbors = get_neighbors_at(graph, vertex2, layer)

        for vertex2_neighbor in vertex2_neighbors:
            if vertex2_neighbor not in vertex1_neighbors:
                graph.add_edge(vertex1, vertex2_neighbor)
        graph.remove_node(vertex2)
        return vertex1

    return None
Beispiel #3
0
def P3(graph: nx.Graph, hyp_b, hyp_is, hyp_f, image: Image):
    __assert_hyper_edge(graph, [hyp_b], 'B')
    __assert_hyper_edge(graph, hyp_is, 'I')
    __assert_hyper_edge(graph, [hyp_f])

    hyp_f_data = graph.node[hyp_f]
    hyp_b_data = graph.node[hyp_b]

    hyp_f_neighbour_ids = list(graph.neighbors(hyp_f))

    if len(hyp_f_neighbour_ids) != 1:
        raise ValueError('F should have 1 neighbour')

    for hyp_i in hyp_is:
        if hyp_f_neighbour_ids[0] not in list(graph.neighbors(hyp_i)):
            raise ValueError('I is not connected with F1 via neighbour')

    hyp_f_neighbour_data = graph.node[hyp_f_neighbour_ids[0]]

    if hyp_f_data['label'] == Direction.N.name:
        if hyp_f_data['x'] != hyp_f_neighbour_data['x'] or hyp_f_data[
                'y'] <= hyp_f_neighbour_data['y']:
            raise ValueError('F hyperedge has weird position')
        if hyp_f_data['x'] != hyp_b_data['x'] or hyp_f_data['y'] >= hyp_b_data[
                'y']:
            raise ValueError('F hyperedge has weird position (B)')
    elif hyp_f_data['label'] == Direction.S.name:
        if hyp_f_data['x'] != hyp_f_neighbour_data['x'] or hyp_f_data[
                'y'] >= hyp_f_neighbour_data['y']:
            raise ValueError('F hyperedge has weird position')
        if hyp_f_data['x'] != hyp_b_data['x'] or hyp_f_data['y'] <= hyp_b_data[
                'y']:
            raise ValueError('F hyperedge has weird position (B)')
    elif hyp_f_data['label'] == Direction.E.name:
        if hyp_f_data['x'] <= hyp_f_neighbour_data['x'] or hyp_f_data[
                'y'] != hyp_f_neighbour_data['y']:
            raise ValueError('F hyperedge has weird position')
        if hyp_f_data['x'] >= hyp_b_data['x'] or hyp_f_data['y'] != hyp_b_data[
                'y']:
            raise ValueError('F hyperedge has weird position (B)')
    elif hyp_f_data['label'] == Direction.W.name:
        if hyp_f_data['x'] >= hyp_f_neighbour_data['x'] or hyp_f_data[
                'y'] != hyp_f_neighbour_data['y']:
            raise ValueError('F hyperedge has weird position')
        if hyp_f_data['x'] <= hyp_b_data['x'] or hyp_f_data['y'] != hyp_b_data[
                'y']:
            raise ValueError('F hyperedge has weird position (B)')
    else:
        raise ValueError('F hyperedge has weird label')

    new_node_position = (hyp_b_data['x'], hyp_b_data['y'])
    new_node_id = get_node_id(new_node_position)

    __add_new_node(graph, image, new_node_id, new_node_position)  # add v
    __add_hyperedges_between_neighbour_nodes(
        graph, hyp_b, new_node_id, new_node_position)  # add 1-b-v-b-2
    for hyp_i in hyp_is:
        __add_edges_between_nodes(graph, new_node_id, hyp_i)  # add v-i and v-i
    __add_edges_between_nodes(graph, new_node_id, hyp_f)  # add v-f1
    graph.remove_node(hyp_b)
Beispiel #4
0
def merge_mwvc_constraints(agt1: str, G1: nx.Graph, agt2: str,
                           G2: nx.Graph) -> (nx.Graph, nx.Graph):
    """
        Merge the weights associated to the nodes of type 'dec_var' that have the same 'name'.
        It assigns

    :param agt1: The name of agent 1
    :param G1: The gadget graph associated to agent 1
    :param agt2: The name of agent 2
    :param G2: The gadget graph associated to agent 2
    :return: The pairs of gadget (gadget1 and gadget2) associated to agents 1 and 2, reps.
     processed after the merging operation.
    """
    shared_dec_vars = [
        n for n in G1.nodes() for m in G2.nodes()
        if n == m and G1.nodes[n]['type'] == 'dec_var'
    ]
    for u in shared_dec_vars:
        if agt1 <= agt2:
            G1.nodes[u]['weight'] += G2.nodes[u]['weight']
            for e in G2.edges(u):
                G1.add_edge(e[0], e[1], w=G2.get_edge_data(*e)['w'])
            G2.remove_node(u)
        else:
            G2.nodes[u]['weight'] += G1.nodes[u]['weight']
            for e in G1.edges(u):
                G2.add_edge(e[0], e[1], w=G1.get_edge_data(*e)['w'])
            G1.remove_node(u)

    return G1, G2
Beispiel #5
0
def lp_reduction(graph: nx.Graph):
    """
    Delete high-degree (degre > budget) vertices

    :param graph: copy of graph to reduce
    :param budget: parameter k
    :return: (new_graph, vc)
    """
    lpsoln = utils.halfint_lpvc(graph)
    num_half = 0
    lpvals = set(lpsoln.values())
    if 1 in lpvals or 0 in lpvals:
        print("#" * 80)
        print(set(lpsoln.values()))
        print("#" * 80)
    vc = set()
    for u, lpval in lpsoln.items():
        if lpval <= 0.25:
            graph.remove_node(u)
        elif lpval >= 0.75:
            vc.add(u)
            graph.remove_node(u)
        else:
            num_half += 1
    #if num_half == len(lpsoln):
    #    print("all half", check_all_half_lp(graph, lpsoln))
    #    sys.exit()
    return graph, vc, sum(lpsoln.values())
    def remove_edge_order(self, g: nx.Graph, list_edges) -> Tuple[int]:
        new_graph = None
        delete_edge = ()
        orphan_node = None

        for i, delete_edge in enumerate(list_edges):
            new_graph = g.copy()
            new_graph.remove_edge(*delete_edge)

            if nx.classes.function.is_empty(new_graph):
                delete_edge = ()
                break

            elif nx.is_connected(new_graph):
                list_edges.pop(i)
                break

            orphan_nodes = [
                nid for nid, degree in new_graph.degree if degree == 0
            ]
            if len(orphan_nodes) == 1:
                orphan_node = orphan_nodes[0]
                list_edges.pop(i)
                break

        if len(delete_edge) > 0:
            g.remove_edge(*delete_edge)

        if orphan_node != None:
            g.remove_node(orphan_node)

        return delete_edge
Beispiel #7
0
 def on_grounded_button_clicked(self):
     current_item = self.collection_list.currentItem()
     self.collections_grounded.clear()
     self.grounded_list.clear()
     G = self.collections[self.collection_list.row(current_item)]
     item = QListWidgetItem("Released")
     try:
         icon = graph(G,
                      self.grounded_list.iconSize().width(),
                      self.ground_engine)
     except EngineError as e:
         self.engineErrorMsg(e)
         return
     item.setIcon(icon)
     self.collections_grounded.append(G)
     self.grounded_list.addItem(item)
     for node in G.nodes:
         G_ = Graph(G)
         G_.remove_node(node)
         error = False
         for H in self.collections_grounded:
             if is_isomorphic(G_, H):
                 error = True
         if error:
             continue
         item = QListWidgetItem("link_{} constrainted".format(node))
         icon = graph(G,
                      self.grounded_list.iconSize().width(),
                      self.ground_engine,
                      except_node=node)
         item.setIcon(icon)
         self.collections_grounded.append(G_)
         self.grounded_list.addItem(item)
     self.grounded_merge.setEnabled(bool(self.grounded_list.count()))
Beispiel #8
0
def polygon_skeleton(polygon, density=10):
    """ Given a buffer polygon, return a skeleton graph.
    """
    skeleton = Graph()
    points = []
    
    for ring in polygon_rings(polygon):
        points.extend(densify_line(list(ring.coords), density))
    
    if len(points) <= 4:
        # don't bother with this one
        return skeleton
    
    print >> stderr, ' ', len(points), 'perimeter points',
    
    rbox = '\n'.join( ['2', str(len(points))] + ['%.2f %.2f' % (x, y) for (x, y) in points] + [''] )
    
    qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE)
    output, error = qvoronoi.communicate(rbox)
    voronoi_lines = output.splitlines()
    
    if qvoronoi.returncode:
        raise _QHullFailure('Failed with code %s' % qvoronoi.returncode)
    
    vert_count, poly_count = map(int, voronoi_lines[1].split()[:2])
    
    for (index, line) in enumerate(voronoi_lines[2:2+vert_count]):
        point = Point(*map(float, line.split()[:2]))
        if point.within(polygon):
            skeleton.add_node(index, dict(point=point))
    
    for line in voronoi_lines[2+vert_count:2+vert_count+poly_count]:
        indexes = map(int, line.split()[1:])
        for (v, w) in zip(indexes, indexes[1:] + indexes[:1]):
            if v not in skeleton.node or w not in skeleton.node:
                continue
            v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point']
            line = LineString([(v1.x, v1.y), (v2.x, v2.y)])
            if line.within(polygon):
                skeleton.add_edge(v, w, dict(line=line, length=line.length))
    
    removing = True
    
    while removing:
        removing = False
    
        for index in skeleton.nodes():
            if skeleton.degree(index) == 1:
                depth = skeleton.node[index].get('depth', 0)
                if depth < 20:
                    other = skeleton.neighbors(index)[0]
                    skeleton.node[other]['depth'] = depth + skeleton.edge[index][other]['line'].length
                    skeleton.remove_node(index)
                    removing = True
    
    print >> stderr, 'contain', len(skeleton.edge), 'internal edges.'
    
    return skeleton
Beispiel #9
0
def drop_diff_point(G1: nx.Graph, G2: nx.Graph):
    nodes = list(G1.nodes())
    for node in nodes:
        if not (node in G2):
            G1.remove_node(node)
    nodes = list(G2.nodes())
    for node in nodes:
        if not (node in G1):
            G2.remove_node(node)
Beispiel #10
0
 def remove_node(self, n):
     try:
         if len(self.adj[n]) == 1:  # allowed for leaf node
             Graph.remove_node(self, n)
         else:
             raise NetworkXError(
                 "deleting interior node %s not allowed in tree" % (n))
     except KeyError:  # NetworkXError if n not in self
         raise NetworkXError("node %s not in graph" % n)
Beispiel #11
0
def _rm_empty_unit(processor: Graph, unit: object) -> None:
    """Remove a unit from the given processor.

    `processor` is the processor to remove the unit from.
    `unit` is the unit to remove.

    """
    warning("No capabilities defined for unit %s, removing...", unit)
    processor.remove_node(unit)
Beispiel #12
0
 def remove_node(self, node):
     """ Remove node from network. """
     if node not in self.nodes():
         logger.error("Node not in network")
         return
     Graph.remove_node(self, node)
     del self.pos[node]
     del self.labels[node]
     node.network = None
     logger.info('Node with id %d is removed.' % node.id)
Beispiel #13
0
 def remove_node(self, node):
     """ Remove node from network. """
     if node not in self.nodes():
         logger.error("Node not in network")
         return
     Graph.remove_node(self, node)
     del self.pos[node]
     del self.labels[node]
     node.network = None
     logger.debug('Node with id %d is removed.' % node.id)
Beispiel #14
0
def get_graph(edges):
    G = Graph()
    G.add_weighted_edges_from(edges)
    nodes = G.nodes()
    print(f'Num initial nodes after MIN_DIST: {len(nodes)}')
    for n in nodes:
        if G.degree(n) < MIN_DEGREE:
            G.remove_node(n)
    print(f'Num nodes after degree filter: {len(G.nodes())}')
    return G
Beispiel #15
0
 def remove_edge(self, u, v=None):
     if v is None:
         (u, v) = u
     if self.degree(u) == 1 or self.degree(v) == 1:  # leaf edge
         Graph.remove_edge(self, u, v)
     else:  # interior edge
         raise NetworkXError(
             "deleting interior edge %s-%s not allowed in tree" % (u, v))
     if self.degree(u) == 0:  # OK to remove remaining isolated node
         Graph.remove_node(self, u)
     if self.degree(v) == 0:  # OK to remove remaining isolated node
         Graph.remove_node(self, v)
def assign_registers_to_line_or_cycle(start: int, graph: nx.Graph, num_length: int) \
        -> Tuple[Sequence[int], Sequence[int], int, int]:
    """
    From the start node assign registers as they are laid out in the ideal circuit diagram in
    [CDKM96]_.

    Assumes that the there are no dead ends in the graph, and any available neighbor can be
    selected from the start without any further checks.

    :param start: a node in the graph from which to start the assignment
    :param graph: a graph with an unambiguous assignment from the start node, e.g. a cycle or line
    :param num_length: the length of the bitstring representation of one summand
    :return: the necessary registers and ancilla labels for implementing an adder program to add
        the numbers a and b. The output can be passed directly to :func:`adder`
    """
    if 2 * num_length + 2 > nx.number_of_nodes(graph):
        raise ValueError(
            "There are not enough qubits in the graph to support the computation."
        )

    graph = graph.copy()

    register_a = []
    register_b = []

    # set the node at start, and assign the carry_ancilla to this node.
    node = start
    carry_ancilla = node
    neighbors = list(graph.neighbors(node))

    idx = 0
    while idx < 2 * num_length:
        # remove the last assigned node to ensure it is not reassigned.
        last_node = node
        graph.remove_node(last_node)

        # crawl to an arbitrary neighbor node if possible. If not, the assignment has failed.
        if len(neighbors) == 0:
            raise ValueError("Encountered dead end; assignment failed.")
        node = neighbors[0]
        neighbors = list(graph.neighbors(node))

        # alternate between assigning nodes to the b register and a register, starting with b
        if (idx % 2) == 0:
            register_b.append(node)
        else:
            register_a.append(node)

        idx += 1
    # assign the z_ancilla to a neighbor of the last assignment to a
    z_ancilla = next(graph.neighbors(node))

    return register_a, register_b, carry_ancilla, z_ancilla
Beispiel #17
0
def P2(graph: nx.Graph, hyperedge_id, image: Image):
    __assert_hyper_edge(graph, hyperedge_id)
    hyperedge_data = graph.node[hyperedge_id]
    new_node_position = (hyperedge_data['x'], hyperedge_data['y'])
    new_node_id = get_node_id(new_node_position)
    old_depth = hyperedge_data.get("depth", 0)
    new_depth = old_depth + 1

    __add_new_node(graph, image, new_node_id, new_node_position)
    __add_hypereges_between_nodes(graph, hyperedge_id, new_node_id,
                                  new_node_position, new_depth)
    __add_direction_hyperedges(graph, new_node_id,
                               create_direction_calulcator(old_depth))
    graph.remove_node(hyperedge_id)
Beispiel #18
0
def add_city_geocode(network: nx.Graph):
    cities = network.nodes
    latitude, longitude = get_geocode(cities)

    for city, lat in latitude.items():
        if isclose(lat, 999.0) or type(lat) != type(1.0):
            try:
                network.remove_node(city)
            except Exception as e:
                print(e)

    nx.set_node_attributes(network, latitude, 'Latitude')
    nx.set_node_attributes(network, longitude, 'Longitude')
    return network
Beispiel #19
0
def precompute(words, length):
    words = [w for w in words if len(w) == length]
    by_letters = group_by_key_func(words, lambda w: "".join(sorted(w)))

    graph = Graph()
    by_subletters = defaultdict(list)
    for key in by_letters:
        counts = tuple(Counter(key).items())
        for differing_letters in [1, 2]:
            for subletters in combinations(counts, len(counts) - differing_letters):
                by_subletters[subletters].append(key)

    for group in by_subletters.values():
        for u, v in combinations(group, 2):
            u_counts = Counter(u)
            v_counts = Counter(v)
            less = None
            more = None
            for letter in u_counts.keys() | v_counts.keys():
                if u_counts[letter] == v_counts[letter]:
                    continue
                elif u_counts[letter] == v_counts[letter] + 1 and more is None:
                    more = letter
                elif u_counts[letter] == v_counts[letter] - 1 and less is None:
                    less = letter
                else:
                    break
            else:
                assert less and more
                graph.add_edge(u, v)

    components = list(networkx.connected_components(graph))
    nodes = list(max(components, key=len))
    graph: networkx.Graph = graph.subgraph(nodes).copy()
    degree = graph.degree
    leaves = [node for node in nodes if degree[node] == 1]
    for leaf in leaves:
        while True:
            neighbors = list(graph.neighbors(leaf))
            if len(neighbors) != 1:
                break
            graph.remove_node(leaf)
            leaf = neighbors[0]

    result = {}
    for node in graph:
        neighbors = list(graph.neighbors(node))
        assert len(neighbors) > 1
        result[node] = [by_letters[node], neighbors]
    return result
Beispiel #20
0
def polygon_dots_skeleton(polygon, points):
    '''
    '''
    skeleton = Graph()

    rbox = '\n'.join(['2', str(len(points))] +
                     ['%.2f %.2f' % (x, y) for (x, y) in points] + [''])

    qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE)
    output, error = qvoronoi.communicate(rbox)
    voronoi_lines = output.splitlines()

    if qvoronoi.returncode:
        raise _QHullFailure('Failed with code %s' % qvoronoi.returncode)

    vert_count, poly_count = list(map(int, voronoi_lines[1].split()[:2]))

    for (index, line) in enumerate(voronoi_lines[2:2 + vert_count]):
        point = Point(*list(map(float, line.split()[:2])))
        if point.within(polygon):
            skeleton.add_node(index, dict(point=point))

    for line in voronoi_lines[2 + vert_count:2 + vert_count + poly_count]:
        indexes = list(map(int, line.split()[1:]))
        for (v, w) in zip(indexes, indexes[1:] + indexes[:1]):
            if v not in skeleton.node or w not in skeleton.node:
                continue
            v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point']
            line = LineString([(v1.x, v1.y), (v2.x, v2.y)])
            if line.within(polygon):
                skeleton.add_edge(v, w, dict(line=line, length=line.length))

    removing = True

    while removing:
        removing = False

        for index in skeleton.nodes():
            if skeleton.degree(index) == 1:
                depth = skeleton.node[index].get('depth', 0)
                if depth < 20:
                    other = skeleton.neighbors(index)[0]
                    skeleton.node[other]['depth'] = depth + skeleton.edge[
                        index][other]['line'].length
                    skeleton.remove_node(index)
                    removing = True

    logging.debug('found %d skeleton edges' % len(skeleton.edge))

    return skeleton
Beispiel #21
0
def remove_topic_nodes(graph: nx.Graph) -> None:
    """Drops topic nodes from the graph."""
    logger.info("Dropping topic nodes")
    logger.info(
        f"Original graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges"
    )
    drop = set()
    for node in graph.nodes:
        if graph.nodes[node]["kind"] == "topic":
            drop.add(node)
    for node in drop:
        graph.remove_node(node)
    logger.info(
        f"Updated graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges"
    )
Beispiel #22
0
def polygon_dots_skeleton(polygon, points):
    '''
    '''
    skeleton = Graph()

    rbox = '\n'.join( ['2', str(len(points))] + ['%.2f %.2f' % (x, y) for (x, y) in points] + [''] )
    
    qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE)
    output, error = qvoronoi.communicate(rbox)
    voronoi_lines = output.splitlines()
    
    if qvoronoi.returncode:
        raise _QHullFailure('Failed with code %s' % qvoronoi.returncode)
    
    vert_count, poly_count = map(int, voronoi_lines[1].split()[:2])
    
    for (index, line) in enumerate(voronoi_lines[2:2+vert_count]):
        point = Point(*map(float, line.split()[:2]))
        if point.within(polygon):
            skeleton.add_node(index, dict(point=point))
    
    for line in voronoi_lines[2+vert_count:2+vert_count+poly_count]:
        indexes = map(int, line.split()[1:])
        for (v, w) in zip(indexes, indexes[1:] + indexes[:1]):
            if v not in skeleton.node or w not in skeleton.node:
                continue
            v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point']
            line = LineString([(v1.x, v1.y), (v2.x, v2.y)])
            if line.within(polygon):
                skeleton.add_edge(v, w, dict(line=line, length=line.length))
    
    removing = True
    
    while removing:
        removing = False
    
        for index in skeleton.nodes():
            if skeleton.degree(index) == 1:
                depth = skeleton.node[index].get('depth', 0)
                if depth < 20:
                    other = skeleton.neighbors(index)[0]
                    skeleton.node[other]['depth'] = depth + skeleton.edge[index][other]['line'].length
                    skeleton.remove_node(index)
                    removing = True
    
    logging.debug('found %d skeleton edges' % len(skeleton.edge))
    
    return skeleton
Beispiel #23
0
def singleSourceSP(G: nx.Graph, A_i: list):
    """Return node: (dist, p(node)) for A_i

    Arguments:
        G {nx.Graph} -- [description]
        A_i {list} -- [description]
    """

    virtNodeId = len(G.nodes())
    G.add_node(virtNodeId)
    G.add_weighted_edges_from([(i, virtNodeId, 0) for i in A_i])
    distances, paths = nx.single_source_dijkstra(G, virtNodeId)
    G.remove_node(virtNodeId)

    path = {node: paths[node][1] for node in paths if node != virtNodeId}

    return distances, path
Beispiel #24
0
def dijkstra(graph: Graph, source: int, target: int):
    graph.nodes[source]["distance"] = 0

    while graph.nodes:
        shortest_path_node = get_node_with_minimal_distance(graph)

        if target == shortest_path_node:
            return graph.nodes[target]["distance"]

        for neighbour in graph.neighbors(shortest_path_node):
            alt = graph.nodes[shortest_path_node]["distance"] + \
                  graph.get_edge_data(shortest_path_node, neighbour)["weight"]
            if alt < graph.nodes[neighbour]["distance"]:
                graph.nodes[neighbour]["distance"] = alt

        graph.remove_node(shortest_path_node)

    return graph
Beispiel #25
0
def _rm_dead_end(processor: Graph, dead_end: object,
                 in_ports: typing.Container[object]) -> None:
    """Remove a dead end from the given processor.

    `processor` is the processor to remove the dead end from.
    `dead_end` is the dead end to remove.
    `in_ports` are the processor original input ports.
    A dead end is a port that looks like an output port after
    optimization actions have cut it off real output ports.

    """
    if dead_end in in_ports:  # an in-port turned in-out port
        raise DeadInputError("No feasible path found from input port "
                             f"${DeadInputError.PORT_KEY} to any output ports",
                             dead_end)

    warning("Dead end detected at unit %s, removing...", dead_end)
    processor.remove_node(dead_end)
Beispiel #26
0
def apply_clustering(graph: networkx.Graph, cluster_dict):
    """
    Takes a graph and a dictionary of [cluster head - cluster member list]
    and changes the graph to represent the clustered graph, i.e. only display
    the cluster heads and their connectivity.
    :param graph: a networkx.Graph
    :param cluster_dict: cluster heads as keys, cluster members as values
    :return:
    """
    # create adjacency matrix for clusters
    cluster_adj = dict()

    if len(cluster_dict) > 1:
        for cluster_head1 in cluster_dict:
            for cluster_head2 in cluster_dict:
                if cluster_head1 == cluster_head2:
                    continue
                cluster1 = cluster_dict[cluster_head1] | {cluster_head1}
                cluster2 = cluster_dict[cluster_head2] | {cluster_head2}
                if edge_exists(graph, cluster1, cluster2):
                    try:
                        cluster_adj[cluster_head1].append(cluster_head2)
                    except KeyError:
                        cluster_adj[cluster_head1] = [cluster_head2]

        # remove all nodes that are not cluster heads
        for node in graph.nodes():
            if node not in cluster_adj:
                graph.remove_node(node)

        # remove all old edges
        graph.remove_edges_from(graph.edges())

        for n1 in cluster_adj:
            for n2 in cluster_adj[n1]:
                graph.add_edge(n1, n2)

    else:  # only one cluster head
        for node in graph.nodes():
            if node not in cluster_dict:
                graph.remove_node(node)

    return graph
Beispiel #27
0
def embed_chain(chain, hardware_graph: nx.Graph):
    current_deg = len(hardware_graph)
    for node in hardware_graph:
        deg = hardware_graph.degree(node)
        if deg < current_deg:
            current_node = node
    embedding = {current_node: chain[0]}
    for log_qb in chain[1:]:
        current_deg = len(hardware_graph)
        for neighbor in hardware_graph.neighbors(current_node):
            deg = hardware_graph.degree(neighbor)
            if deg < current_deg:
                new_node = neighbor
                current_deg = deg
        embedding[new_node] = log_qb
        hardware_graph.remove_node(current_node)
        current_node = new_node
        new_node = None
    hardware_graph.remove_node(current_node)
    return embedding
Beispiel #28
0
    def remove_edge(self, g: nx.Graph) -> Tuple[int]:
        random.seed(42)
        new_graph = None
        delete_edge = ()
        tried_edges = []
        orphan_node = None

        # if g.number_of_nodes() == g.number_of_edges() + 1:
        #     return None

        while True:
            delete_edge = random.choice(list(g.edges))
            while set(delete_edge) in tried_edges:
                delete_edge = random.choice(list(g.edges))
                # print(delete_edge)

            new_graph = g.copy()
            new_graph.remove_edge(*delete_edge)
            tried_edges.append(set(delete_edge))

            if nx.classes.function.is_empty(new_graph):
                delete_edge = ()
                break

            elif nx.is_connected(new_graph):
                break

            orphan_nodes = [
                nid for nid, degree in new_graph.degree if degree == 0
            ]
            if len(orphan_nodes) == 1:
                orphan_node = orphan_nodes[0]
                break

        if len(delete_edge) > 0:
            g.remove_edge(*delete_edge)

        if orphan_node != None:
            g.remove_node(orphan_node)

        return delete_edge
Beispiel #29
0
def monopolar_partition(input_graph, k):
    DEBUG = False
    #initialization
    G = input_graph
    A_init = Graph()  #an empty graph
    B_init = input_graph
    Q = [
        [A_init, B_init],
    ]  # deliberately double-depth Q to manage 'branches'
    #loop body
    for branch in Q:
        A = branch[0]
        if DEBUG == True:
            print "A "
            print A.nodes()
        B = branch[1]
        if DEBUG == True:
            print "B "
            print B.nodes()
        if nx.number_of_nodes(A) > k:
            continue  #reject branch

        p2s = forbidden_graphs(B)
        if DEBUG == True:
            print "p2s "
            print p2s
        if p2s == []:
            return True
            break
        else:
            p2s = p2s[0]
            for vertex in p2s:
                A_new = nx.union(A, nx.subgraph(input_graph, vertex))
                B_new = Graph(B)
                B_new.remove_node(vertex)
                Q.append([A_new, B_new])

        #all else fails
    return False
Beispiel #30
0
    def on_grounded_button_clicked(self):
        """Grounded combinations."""
        current_item = self.collection_list.currentItem()
        self.collections_grounded.clear()
        self.grounded_list.clear()
        G = self.collections[self.collection_list.row(current_item)]
        item = QListWidgetItem("Released")
        try:
            icon = graph(G,
                         self.grounded_list.iconSize().width(),
                         self.ground_engine)
        except EngineError as e:
            self.engineErrorMsg(e)
            return
        item.setIcon(icon)
        self.collections_grounded.append(G)
        self.grounded_list.addItem(item)

        def isomorphic(G: Graph, l: List[Graph]) -> bool:
            for H in l:
                if is_isomorphic(G, H):
                    return True
            return False

        for node in G.nodes:
            G_ = Graph(G)
            G_.remove_node(node)
            if isomorphic(G_, self.collections_grounded):
                continue
            item = QListWidgetItem("link_{}".format(node))
            icon = graph(G,
                         self.grounded_list.iconSize().width(),
                         self.ground_engine,
                         except_node=node)
            item.setIcon(icon)
            self.collections_grounded.append(G_)
            self.grounded_list.addItem(item)
        self.grounded_merge.setEnabled(bool(self.grounded_list.count()))
Beispiel #31
0
def approximate_minimal_edge_length_for_graph(graph: nx.Graph,
                                              max_length: float,
                                              max_angle: float,
                                              scale: np.ndarray):
    nodes_with_degree_of_two = [
        node for node in graph.nodes if graph.degree(node) == 2
    ]

    for node_id in nodes_with_degree_of_two:
        current_node = graph.nodes[node_id]
        neighbors = list(graph.neighbors(node_id))
        neighbor1 = graph.nodes[neighbors[0]]
        neighbor2 = graph.nodes[neighbors[1]]
        vector1 = get_vector_between_nodes(neighbor1, current_node, scale)
        vector2 = get_vector_between_nodes(current_node, neighbor2, scale)
        new_edge_vector = get_vector_between_nodes(neighbor1, neighbor2, scale)
        distance_between_combined_edges = vector_length(new_edge_vector)
        angle = calculate_angle_between_vectors(vector1, vector2)
        if angle <= max_angle and distance_between_combined_edges <= max_length:
            graph.remove_edges_from([(neighbors[0], node_id),
                                     (node_id, neighbors[1])])
            graph.remove_node(node_id)
            graph.add_edge(neighbors[0], neighbors[1])
Beispiel #32
0
 def remove_node(self, n):
     Graph.remove_node(self, n)
     self.fh.write("Remove node: %s\n" % n)
Beispiel #33
0
def solve():
	from networkx import Graph, number_connected_components
	from heap.heap import heap
	
	def up(p):
		r, c = divmod(p,C)
		return (R-1 if r==0 else r-1)*C + c
	
	def down(p):
		r, c = divmod(p,C)
		return (0 if r==R-1 else r+1)*C + c
	
	def left(p):
		r, c = divmod(p,C)
		return r*C + (C-1 if c==0 else c-1)
	
	def right(p):
		r, c = divmod(p,C)
		return r*C + (0 if c==C-1 else c+1)
	
	def link(a,b):
		G.add_edge(('start',a),('end',b))
		H[b] += 1
	
	R, C = map(int,input().split())
	N = R*C
	G = Graph()
	H = heap({n:0 for n in range(N)})
	
	for p in range(N):
		G.add_node(('start',p))
		G.add_node(('end',p))
	
	for p, x in enumerate(x for _ in range(R) for x in input().strip()):
		if x == '|':
			link(p,up(p))
			link(p,down(p))
		elif x == '-':
			link(p,left(p))
			link(p,right(p))
		elif x == '/':
			link(p,down(left(p)))
			link(p,up(right(p)))
		elif x == '\\':
			link(p,up(left(p)))
			link(p,down(right(p)))
	
	while H[H.peek()] <= 1:
		p, ins = H.popitem()
		
		if ins == 0:
			# There is a sqaure such that no other square points to it.
			# It's impossible for a lemming to get here.
			# So there are no proper ways to arrange this.
			return 0
		
		else:
			# There is exactly one edge leading into p.
			# Remove the relevant nodes.
			_, q = next(iter(G['end',p]))
			r = next(r for _, r in G['start',q] if r != p)
			
			G.remove_node(('end',p))
			G.remove_node(('start',q))
			
			# If q now points to p, the other square that q points to
			# has one fewer square pointing to it.
			H[r] -= 1
	
	# Now all remaining nodes are cycles, and there are exatly two ways
	# to choose the directions for each cycle.
	return pow(2,number_connected_components(G),1000003)
Beispiel #34
0
class LangGraph(object):
	"""
	A graph of all the relationships in a document and/or sentence
	"""
	def __init__(self, directed=False):
		"""
		Builds a graph out of the given document
		"""
		self.isDirected = directed

		#a graph that is meant to be full of class Instance
		if self.isDirected:
			self.graph = DiGraph()
		else:
			self.graph = Graph()
		
		self.start = None #an Instance

		#keep the graph also according to temporal, redundant probably needs
		#refactoring
		self.temporal = None 
		self.temporalMap = None

	def setStart(self, start):
		"""
		Sets the starting instance, also builds the temporal ordering
		of the graph
		"""
		self.start = start
		self.temporal = self.narrativeOrder()
		self.temporalMap = self.narrativeMapping()
			
	def indexToInst(self, index):
		"""
		Returns the instance corresponding to the given index
		"""
		result = index

		#if the index is an int, lookup the instance associated with it
		if type(index) == int:
			result = self.temporal[index]

		return result

	def instToIndex(self, instance):
		"""
		Return the index associated with the instance
		"""
		return self.temporalMap[instance]

	def narrativeOrder(self):
		"""
		Returns the instances in narrative order
		"""
		results = []
		node = self.start
		prev = None

		#while there are more nodes, keep adding them
		while node is not None:
			#record the current node
			results.append(node)
			
			#get the connected nodes
			fringe = [n for n in self.adj(node, WORD_EDGE) if n != prev]
			nextNode = fringe[0] if fringe else None

			#advance to the next node
			prev = node
			node = nextNode

		return results

	def narrativeMapping(self):
		"""
		Makes the mapping from instances to their narrative index
		"""
		return {inst:i for i,inst in enumerate(self.temporal)}

	def addNode(self, node):
		"""
		Adds a node to the graph
		"""
		self.graph.add_node(node)

	def addEdge(self, start, end, type):
		"""
		Adds an edge between the two instances
		"""
		#if the edge exists, just add the type
		if self.graph.has_edge(start, end):
			self.addType(start, end, type)
		else:
			self.graph.add_edge(start, end, TYPES=set([type]))

	def removeEdge(self, start, end, edgeType):
		"""
		Removes an edge with a given type from the edge type
		"""
		#remove the type
		self.removeType(start, end, edgeType)

		#if there are no types, remove the edge itself
		types = self.edgeTypes(start, end)

		#remove the edge
		if not len(types) and self.graph.has_edge(start, end):
			self.graph.remove_edge(start, end)

	def addType(self, start, end, type):
		"""
		Adds a type between the edges
		"""
		#look for existing types
		types = self.graph[start][end].get(TYPES, set())

		#add the new type
		types.add(type)

		self.graph[start][end][TYPES] = types

	def removeType(self, start, end, edgeType):
		"""
		Removes the type on the edge
		"""
		for prefix in [PARENT, CHILD]:
			edgeType = removePrefix(prefix, edgeType)

		types = self.graph[start][end][TYPES]

		#if the types contains the edge, remove
		if edgeType in types:
			types.remove(edgeType)

	def hasType(self, start, end, type):
		"""
		Returns true if the edge between the two nodes has the given
		type
		"""
		return type in self.edgeTypes(start, end)

	def singleEdgeTypes(self, start, end):
		"""
		Returns the types on the edge if any, or an empty set is returned
		"""
		#make sure we are using instances rather than indexes
		start = self.indexToInst(start)
		end = self.indexToInst(end)

		data = self.graph.get_edge_data(start,end)
		result = set()
		
		#if there is data, get the types
		if data is not None:
			result = data.get(TYPES, set())

		return result

	def edgeTypes(self, start, end):
		"""
		Returns the types on the edge if any, or an empty set is returned
		"""
		if self.isDirected:
			parent = addPrefixes(PARENT, self.singleEdgeTypes(end, start))
			child = addPrefixes(CHILD, self.singleEdgeTypes(start, end))
			types = parent.union(child)

		else:
			types = self.singleEdgeTypes(start, end)
		
		return types

	def allEdgeTypes(self):
		"""
		Returns all the edge types
		"""
		results = set()
		
		#collect all the edges with all the types
		for s,e,types in self.allEdges():
			
			#look up the edge types to make sure everything is covered
			for edgeType in types:
				results.add(edgeType)

			#add in the reverse types
			for edgeType in self.edgeTypes(e,s):
				results.add(edgeType)
				
		return results

	def allEdges(self):
		"""
		Yield all the edges in the graph
		"""
		for start, end in self.graph.edges():
			yield start, end, self.edgeTypes(start, end)

	def contains(self, instance):
		"""
		Returns true if the graph contains the instance
		"""
		return self.graph.has_node(instance)

	def instances(self):
		"""
		Return all the instances in the graph
		"""
		return self.graph.nodes()

	def edges(self, instance):
		"""
		Returns all the edges connected to this instance
		"""
		inst = self.indexToInst(instance)

		#make get the directed edges
		if self.isDirected:
			results = [t for _, t in self.graph.out_edges(inst)] + [t for t, _ in self.graph.in_edges(inst)]
		else:
			results = self.graph.adj[inst]

		return results

	def docType(self):
		"""
		Returns the document type (String)
		"""
		return self.temporal[0].event.docType

	def adj(self, instance, type=None):
		"""
		Returns the adjancent node with a given type
		"""
		return [other for other	in self.edges(instance)
			if self.hasType(instance, other, type) or type is None]

	def nonNarrativeAdj(self, instance, returnIndex=False):
		"""
		Returns the nodes that are not adjancent to the given instance
		"""
		results = []
	
		#add each node if it has a non-narrative (temporal) connection
		for node in self.edges(instance):

			#get the non narrative types
			edgeTypes = nonNarrativeTypes(self.edgeTypes(instance, node))

			#if there is a non-narrative edge, add it
			if edgeTypes:

				#lookup the index of the node
				nodeMarker = self.instToIndex(node) if returnIndex else node
				results.append((nodeMarker, edgeTypes))

		return results

	def words(self):
		"""
		Returns the words in narrative order
		"""
		return [t.word for t in self.tokens()]

	def tokens(self):
		"""
		Returns the tokens in narrative order
		"""
		return [i.token for i in self.temporal]

	def labels(self):
		"""
		Returns the sequence of labels for the instances
		"""
		return [i.event.type for i in self.temporal]

	def removeAny(self, blackList):
		"""
		Removes any nodes/tokens/instances that match the words in the blacklist
		"""
		#if a token or its lemma match any of the words in the blacklist
		#mark it for removal
		toRemove = {inst.token for inst in self.temporal 
			if inst.token.word.lower() in blackList 
			or inst.token.lemma.lower() in blackList}

		self.removeNodes(toRemove)

	def removeNodes(self, tokens):
		"""
		Removes the token from the graph
		"""
		startLen = len(self)

		#mark all the instances/indexes to remove
		instances = {inst:i for inst,i in self.temporalMap.items() 
			if inst.token in tokens}

		#determine the remaining nodes
		remaining = sorted(list(set(range(startLen)) - {i for i in instances.values()}))
		
		#add in all the bypasses
		for startIndex, endIndex in iterPairs(remaining):
				start = self.temporal[startIndex]
				end = self.temporal[endIndex]
				self.addEdge(start, end, WORD_EDGE)

		#remove the edges
		for inst in instances:
			self.graph.remove_node(inst)
	
		#if there are remaining nodes then reset the temporal mapping
		if remaining:
			startIndex = min(remaining)
			self.start = self.temporal[startIndex]

			#redo narrative order
			self.temporal = self.narrativeOrder()
			self.temporalMap = self.narrativeMapping()

		else:
			self.start = None
			self.temporal = []
			self.temporalMap = {}

	def copy(self):
		"""
		Performs a shallow copy of the graph
		"""
		newGraph = LangGraph(self.isDirected, self.entEdges)

		#create new instances
		newInst = {i:me.Instance(copy(i.token), i.event) for i in self.temporal}

		#add in all the edges
		for start, end in self.graph.edges():
			for eType in self.edgeTypes(start, end):
				newGraph.addEdge(newInst[start], newInst[end], eType)

		newGraph.setStart(newInst[self.start])

		return newGraph

	def graphString(self):
		"""
		Returns the graph as a string
		"""
		return " ".join([t.word for t in self.tokens()])

	def __len__(self):
		"""
		Returns the number of nodes (tokens) in the graph
		"""
		return len(self.graph)

	def __repr__(self):
		"""
		Returns a summary string of the graph
		"""
		return "LangGraph {} nodes, {} edges".format(len(self.graph.nodes()), len(self.graph.edges()))
Beispiel #35
0
                utm_zone_number = pos[2]
            graph.add_node(item.id, lat=item.lat, lon=item.lon, pos=pos[:2])
            #nodes += 1
        items += 1
        print('{0} items processed'.format(items), end='\r')

    print('{0} items processed'.format(items))

    if shape_file:
        n = graph.number_of_nodes()
        i = 0
        print('Apply shapefile')
        for node in graph.nodes():
            p = Point(graph.node[node]['lon'], graph.node[node]['lat'])
            if not shape_file.contains(p):
                graph.remove_node(node)
            i += 1
            print('{0}/{1} nodes processed'.format(i, n), end='\r')
        print('{0}/{1} nodes processed'.format(i, n))

    print('Search for orphaned nodes')
    orphaned = set()
    n = graph.number_of_nodes()
    i = 0
    for node in graph.nodes_iter():
        if graph.degree(node) == 0:
            orphaned.add(node)
        i += 1
        print('{0}/{1} nodes processed'.format(i, n), end='\r')
    
    print('{0}/{1} nodes processed'.format(i, n))
Beispiel #36
0
 def remove_node(self,n):
     Graph.remove_node(self,n)
     self.fh.write("Remove node: %s\n"%n)
Beispiel #37
0
class Network(HasTraits):
    """ The implementation of the Connectome Networks """

    implements(INetwork)

    # Network ID, from parsed GraphML the graphid
    networkid = ''

    # Network name
    networkname = Str
    
    # network name as seen in the TreeView
    name = Str
    
    # Is it an hierarchical network?
    hierarchical = CBool(False)

    # TODO: later, also Hypergraph?!
    # see: http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1000385
    hypergraph = CBool(False)

    # Directionality of the Network, {True: 'directed', False: 'undirected'}
    directed = CBool(False)

    # metadata for the network
    metadata = Dict

    # NodeKeys from the parsed GraphML
    # These are Dict of Dict, all having strings
    nodekeys = {}
    
    # Edgekeys, from parsed GraphML
    edgekeys = {}

    # A NetworkX AttrGraph containing all the information
    graph = Any
        
    # Surface containers
    surfaces = List(ISurfaceContainer)
    
    # Surface containers loaded
    surfaces_loaded = List(ISurfaceContainer)
    
    # Volume data
    volumes = List(IVolume)
    
    # Track data
    tracks = List(ITrackfile)

    # is this network active, and thus a render manager displayed?
    active = Bool

    # the render manager of this network
    rendermanager = Instance(RenderManager)
    
    # DatasourceManager Instance of this network
    datasourcemanager = Instance(DatasourceManager)
    
    # private traits
    ###########
    
    # parent cfile this networks belongs to
    _parentcfile = Any

    # filezip of cfile
    _filezip = DelegatesTo('_parentcfile')

    # edge parameters for visualization
    _edge_para = Instance(EdgeParameters)

    # View
    traits_view = View(
        Item('networkname', style = 'readonly'),
        Item('hierarchical', style = 'simple'),
        Item('hypergraph', style = 'simple'),
        Item('directed', style = 'simple'),
        Item('active', style = 'simple'),
        title   = 'A network', 
    )

    def __init__(self, name, src = None, directed = '0', pickled_graph = None, \
                 hierarchical ='0', hypergraph = '0', graph = None):
        """ Initializes the network and sets the traits.
        
        Parameters
        ----------
        name : string
            the name of the network
        src : file handle or StringIO object
            the source text of the network to parse
        pickled_graph : NetworkX graph
            reference to a graph object, src should be None
        directed : bool
            Is the network directed?
        hierarchical : bool
            Is the network hierarchical? (default: '0') Not implemented yet.
        hypergraph : bool
            Is the network a hypergraph? (default: '0') Not implemented yet.
        
        """
        
        # initialize the traits
        self.networkname = name
        self.directed = int(directed)
        self.hierarchical = int(hierarchical)
        self.hypergraph = int(hypergraph)
        
        if src is None and not pickled_graph is None:
            self.load_pickled_graphml(pickled_graph)
        else:
            if not src is None:
                # generates NetworkX Graph
                self.graph = self.parse_network_graphml(src)
            elif not graph is None:
                self.graph = graph
            else:
                
                if self.directed:
                    from networkx import DiGraph
                    self.graph = DiGraph()
                    logger.info("Initialize with empty directed Graph")
                else:
                    from networkx import Graph
                    self.graph = Graph()
                    logger.info("Initialize with empty undirected Graph")
                
                
        # initializes the weight key of the graph
        # with the first edgekey
        if len(self.edgekeys) > 0:
            edgk = self.edgekeys.keys()
            if not 'weight' in edgk:
                self.set_weight_key(edgk[0])
        else:
            # try grabbing first edge from the graph
            if self.graph.number_of_edges() > 0:
                it = self.graph.edges_iter(data=True)
                edg = it.next()
                if len(edg[2]) > 0:
                    # if it has a weigth key, just leave it
                    edgk = edg[2].keys()
                    if not 'weight' in edgk:
                        self.set_weight_key(edgk[0])
            else:
                pass
                # logger.error('Cannot set weight key for network : ' + self.networkname)
                
    def _name_default(self):
        return self.networkname

    def _active_default(self):
        return False

    def _active_changed(self , value):
        if value:
            n = self.name
            if ' [Active]' not in n:
                self.name = "%s [Active]" % n
                
            # XXX: do refactor with threaded loading of surfaces
            # and default spring force layout for graph rendering!
            # see also TraitsUI Demos: Multi thread demo
            
            # load the surface containers data
            # make a deep copy of the already loaded surface containers
            import copy
            self.surfaces = copy.deepcopy(self.surfaces_loaded)
            for surfcont in self.surfaces:
                surfcont.load_surface_container()
            
            if self.rendermanager is None:
                self._create_datasourcemanager()
                self._create_renderer()
                # if there are no surfaces, initialize
                # network rendering, but only if dn_positions are given
                if len(self.surfaces) == 0:
                    logger.debug('No surfaces found. Try to render graph view with dn_position information.')
                    self.rendermanager.datasourcemanager._compute_3DLayout(-1, -1)
                    self.rendermanager.visualize_graph()
                else:
                    logger.debug('SurfaceContainer found. Try to render 3D View using %s.' % self.surfaces[0].name)
                    if len(self.surfaces[0].surfaces) == 0:
                        logger.debug('Rendering not possible because SurfaceContainer contains no surfaces.')
                    else:
                        logger.debug('Using first surface for rendering.')
                        self.surfaces[0].surfaces[0]._layout_3DView()
            
            if not self._parentcfile._workbenchwin is None:
                #from enthought.pyface.timer.api import do_later
                from enthought.pyface.api import GUI
                GUI.invoke_later(self._parentcfile._workbenchwin.status_bar_manager.set, message = '')
            
        else:
            self.name = self.name.replace(' [Active]', '')
            logger.debug('Close RenderManager scenes')
            self.rendermanager.close_scenes()
            logger.debug('All scenes closed.')
            # FIXME: what is happening in the following?
            # e.g. for instances. e.g. reset traits?
            # XXX: this is somehow not correct. do i need to use del
            # or remove/reset traits?
            self.rendermanager = None
            self.datasourcemanager = None
            self.surfaces = []

    def _de_activate(self):
        """ Toggles the internal state of the activation """
        if self.active:
            self.active = False
        else:
            self._parentcfile._workbenchwin.status_bar_manager.message = 'Activating network ...'
            self.active = True

    def _edge_parameters(self):
        """ Dialog to change edge attribute and thresholding """
        if self._edge_para is None:
            self._edge_para = EdgeParameters(self, self.rendermanager.attract.point_scalars_name)
            
        self._edge_para.configure_traits()


    def _create_renderer(self):
        """ Creates the renderer instance if not yet available
        and opens the scenes in mayavi """

        if self.active:
            if self.rendermanager is None:
                logger.debug('Create a RenderManager instance')
                self.rendermanager = RenderManager(network=self)
            else:
                logger.debug('RenderManager instance already running. This is an error.')

    def _create_datasourcemanager(self):
        """ Creates the datasource manager instance if not yet available """
        if self.active:
            if self.datasourcemanager is None:
                logger.debug('Create a DatasourceManager instance')
                self.datasourcemanager = DatasourceManager(network=self)
            else:
                logger.debug('DatasourceManager instance already running. This is an error.')


    def _render_matrix(self):
        """ Invokes the connectivity matrix viewer """
        # assume the network is activated (i.e. data source generated)
        # we need the edge parameter instance initialized
        if self._edge_para is None:
            self._edge_para = EdgeParameters(self, self.rendermanager.attract.point_scalars_name)
            
        logger.debug('Invoke Matrix Viewer...')
        self.rendermanager.invoke_matrix_viewer()
        
    def _trackvis_launch(self):
        """ Generates scene file and launch Trackvis on the selected nodes """
        import tempfile
        
        logger.debug('Starting TrackVis ...')

        # extract selected subgraph
        selectionlist = self.get_selectiongraph_list()
        
        if len(selectionlist) == 0:
            # message            
            from enthought.traits.ui.message import message
            message(message = 'No nodes selected for ROI creation!', title = 'Infomessage', buttons = [ 'OK' ], parent = None)

        tmpgraph = self.graph.subgraph(selectionlist)

        # extract trackfile temporarily
        if len(self.tracks) == 0:
            logger.info('No trackfile found to invoke Trackvis.')
            return
        else:

            # load the first trackfile
            trackfname = self.tracks[0].load_trackfile_to_file()

            # find the first valid segmentation volume in the self.volumes list
            for vol in self.volumes:
                if vol.segmentation:
                    logger.debug('Found a segmentation volume file. Assume labels are corresponding.')
                    volumefname = vol.load_volume_to_file()
                    break

        # generate the scene file in the temporary folder
        tmpscenefile=tempfile.mkstemp(prefix='tmp', suffix='.scene')
            
        # generate trackfile        
        generate_scene_file(scenefname=tmpscenefile[1], \
                          trackfname = trackfname, \
                          volumefname = volumefname, \
                          selectiongraph = tmpgraph)
        
        # execute trackvis in a thread
        pref = preference_manager.preferences       
        action = ThreadedTrackvis(tvpath = pref.get('cviewer.plugins.ui.trackvispath'), \
                                    fname = tmpscenefile[1], \
                                    trkfname = trackfname,\
                                    volfname = volumefname)
        action.start()
    

    def add_surface_container(self, surfacecontainer):
        """ Add a surface container to the loaded list
        
        Parameters
        ----------
        surfacecontainer : `ISurfaceContainer` instance
            a surface container object
        
        """
        surfacecontainer._networkref = self
        self.surfaces_loaded.append(surfacecontainer)

    def add_volume(self, volume):
        """ Adds a volume to the volumes list
        
        Parameters
        ----------
        volume : `IVolume` instance
            a volume object
        
        """
        self.volumes.append(volume)
        
    def add_trackfile(self, trackfile):
        """ Adds a trackfile to the tracks list
        
        Parameters
        ----------
        trackfile : `ITrackfile` instance
            a trackfile of type ITrackfile
        
        """
        self.tracks.append(trackfile)

    def unselect_all(self):
        """ Unselects every node in the current network """
        if self.datasourcemanager is None:
            raise Exception('No DatasourceManager. You have to first activate the network and render it.')
        from numpy import array
        # get all the nodes
        graphnodes = self.datasourcemanager._srcobj.relabled_graph.nodes()
        # and unselect all nodes
        self.rendermanager._select_nodes(selection_node_array = array(graphnodes))

    def select_all(self):
        """ Selects all nodes in the current network """
        if self.datasourcemanager is None:
            raise Exception('No DatasourceManager. You have to first activate the network and render it.')
        from numpy import array
        # get all the nodes
        graphnodes = self.datasourcemanager._srcobj.relabled_graph.nodes()
        # and select all nodes
        self.rendermanager._select_nodes(selection_node_array = array(graphnodes), activate = True)
  
    def set_selectiongraph(self, sellist, activate = False):
        """ Sets the selected nodes in the network to active.
        
        Parameters
        ----------
        sellist : array_like
            a list of nodeids conforming to the NetworkX node id
        activate : boolean
            set the selectionlist nodes to activated?
        
        """
        from numpy import array, int16
        graphnodes = self.graph.nodes(data=False)

        if self.rendermanager is None:
            raise Exception('No RenderManager. You have to first activate the network and render it.')

        if len(sellist) == 0:
            self.unselect_all()
            return
        
        from numpy import array, append
        tmparr = array([])
        for node in sellist:
            # check if it is a valid graph node id
            if node in graphnodes:
                # get the node id as integer
                j = int(node.lstrip('n'))-1
                # extend empty array with node id
                tmparr = append(tmparr, j)
                
        self.rendermanager._select_nodes(selection_node_array = array(tmparr, dtype = int16), activate = activate)

    def get_selectiongraph_list(self):
        """ Returns a list of the node ids that were selected in
        the rendered scene.
        
        """
        if self.datasourcemanager is None:
            raise Exception('No DatasourceManager. You have to first activate the network and render it.')
        
        import numpy as np
        
        sel_list = []
        
        if not self.active:
            return sel_list
        
        selnodesarray = self.datasourcemanager._srcobj.selected_nodes
        
        # array with indices where the nodes are selected (==1)
        idx = np.where(selnodesarray == 1)[0]
        
        for i in idx:
            sel_list.append('n' + str(i + 1))
        
        return sel_list
        

    def set_weight_key(self, weight_key = None):
        """ Sets the weight key in the graph representation of the network.
        
        Parameters
        ----------
        weight_key : Str
            Must be a possible existing edge key
            
        """
        if not weight_key is None:
            for u,v,d in self.graph.edges(data=True):
                self.graph[u][v]['weight']=d[weight_key]
            return True
        else:
            return False

    def get_matrix(self, weight_key = None):
        """ Returns the connectivity matrix of the network with the nodes
        ordered according to their id in the GraphML file.
        
        Parameters
        ----------
        weight_key : Str
            Possible key value of the edges
        
        Returns
        -------
        matrix : `Numpy.array` instance
            The connectivity matrix
        
        """
        nr_nodes = len(self.graph.nodes())
        
        if not weight_key is None:
            #FIXME: sanity check if weight_key exists
            # thanks to Aric Hagberg
            for u,v,d in self.graph.edges(data=True):
                self.graph[u][v]['weight']=d[weight_key]
                
        nodes = [(lambda nmod:'n'+str(nmod))(node) for node in range(1,nr_nodes + 1)]
        from networkx import to_numpy_matrix
        return to_numpy_matrix(self.graph, nodelist = nodes)

    def toggle_surface(self):
        """ Toggle the surface for the selected network nodes """
        if self.rendermanager is None:
            raise Exception('No RenderManager. You have to first activate the network and render it.')
        self.rendermanager._toggle_surface()
        
    def show_surface(self):
        """ Shows the surface for the selected network nodes """
        if self.rendermanager is None:
            raise Exception('No RenderManager. You have to first activate the network and render it.')
        self.rendermanager._show_surface()

    def load_pickled_graphml(self, graph):
        """ Loads a pickled GraphML file
        
        Parameters
        ----------
        graph : NetworkX Graph instance
            A graph instance
            
        """
        
        # setting the graph
        self.graph = graph
        
        if self.graph.has_node('n0'):
            if self.graph.node['n0'].has_key('nodekeys'):
                # extracting the node keys from the first node
                self.nodekeys = self.graph.node['n0']['nodekeys']
                
            # extracting the edge keys from the first edge (without explanation)
            if self.graph.node['n0'].has_key('edgekeys'):
                self.edgekeys = self.graph.node['n0']['edgekeys']
                
            if self.graph.node['n0'].has_key('graphid'):
                self.networkid = self.graph.node['n0']['graphid']
                
            # remove node
            self.graph.remove_node('n0')
    
    def _return_default_edgevalue(self, edgekeys, key):
        """ Looks up if there is a default value defined, otherwise
        return zero """
        if edgekeys[key].has_key('default'):
            return float(edgekeys[key]['default'])
        else:
            return 0.0
    
    def parse_network_graphml(self, path):
        """ Read network in GraphML format from a path.
        
        Parameters
        ----------
        path : string
            path the the GraphML file
        
        Returns
        -------
        graph : NetworkX `Graph`
            
        """
        import networkx as nx
        from networkx.utils import _get_fh
        from lxml import etree
        
        # Return a file handle for given path.
        # Path can be a string or a file handle.
        # Attempt to uncompress/compress files ending in .gz and .bz2.
        
        fh=_get_fh(path,mode='r')
        
        tree = etree.parse(fh)
        # get the root node from parsed lxml
        root = tree.getroot()
        
        # Schema Validation
        # http://codespeak.net/lxml/validation.html#xmlschema
        
        # define the namespace prefixes
        nsprefix = "{%s}" % root.nsmap[None]
        nsxlink = "{%s}" % root.nsmap['xlink']
        
        nodekeys = {}
        edgekeys = {}
        defaultDirected = [True]
        
        # Parse the KEYs
        for child in root.iterchildren():
            if child.tag == (nsprefix+'key'):
                
                attribs = child.attrib
        
                ddkeys = {}
                for mchildren in child:
                    if mchildren.tag == (nsprefix+'default'):
                        ddkeys['default'] = mchildren.text
                    elif mchildren.tag == (nsprefix+'desc'):
                        ddkeys['desc'] = mchildren.text
        
                if child.attrib['for'] == 'node':
                    # Parse all the node keys
                    # Read in the description and the default (if existing)
                    # dict of dicts for nodes: key1: the id; key2: rest: attr.name, attr.type, desc, default
                    nodekeys[attribs['id']] = {'attr.name' : attribs['attr.name'], \
                                               'attr.type' : attribs['attr.type']}
                    # add default/desc keys if existing
                    nodekeys[attribs['id']] = ddkeys
                        
                elif child.attrib['for'] == 'edge':
                    # Parse all the edge keys
                    # Read in the description and the default (if existing)
                    # dict of dicts for edges: key1: the id; key2: rest: attr.name, attr.type, desc, default
                    edgekeys[attribs['id']] = {'attr.name' : attribs['attr.name'], \
                                               'attr.type' : attribs['attr.type']}
                    # add default/desc keys if existing
                    edgekeys[attribs['id']] = ddkeys
                    
                else:
                    logger.error("The 'for' attribute of key-tag not known, must be either node or edge")
                    
            elif child.tag == (nsprefix+'graph'):
                # start parsing the graph into networkx data structure
                # create graph depending on (either AttrGraph or AttrDiGraph)
                #   directionality: undirected/directed
                #   version of networkx:
                #   contains self-loops
                #   edges have dicts
                #   data per graph/node/edge
                for attr, value in child.items():
                    if attr == 'edgedefault' and value == 'undirected':
                        defaultDirected[0] = False
                    elif attr == 'id':
                        graphid = value
                
                if defaultDirected[0]:
                    G = nx.DiGraph()
                else:
                    G = nx.Graph()
    
                # add id, nodekeys and edkeys as traits               
                self.networkid = graphid
                self.nodekeys = nodekeys
                self.edgekeys = edgekeys
    
                # iterate over all nodes and edges
                for children in child.iterchildren():
                    if children.tag == (nsprefix+'node'):
                        
                        # parse the node
                        for attr, value in children.items():
                            if attr == 'id':
                                # add the node with corresponding id
                                G.add_node(value)
                                # keep node id to store attributes
                                nodeid = value
                            elif attr == (nsxlink+'href'):
                                # add xlink to node dictionary
                                G.node[nodeid]['xlink'] = value
                            else:
                                # node attribute not known
                                logger.warning('The following node attribute is not known and thus discarded:'+ attr + ':' + value)
        
                        # parse node data, add to node dict
                        for data in children.iterchildren():
                            # read the keylabel, i.e. the data attribute name
                            keylabel = data.attrib['key']
                            # is the keylabel in the list of allowed keys
                            if nodekeys.has_key(keylabel):
                                if not data.text == '':
                                    # add data to the node's dict
                                    G.node[nodeid][keylabel] = data.text

                                else:
                                    # no data available, check if default value exists
                                    if nodekeys[keylabel].has_key('default'):
                                        # add default data to the node's dict
                                        G.node[nodeid][keylabel] = nodekeys[keylabel]['default']
                                        logger.debug('Added default value '+ keylabel + ':' + nodekeys[keylabel]['default'])
                                    else:
                                        logger.warning('Nor data nor default value defined for ' + keylabel)
                                        # TODO: Work with exceptions!
                            else:
                                logger.warning("Data entry with key " + keylabel + " not defined.")
        
                        
                    elif children.tag == (nsprefix+'edge'):
                        
                        # parse the edge
                        # parse its attributes
                        for attr, value in children.items():
                            if attr == 'id':
                                # no usage of edge id
                                # add the edge with corresponding id
                                src = children.attrib['source']
                                tar = children.attrib['target']
                                G.add_edge(src, tar)
                                # keep dest and tar id to store attributes
                                srcid = src
                                tarid = tar
                            elif attr == (nsxlink+'href'):
                                # add xlink to edge dictionary
                                G.edge[srcid][tarid]['xlink'] = value
        
                        # parse data, and add to the edge dict
                        for data in children.iterchildren():
                            # read the keylabel, i.e. the data attribute name
                            keylabel = data.attrib['key']
                            # is the keylabel in the list of allowed keys
                            if self.edgekeys.has_key(keylabel):
                                if not data.text == '':
                                    # add data to the edge's dict, assume float!!
                                    G.edge[srcid][tarid][keylabel] = float(data.text)
                                else:
                                    # no data available, check if default value exists
                                    G.edge[srcid][tarid][keylabel] = self._return_default_edgevalue(self.edgekeys, keylabel)
                        data_keys = G.edge[srcid][tarid].keys()
                        # check if we missed some edge keys that are available in the header
                        for k, v in self.edgekeys.items():
                            if not k in data_keys:
                                G.edge[srcid][tarid][k] = self._return_default_edgevalue(self.edgekeys, k)
        
        # return the generated network graph
        return G
Beispiel #38
0
 def remove_node(self, n):
     Graph.remove_node(self, n)
     self.fh.write(f"Remove node: {n}\n")