Beispiel #1
0
def draw_edges(graph: nx.Graph, node_colors: list,
               node_positions: list) -> None:
    """Draw the network edges.

    If an edge has two nodes of the same color, use that color for the edge, otherwise
    make the edge a light gray.
    """
    nodes = graph.nodes()

    node_color_lookup = {}
    for (i, node) in enumerate(nodes):
        node_color_lookup[node] = node_colors[i]

    edge_colors = []
    for (i, edge) in enumerate(graph.edges()):
        (n1, n2) = edge
        c1 = node_color_lookup[n1]
        c2 = node_color_lookup[n2]
        edge_colors.append(c2)
        continue
        if c1 == c2:
            edge_colors.append(c1)
        else:
            edge_colors.append('#aaaaaa')
    edge_colors = [node_color_lookup[e[1]] for e in graph.edges()]

    nx.draw_networkx_edges(
        G=graph,
        pos=node_positions,
        with_labels=False,
        edge_color=edge_colors,
        alpha=0.025,
    )
Beispiel #2
0
def draw_pyplot_graph(graph: nx.Graph):
    """Will open a window with the NetworkX graph object drawn

    Given NetworkX graph object, calls matplotlib.pyplot to draw then show the graph object

    Args:
        graph: NetworkX Graph object, or derivative

    Requires:
        import matplotlib.pyplot as plt
    """
    # Create dict of key=node, value=pseudonode status (bool)
    pns = {v: d["pseudonode"] for _, v, d in graph.edges(data=True)}
    # color_map is an ordered list, where order is for `node in graph`
    # This is the same order nx.draw encounters nodes
    color_map = []
    for node in graph:
        if pns[node]:  # If node is a pseudonode ...
            color_map.append("blue")
        else:
            color_map.append("green")

    edge_labels = {(u, v): d["cost"] for u, v, d in graph.edges(data=True)}

    pos = nx.spring_layout(graph)
    nx.draw(graph, pos, node_color=color_map, with_labels=True, font_size=7)
    nx.draw_networkx_edge_labels(graph,
                                 pos,
                                 edge_labels=edge_labels,
                                 label_pos=0.3,
                                 font_size=7)
    plt.show()
def count_graph_distance(g1: nx.Graph, g2: nx.Graph, mapping: dict,
                         reverse_mapping: dict, sub: bool):
    d_vertex = 0
    d_edge = 0

    symbols1 = nx.get_node_attributes(g1, 'symbol')
    symbols2 = nx.get_node_attributes(g2, 'symbol')

    # count distance of vertices
    for node1 in g1.nodes():
        if mapping[node1] == -1:
            d_vertex += 1
        elif symbols1[node1] != symbols2[mapping[node1]]:
            d_vertex += 1
    if not sub:  # not sub graph distance
        for node2 in g2.nodes():
            if reverse_mapping[node2] == -1:
                d_vertex += 1

    # count distance of edges
    for first, second in g1.edges():
        if mapping[first] == -1 or mapping[second] == -1 or not g2.has_edge(
                mapping[first], mapping[second]):
            d_edge += 1
    if not sub:
        for first, second in g2.edges():
            if reverse_mapping[first] == -1 or reverse_mapping[second] == -1 \
                    or not g1.has_edge(reverse_mapping[first], reverse_mapping[second]):
                d_edge += 1

    return d_vertex + d_edge
Beispiel #4
0
def preprocess_transition_probs(sc: SparkContext, graph: nx.Graph, p, q,
                                is_directed):
    """
    Preprocessing of transition probabilities for guiding the random walks.
    """

    alias_nodes = {}
    for node in graph.nodes():
        unnormalized_probs = [
            graph[node][nbr]['weight'] for nbr in sorted(graph.neighbors(node))
        ]
        norm_const = sum(unnormalized_probs)
        normalized_probs = [
            float(u_prob) / norm_const for u_prob in unnormalized_probs
        ]
        alias_nodes[node] = alias_setup(normalized_probs)

    b_graph = sc.broadcast(graph)

    if is_directed:
        alias_edges = sc.parallelize(graph.edges(), 1000)\
            .map(lambda uv: ((uv[0], uv[1]), get_alias_edge(uv[0], uv[1], b_graph.value, p, q)))\
            .collectAsMap()
    else:
        alias_edges = sc.parallelize(graph.edges(), 1000)\
            .flatMap(lambda uv: [
                ((uv[0], uv[1]), get_alias_edge(uv[0], uv[1], b_graph.value, p, q)),
                ((uv[1], uv[0]), get_alias_edge(uv[1], uv[0], b_graph.value, p, q))
            ]).collectAsMap()

    return alias_nodes, alias_edges
Beispiel #5
0
def _assert_graphs_nx_equal(g1: nx.Graph, g2: nx.Graph):
    # Check number of nodes and edges
    assert g1.number_of_nodes() == g2.number_of_nodes()
    assert g1.number_of_edges() == g2.number_of_edges()

    # Check node features
    for (node_id_1, node_features_1), (node_id_2, node_features_2) in \
            zip(g1.nodes(data='features'), g2.nodes(data='features')):
        assert node_id_1 == node_id_2
        assert (node_features_1 is not None) == (node_features_2 is not None)
        if node_features_1 is not None and node_features_2 is not None:
            torch.testing.assert_allclose(node_features_1, node_features_2)

    # Check edge features
    for (sender_id_1, receiver_id_1, edge_features_1), (sender_id_2, receiver_id_2, edge_features_2) in \
            zip(g1.edges(data='features'), g2.edges(data='features')):
        assert sender_id_1 == sender_id_2
        assert receiver_id_1 == receiver_id_2
        assert (edge_features_1 is not None) == (edge_features_2 is not None)
        if edge_features_1 is not None and edge_features_2 is not None:
            torch.testing.assert_allclose(edge_features_1, edge_features_2)

    # Check graph features
    assert has_global_features(g1) == has_global_features(g2)
    if has_global_features(g1) and has_global_features(g2):
        torch.testing.assert_allclose(g1.graph['features'], g2.graph['features'])
Beispiel #6
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 #7
0
def solveClique(G: nx.Graph) -> list:
    """
    Solves the maximum clique problem.
    :param G: undirected graph
    :return: List of nodes
    """
    clique = Model('Clique')

    # Variable
    X = dict()

    for u in G.nodes():
        X[u] = clique.addVar(vtype=GRB.BINARY, name=f'X_{u}')

    # Constraints
    for u in G.nodes():
        for v in G.nodes():
            if (((u,v) not in G.edges()) or ((v,u) not in G.edges())) and (u != v):
                clique.addConstr(X[u] + X[v], GRB.LESS_EQUAL, 1)

    # Objective function
    clique.setObjective(quicksum(X[u] for u in G.nodes()), sense=GRB.MAXIMIZE)

    clique.update()
    clique.optimize()

    if clique.status == GRB.OPTIMAL:
        solution = list()
        for u in G.nodes():
            if round(clique.getVarByName(f'X_{u}').x, 0) == 1:
                solution.append(u)
        return solution

    else:
        return None
Beispiel #8
0
def ic_diffuse(g: nx.Graph, activated1, activated2):
    free_nodes = set(g.graph['free'])

    new_activated1 = []
    new_activated2 = []

    while activated1 + activated2:
        if activated1:
            node = activated1.pop(0)
            for edge in g.edges(node, data=True):
                if edge[1] in free_nodes:
                    r = np.random.random()
                    if r < edge[2]['w']:
                        # node is activated
                        new_activated1.append(edge[1])
                        activate(g, edge[1], 1)
                        free_nodes.remove(edge[1])

        if activated2:
            node = activated2.pop(0)
            for edge in g.edges(node, data=True):
                if edge[1] in free_nodes:
                    r = np.random.random()

                    if r < edge[2]['w']:
                        # node is activated
                        new_activated2.append(edge[1])
                        activate(g, edge[1], 2)
                        free_nodes.remove(edge[1])

    return new_activated1, new_activated2
Beispiel #9
0
def calculate_internal_external_densities(
    graph: nx.Graph,
    partitions: Dict[Any, Any],
    weight_attribute: str = 'weight'
) -> Tuple[Dict[Any, List[float]], Dict[Any, List[float]]]:
    """
    Calculates the internal and external densities given a graph and a node membership dictionary. Density is defined
    by 'How to Make the Team: Social Networks vs. Demography as Criteria for Designing Effective Teams' as being
    the mean strength of tie between members of the set. In other words, density is the normalized average of edge
    weights by node.

    For a given node, the density is the sum of all edge weights divided by the maximum edge weight for that node.

    For internal density, only the edge's whose target node is in the same membership group will be summed. Similarly,
    for external density, only the edge's whose target node is not in the same membership group will be summed.

    See also:
    Reagans, R., Zuckerman, E., & McEvily, B. (2004).
    How to Make the Team: Social Networks vs. Demography as Criteria for Designing Effective Teams.
    Administrative Science Quarterly, 49(1), 101–133. https://doi.org/10.2307/4131457

    :param graph: A weighted graph that the internal density will be calculated over
    :param Dict[any, int] partitions: A dictionary for the graph with each key being a node id and each value is
        the membership for that node id. Often this will be a partition dictionary calculated from
        topologic.louvain.best_partition
    :param str weight_attribute: The key to the weight column on the graph's edges

    :return: A tuple of two dictionaries. The first is the internal density and the second is the external density
    :rtype: Tuple[Dict[Any, List[float]], Dict[Any, List[float]]]
    """
    if not nx.is_weighted(graph, weight=weight_attribute):
        raise ValueError('The graph must be weighted.')

    # build a dictionary where the key is a membership_id and the value is a list of nodes that belong to that
    # membership
    membership_inverted: Dict[Any, List[Any]] = collections.defaultdict(list)
    for key in partitions.keys():
        membership_inverted[partitions[key]].append(key)

    internal_density: Dict[Any, List[float]] = collections.defaultdict(list)
    external_density: Dict[Any, List[float]] = collections.defaultdict(list)

    for partition_id in membership_inverted.keys():
        for node in membership_inverted[partition_id]:
            max_weight = max((weight for source, target, weight in graph.edges(
                node, data=weight_attribute)))

            for source, target, weight in graph.edges(node,
                                                      data=weight_attribute):
                target_partition = partitions[target]
                density_for_node = weight / max_weight

                if target_partition == partition_id:
                    internal_density[partition_id].append(density_for_node)
                else:
                    external_density[partition_id].append(density_for_node)

    return internal_density, external_density
Beispiel #10
0
def extract_subgraph_by_bond_type(
    g: nx.Graph,
    bond_types: List[str],
    filter_dataframe: bool = True,
    update_coords: bool = True,
    recompute_distmat: bool = False,
    inverse: bool = False,
    return_node_list: bool = False,
) -> Union[nx.Graph, List[str]]:
    """Extracts a subgraph from a graph based on a list of allowable bond types.

    :param g: The graph to extract the subgraph from.
    :type g: nx.Graph
    :param bond_types: List of allowable bond types.
    :type bond_types: List[str]
    :param filter_dataframe: Whether to filter the pdb_df of the graph, defaults to True
    :type filter_dataframe: bool, optional
    :param update_coords: Whether to update the coordinates of the graph. Defaults to True.
    :type update_coords: bool
    :param recompute_distmat: Whether to recompute the distance matrix of the graph. Defaults to False.
    :type recompute_distmat: bool
    :param inverse: Whether to inverse the selection, defaults to False
    :type inverse: bool, optional
    :param return_node_list: Whether to return the node list, defaults to False
    :type return_node_list: bool, optional
    :return: The subgraph or node list if return_node_list is True.
    :rtype: Union[nx.Graph, List[str]]
    """

    node_list: List = []

    for u, v, d in g.edges(data=True):
        for bond_type in list(d["kind"]):
            if bond_type in bond_types:
                node_list.append(u)
                node_list.append(v)
    node_list = list(set(node_list))
    log.debug(f"Found {len(node_list)} nodes in the bond type subgraph.")

    # Remove bond annotations
    for u, v, d in g.edges(data=True):
        for bond in list(d["kind"]):
            if not inverse:
                if bond not in bond_types:
                    d["kind"].discard(bond)
            elif inverse:
                if bond in bond_types:
                    d["kind"].discard(bond)

    return extract_subgraph_from_node_list(
        g,
        node_list,
        filter_dataframe=filter_dataframe,
        inverse=inverse,
        return_node_list=return_node_list,
        recompute_distmat=recompute_distmat,
        update_coords=update_coords,
    )
def update_cost(  # pylint: disable=too-many-arguments
    G: nx.Graph,
    gdf: gpd.GeoDataFrame,
    edge_df: Optional[gpd.GeoDataFrame] = None,
    cost_attr: Optional[str] = "cost",
    weight_attr: Optional[str] = "weight",
    key_attr: Optional[str] = "key",
) -> nx.Graph:
    """Update the cost of edges the graph from a geo dataframe.

    Args:
        G: Input graph. Must have a geometry attribute on the edges.
        gdf: Must contain geometry column and value column.
        edge_df: The edge geo dataframe of the graph.

    Other Args:
        cost_attr: Name of the cost function.
        weight_attr: Name of the weight function.
        key_attr: Name of the key for multi graphs.

    Returns:
        Graph with updated cost attribute.
    """
    # convert G to geodataframe
    if edge_df is None:
        # for a multigraph, remember the keys
        for u, v, k in G.edges(keys=True):
            G[u][v][k][key_attr] = k

        # # create a geodataframe
        edge_df = ox.graph_to_gdfs(G, nodes=False, fill_edge_geometry=True)
        edge_df = edge_df.rename(columns=dict(u="source", v="target"))

    # check the crs of geometries
    if edge_df.crs is None and not gdf.crs is None:
        edge_df.crs = gdf.crs
    elif gdf.crs is None and not edge_df.crs is None:
        gdf.crs = edge_df.crs

    # get intersection of the geodataframes
    logging.info("%s rows in edge dataframe", len(edge_df))
    join = gpd.sjoin(edge_df, gdf, how="left")
    logging.info("%s rows in join dataframe", len(join))

    edges_in_join = zip(join["source"], join["target"])
    for u, v in G.edges():
        assert (u, v) in edges_in_join or (v, u) in edges_in_join

    # group the edges and take average pollution
    for key, value in (
        join.groupby(["source", "target", "key"])[cost_attr].mean().iteritems()
    ):
        i, j, k = key[0], key[1], key[2]
        G[i][j][k]["gamma"] = value if value >= 0 else 0
        G[i][j][k][cost_attr] = value * G[i][j][k][weight_attr]

    return G
Beispiel #12
0
class Electrical_network():
    """ Electrical Network: graph, power injections, electrical state (phases and frequencies)

	inputs: list of buses (id, {dict}), list of lines (id, {dict}) """
    def __init__(self, buses, lines):

        # create networkx graph
        self.graph = Graph()
        self.graph.add_nodes_from(buses)
        self.graph.add_edges_from(lines)
        self.state = State(self.graph.number_of_nodes())

        self.sm_id = filter(lambda n: self.graph.nodes[n]['sm'] == True,
                            self.graph.nodes)
        self.load_id = filter(lambda n: self.graph.nodes[n]['sm'] == False,
                              self.graph.nodes)

        # unweighted incidence in shape (|nodes| x |edges|), column ordering is produced by graph.edges
        self.incidence = incidence_matrix(self.graph, oriented=True)

        self.node_coord = np.array(
            [self.graph.nodes[n]['coord'] for n in self.graph.nodes])
        self.edge_coord = np.array([
            (self.node_coord[e[0]] + self.node_coord[e[1]]) / 2.
            for e in self.graph.edges()
        ])

    def get_P(self):
        return np.array(
            [self.graph.nodes[n]['power'] for n in self.graph.nodes])

    # inertia and damping coeffs, ordered according to sm_id and load_id
    def get_I_sm(self):
        return np.array([self.graph.nodes[n]['inertia'] for n in self.sm_id])

    def get_D_sm(self):
        return np.array([self.graph.nodes[n]['damping'] for n in self.sm_id])

    def get_D_load(self):
        return np.array([self.graph.nodes[n]['damping'] for n in self.load_id])

    # edge susceptance, edge ordering is produced by graph.edges
    def get_active_susceptance(self):
        return diags([
            self.graph[e[0]][e[1]]['susceptance'] *
            int(self.graph[e[0]][e[1]]['status']) for e in self.graph.edges()
        ])

    # edge susceptance, edge ordering is produced by graph.edges
    def get_susceptance(self):
        return diags([
            self.graph[e[0]][e[1]]['susceptance'] for e in self.graph.edges()
        ])
Beispiel #13
0
    def calculate_dot_product_similarity(sub_graph: nx.Graph,
                                         super_graph: nx.Graph):
        a_values = np.ones(len(sub_graph.nodes()) + len(sub_graph.edges()))
        b_values = np.zeros(len(a_values))
        for i, node in enumerate(sub_graph.nodes()):
            if node in super_graph.nodes():
                b_values[i] = 1
        for i, edge in enumerate(sub_graph.edges()):
            if ParsemisMiner.graph_has_edge(super_graph, sub_graph, edge):
                b_values[i + len(sub_graph.nodes())] = 1

        return np.prod(np.column_stack(
            (a_values, b_values)), axis=1).sum() / len(a_values)
def graph_to_list_differences(g: nx.Graph,
                              original_graph_complement: nx.Graph):
    """
    Converte um grafo para a sua forma binária considerando apenas as arestas
    que foram adicionadas em relação ao seu original.
    """
    complement_edges = list(original_graph_complement.edges())
    graph_edges = list(g.edges())
    bin_differences_list = [
        1 if e in graph_edges and complement_edges else 0
        for e in complement_edges
    ]
    # List_Gr = [0 for e in Complement.edges() if e in Gr.edges()]
    return bin_differences_list
Beispiel #15
0
def planarize(G: nx.Graph):
    '''
	Takes a graph with node embeddings in R^2 and removes random edges until planar.
	'''
    pos = nx.get_node_attributes(G, 'pos')
    assert pos != {}, 'planarize() needs a node embedding'

    def on_segment(p, q, r):
        if r[0] <= max(p[0], q[0]) and r[0] >= min(p[0], q[0]) and r[1] <= max(
                p[1], q[1]) and r[1] >= min(p[1], q[1]):
            return True
        return False

    def orientation(p, q, r):
        val = ((q[1] - p[1]) * (r[0] - q[0])) - ((q[0] - p[0]) * (r[1] - q[1]))
        if val == 0: return 0
        return 1 if val > 0 else -1

    def intersects(seg1, seg2):
        p1, q1 = seg1
        p2, q2 = seg2

        o1 = orientation(p1, q1, p2)
        o2 = orientation(p1, q1, q2)
        o3 = orientation(p2, q2, p1)
        o4 = orientation(p2, q2, q1)

        if o1 != o2 and o3 != o4:
            return True

        if o1 == 0 and on_segment(p1, q1, p2): return True
        if o2 == 0 and on_segment(p1, q1, q2): return True
        if o3 == 0 and on_segment(p2, q2, p1): return True
        if o4 == 0 and on_segment(p2, q2, q1): return True

        return False

    deleted = set()
    for e1 in G.edges():
        for e2 in G.edges():
            if not (e1 in deleted or e2 in deleted or e1[0] in e2
                    or e1[1] in e2):
                e1_pos = (pos[e1[0]], pos[e1[1]])
                e2_pos = (pos[e2[0]], pos[e2[1]])
                if intersects(e1_pos, e2_pos):
                    deleted.add(e1)

    G.remove_edges_from(deleted)
    return G
Beispiel #16
0
def check_embedding(Q, A, emb, **args):
    from networkx import Graph, is_connected
    check_embedding.warning = None
    Qg = Graph()
    Ag = Graph()
    Qg.add_edges_from(Q)
    Ag.add_edges_from(A)

    qubhits = 0
    footprint = set()
    var = {}
    for x in Qg:
        try:
            embx = emb[x]
        except KeyError:
            check_embedding.errcode = "missing chain"
            return False
        for q in embx:
            var[q] = x
        footprint.update(embx)
        qubhits += len(embx)
        if not is_connected(Ag.subgraph(embx)):
            check_embedding.errcode = "broken chain for %s: (%s)" % (x, embx)
            return False
    if len(footprint) != qubhits:
        check_embedding.errcode = "overlapped chains"
        return False

    Qv = Graph()
    for p, q in Ag.edges():
        try:
            Qv.add_edge(var[p], var[q])
        except KeyError:
            continue
    for x, y in Qg.edges():
        if not Qv.has_edge(x, y):
            check_embedding.errcode = "missing edge"
            return False

    for x, chain in args.get("fixed_chains", {}).items():
        if set(chain) != set(emb[x]):
            check_embedding.errcode = "fixed chain mismatch"
            return False
    for x, domain in args.get("restrict_chains", {}).items():
        if not set(domain) >= set(emb[x]):
            check_embedding.warning = "restrict chain mismatch"

    return True
Beispiel #17
0
def draw_pyplot_graph(graph: nx.Graph):
    """Will open a window with the NetworkX graph object drawn

    Given NetworkX graph object, calls matplotlib.pyplot to draw then show the graph object

    Args:
        graph: NetworkX Graph object, or derivative

    Requires:
        import matplotlib.pyplot as plt
    """
    # Node colouring + Pseudonode handling
    # Create dict keyed by node, value is pseudonode status (bool)
    pns = {v: d["pseudonode"] for _, v, d in graph.edges(data=True)}
    # color_map is an ordered list, where order is for `node in graph`
    # This is the same order nx.draw encounters nodes
    color_map = [
        "green"
        if not node in list(pns.keys()) else "blue" if pns[node] else "green"
        for node in graph
    ]

    # Edge labelling
    edge_labels = {(u, v): d["cost"] if d["cost"] > 0 else ""
                   for u, v, d in graph.edges(data=True)}

    # Edge Colouring
    edge_color = nx.get_edge_attributes(graph, "color").values()

    # Edge weight
    edge_weight = nx.get_edge_attributes(graph, "weight").values()

    pos = nx.spring_layout(graph)
    nx.draw(
        graph,
        pos,
        node_color=color_map,
        edge_color=edge_color,
        width=list(edge_weight),
        with_labels=True,
        font_size=7,
    )
    nx.draw_networkx_edge_labels(graph,
                                 pos,
                                 edge_labels=edge_labels,
                                 label_pos=0.3,
                                 font_size=7)
    plt.show()
Beispiel #18
0
def initial_flow(G: nx.Graph,
                 KE: float = 1.,
                 scale_distribution: Callable = None):
    '''
	Construct divergence-free initial conditions with energies at specified length-scales.

	scale_distribution: probability measure on [0, 1] (default uniform)
	'''
    assert KE >= 0, 'Specify nonnegative kinetic energy'
    if scale_distribution is None:
        scale_distribution = lambda x: 1.

    N = len(G.edges())
    P = gds.edge_gds(
        G).leray_projector  # TODO: assumes determinism of construction
    freqs, spec_fun = edge_power_spectrum(G)
    dist = np.array(
        list(
            map(scale_distribution,
                (freqs - freqs.min()) / (freqs.max() - freqs.min()))))

    def f(x):
        return np.linalg.norm(spec_fun(P @ x) - dist)

    x0 = np.random.uniform(size=N)
    sol = minimize(f, x0)
    u = P @ sol.x
    u *= np.sqrt(KE / np.dot(u, u))
    return u
Beispiel #19
0
    def _prepare_data(self, g_netx: nx.Graph, custom_node_labels: Dict) -> Tuple[List, List, List, nx.graph.EdgeView]:
        """Create the scatter plot data from a NetworkX Graph.

        Args:
            g_netx (nx.Graph):
            custom_node_labels (Dict):
        """

        graph_components = [comp for comp in nx.connected_components(g_netx)]
        graph_edges = g_netx.edges()
        # Prepare the node groups and colors
        communities_dict = {}
        for community_ind, graph_component in enumerate(graph_components):
            for node in graph_component:
                if custom_node_labels:
                    communities_dict[node] = custom_node_labels[node]
                else:
                    communities_dict[node] = community_ind
        nodes_with_colors = []
        node_labels = []
        for node in g_netx.nodes():
            labels_current = node
            node_labels.append("Node: {}".format(labels_current))
            try:
                nodes_with_colors.append(communities_dict[node])
            except KeyError:
                print("Node %d in small community" % node)

        return graph_components, nodes_with_colors, node_labels, graph_edges
async def populate_exchange_graph(graph: nx.Graph,
                                  exchange: ccxt.Exchange,
                                  log=True,
                                  fees=False,
                                  suppress=None,
                                  depth=False,
                                  invocation_id=0) -> nx.DiGraph:
    """
    Returns a Networkx DiGraph populated with the current ask and bid prices for each market in graph (represented by
    edges)
    """
    if suppress is None:
        suppress = ['markets']
    adapter = LoadExchangeGraphAdapter(logger, {
        'count': invocation_id,
        'exchange': exchange.id
    })

    result = nx.DiGraph()

    tasks = [
        _add_weighted_edge_to_graph(exchange,
                                    edge[2]['market_name'],
                                    result,
                                    adapter,
                                    log=log,
                                    fees=fees,
                                    suppress=suppress,
                                    depth=depth)
        for edge in graph.edges(data=True)
    ]
    await asyncio.wait(tasks)
    await exchange.close()

    return result
 def generate_small_world_graph(self):
     max_edges = self.NODE_COUNT*(self.NODE_COUNT-1)/2
     if self.EDGE_COUNT > max_edges:
         return complete_graph(self.NODE_COUNT)
     graph = Graph()
     graph.add_nodes_from(range(self.NODE_COUNT))
     edges = performer.edge_indices.flatten()
     probabilities = performer.probabilities.flatten()
     for trial in range(len(edges)-9):
         edge_index = numpy.random.choice(edges, p=probabilities)
         source, destination = self.edge_nodes(edge_index)
         graph.add_edge(source, destination, length = self.link_length(source, destination),
                        weight = self.edge_weight(source, destination))
         probabilities[edge_index] = 0
         probabilities /= sum(probabilities)
         if max(graph.degree().values()) > self.DEGREE_MAX:
             graph.remove_edge(source, destination)
         if graph.number_of_edges() > self.EDGE_COUNT:
             victim = random.choice(graph.edges())
             graph.remove_edge(victim[0], victim[1])
         if self.constraints_satisfied(graph):
             print 'performer.generate_small_world_graph:',
             print self.BENCHMARK, self.NODE_COUNT, self.EDGE_COUNT, trial
             self.process_graph(graph)
             return graph
Beispiel #22
0
def search_direct_relationships(
        graph: Graph,
        source: Optional[Dict] = None,
        edge: Optional[Dict] = None,
        target: Optional[Dict] = None) -> Iterable[Tuple]:
    """Search direct relation ship.

    Arguments:
        graph (Graph): graph instance
        source (Optional[Dict]): optional source node query constraint
        edge (Optional[Dict]): optional edge query constraint
        target (Optional[Dict]): optional target node query constraint

    Returns:
        (Iterable[Tuple]): itrable tuple of edge

    """
    _iterable = search_edges(graph=graph,
                             query=edge) if edge else graph.edges()

    if source:
        _predicate_source = prepare_query(source)
        _iterable = filter(
            lambda edge: _predicate_source(graph.nodes[edge[0]]), _iterable)

    if target:
        _predicate_target = prepare_query(target)
        _iterable = filter(
            lambda edge: _predicate_target(graph.nodes[edge[1]]), _iterable)

    return _iterable
Beispiel #23
0
def make_double(graph: nx.Graph):
    newgraph = nx.Graph()
    offset = graph.graph['max_id']
    for u, v in graph.edges():
        newgraph.add_edge(u, v + offset)
        newgraph.add_edge(v, u + offset)
    return newgraph
Beispiel #24
0
def get_edge_index(G: Graph) -> torch.LongTensor:
    """
    Create pytorch geometric edge_index from a networkx graph.
    """
    edge_index = toolz.functoolz.pipe(G.edges(), map(list), list,
                                      torch.LongTensor)
    return edge_index.t().contiguous()
Beispiel #25
0
def _edge_coords(g: nx.Graph, l: dict) -> dict:
    """Converts coordinates for the graph edges for plotting purposes.

        Args:
            g (nx.Graph): input graph
            l (dict[int, float]): Dictionary of nodes and their respective coordinates. Can be
                generated using a NetworkX `layout <https://networkx.github.io/documentation/latest/
                reference/drawing.html#module-networkx.drawing.layout>`__

        Returns:
             dict[str, list]: lists of x and y coordinates for the beginning and end of each edge.
             ``None`` is placed as a separator between pairs of nodes/edges.
        """
    e_x = []
    e_y = []

    for e in g.edges():

        start_x, start_y = l[e[0]]
        end_x, end_y = l[e[1]]

        e_x.append(start_x)
        e_x.append(end_x)

        e_y.append(start_y)
        e_y.append(end_y)

        e_x.append(None)
        e_y.append(None)

    return {"x": e_x, "y": e_y}
Beispiel #26
0
    def __init__(self, binaryId: str, g: nx.Graph, label: int,
                 node_tags: int = None, node_features=None):
        """
        g: a networkx graph
        label: an integer graph label
        node_tags: a list of integer node tags
        node_features: a numpy array of continuous node features
        """
        self.bId = binaryId
        self.num_nodes = len(node_tags)
        self.node_tags = node_tags
        self.label = None if label == '?' else label
        self.node_features = node_features  # nparray (node_num * feature_dim)
        self.degs = list(dict(g.degree).values())

        if g.number_of_edges() != 0:
            x, y = zip(*g.edges())
            self.num_edges = len(x)
            self.edge_pairs = np.ndarray(shape=(self.num_edges, 2), dtype=np.int32)
            self.edge_pairs[:, 0] = x
            self.edge_pairs[:, 1] = y
            self.edge_pairs = self.edge_pairs.flatten()
        else:
            self.num_edges = 0
            self.edge_pairs = np.array([])
            log.warning(f'{binaryId} has no edge')
            log.debug(f'{binaryId} #nodes: {self.num_nodes}, label: {label}')
Beispiel #27
0
def make_prim_mst(G, generator=None):
    if generator is None:
        mst = Graph()
    else:
        mst = generator()
    #priorityQ is a list of list (the reverse of the edge tuple with the weight in the front)
    priorityQ = []
    firstNode = G.nodes()[0]
    mst.add_node(firstNode)
    for edge in G.edges_iter(firstNode, data=True):
        if len(edge) != 3 or edge[2] is None:
            raise ValueError, "make_prim_mst accepts a weighted graph only (with numerical weights)"
        heappush(priorityQ, (edge[2], edge))

    while len(mst.edges()) < (G.order() - 1):
        w, minEdge = heappop(priorityQ)
        if len(minEdge) != 3 or minEdge[2] is None:
            raise ValueError, "make_prim_mst accepts a weighted graph only (with numerical weights)"
        v1, v2, w = minEdge
        if v1 not in mst:
            for edge in G.edges_iter(v1, data=True):
                if edge == minEdge:
                    continue
                heappush(priorityQ, (edge[2], edge))
        elif v2 not in mst:
            for edge in G.edges_iter(v2, data=True):
                if edge == minEdge:
                    continue
                heappush(priorityQ, (edge[2], edge))
        else:
            # non-crossing edge
            continue
        mst.add_edge(minEdge[0], minEdge[1], minEdge[2])
    return mst
Beispiel #28
0
def make_prim_mst(G, generator=None):
	if generator is None:
		mst = Graph()
	else:
		mst = generator()       
	#priorityQ is a list of list (the reverse of the edge tuple with the weight in the front)
	priorityQ = []
	firstNode = G.nodes()[0]
	mst.add_node(firstNode)
	for edge in G.edges_iter(firstNode, data=True):
		if len(edge) != 3 or edge[2] is None:
			raise ValueError, "make_prim_mst accepts a weighted graph only (with numerical weights)"
		heappush(priorityQ, (edge[2], edge))

	while len(mst.edges()) < (G.order()-1):
		w, minEdge = heappop(priorityQ)
		if len(minEdge) != 3 or minEdge[2] is None:
			raise ValueError, "make_prim_mst accepts a weighted graph only (with numerical weights)"
		v1, v2, w = minEdge
		if v1 not in mst:
			for edge in G.edges_iter(v1, data=True):
				if edge == minEdge:
					continue
				heappush(priorityQ, (edge[2], edge))
		elif v2 not in mst:
			for edge in G.edges_iter(v2, data=True):
				if edge == minEdge:
					continue
				heappush(priorityQ, (edge[2], edge))
		else:
			# non-crossing edge 
			continue 
		mst.add_edge(minEdge[0],minEdge[1],minEdge[2])
	return mst
Beispiel #29
0
 def add_existing_knowledge_graph(self, another_graph: nx.Graph):
     """
         Merge an existing knowledge graph into the current graph.
     """
     self.add_nodes_from(another_graph.nodes(data=True))
     self.add_edges_from(another_graph.edges(data=True))
     return
Beispiel #30
0
def _assert_graph_and_graph_nx_equals(graph: tg.Graph, graph_nx: nx.Graph):
    # Check number of nodes and edges
    assert graph_nx.number_of_nodes() == graph.num_nodes
    assert graph_nx.number_of_edges() == graph.num_edges

    # Check node features
    assert has_node_features(graph) == has_node_features(graph_nx)
    if has_node_features(graph) and has_node_features(graph_nx):
        for node_features_nx, node_features in zip(graph_nx.nodes(data='features'), graph.node_features):
            torch.testing.assert_allclose(node_features_nx[1], node_features)

    # Check edge indexes
    for (sender_id_nx, receiver_id_nx, *_), sender_id, receiver_id in \
            zip(graph_nx.edges, graph.senders, graph.receivers):
        assert sender_id_nx == sender_id
        assert receiver_id_nx == receiver_id

    assert has_edge_features(graph) == has_edge_features(graph_nx)
    if has_edge_features(graph) and has_edge_features(graph_nx):
        for (*_, edge_features_nx), edge_features in zip(graph_nx.edges(data='features'), graph.edge_features):
            torch.testing.assert_allclose(edge_features_nx, edge_features)

    # Check graph features
    assert has_global_features(graph) == has_global_features(graph_nx)
    if has_global_features(graph) and has_global_features(graph_nx):
        torch.testing.assert_allclose(graph_nx.graph['features'], graph.global_features)
def get_properties(network: nx.Graph):
    N = len(network)
    L = len(list(network.edges()))
    D = nx.density(network)
    d = nx.diameter(network)
    C = nx.average_clustering(network, weight="weight")
    return N, L, D, d, C
Beispiel #32
0
    def test_happy_path(self):
        graph = Graph()
        initial_node = gen_name()
        graph.add_node(initial_node, layer=0, position=(0.5, 0.5), label='E')

        if visualize_tests:
            visualize_graph_3d(graph)
            pyplot.show()

        P1().apply(graph, [initial_node])

        nodes_data = graph.nodes(data=True)

        self.assertEqual(len(graph.nodes()), 7)
        self.assertEqual(len(graph.edges()), 13)

        # check the initial node
        initial_node_data = nodes_data[initial_node]
        self.assertEqual(initial_node_data['layer'], 0)
        self.assertEqual(initial_node_data['position'], (0.5, 0.5))
        self.assertEqual(initial_node_data['label'], 'e')

        # check other nodes
        vx_bl = get_node_at(graph, 1, (0, 0))
        vx_br = get_node_at(graph, 1, (1, 0))
        vx_tl = get_node_at(graph, 1, (0, 1))
        vx_tr = get_node_at(graph, 1, (1, 1))
        self.assertIsNotNone(vx_bl)
        self.assertIsNotNone(vx_br)
        self.assertIsNotNone(vx_tl)
        self.assertIsNotNone(vx_tr)
        self.assertEqual(nodes_data[vx_bl]['label'], 'E')
        self.assertEqual(nodes_data[vx_br]['label'], 'E')
        self.assertEqual(nodes_data[vx_tl]['label'], 'E')
        self.assertEqual(nodes_data[vx_tr]['label'], 'E')

        vx_i1 = get_node_at(graph, 1, (2 / 3, 1 / 3))
        vx_i2 = get_node_at(graph, 1, (1 / 3, 2 / 3))
        self.assertIsNotNone(vx_i1)
        self.assertIsNotNone(vx_i2)
        self.assertEqual(nodes_data[vx_i1]['label'], 'I')
        self.assertEqual(nodes_data[vx_i2]['label'], 'I')

        self.assertTrue(graph.has_edge(initial_node, vx_i1))
        self.assertTrue(graph.has_edge(initial_node, vx_i2))
        self.assertTrue(graph.has_edge(vx_tl, vx_tr))
        self.assertTrue(graph.has_edge(vx_tr, vx_br))
        self.assertTrue(graph.has_edge(vx_br, vx_bl))
        self.assertTrue(graph.has_edge(vx_bl, vx_tl))
        self.assertTrue(graph.has_edge(vx_bl, vx_tr))
        self.assertTrue(graph.has_edge(vx_i1, vx_bl))
        self.assertTrue(graph.has_edge(vx_i1, vx_br))
        self.assertTrue(graph.has_edge(vx_i1, vx_tr))
        self.assertTrue(graph.has_edge(vx_i2, vx_bl))
        self.assertTrue(graph.has_edge(vx_i2, vx_tl))
        self.assertTrue(graph.has_edge(vx_i2, vx_tr))

        if visualize_tests:
            visualize_graph_3d(graph)
            pyplot.show()
def summarize_email(raw_text, sender=None,  language='english'):
    raw_text = strip_signature(raw_text, sender)
    stopwords = cachedStopWords
    sentence_list = tokenize.sent_tokenize(raw_text, language)
    word_set = [get_tokenized(sentence, stopwords) for sentence in sentence_list]

    graph = Graph()
    pairs = itertools.combinations(enumerate(filter(None, word_set)), 2)
    for (index_a, words_a), (index_b, words_b) in pairs:
        similarity = cosine(words_a, words_b)
        if similarity > 0:
            graph.add_edge(index_a, index_b, weight=similarity)

    if not graph.edges():
        return sentence_list[0]

    ranked_sentence_indexes = pagerank(graph).items()
    sentences_by_rank = sorted(ranked_sentence_indexes, key=itemgetter(1), reverse=True)
    summary_size = int(math.ceil(len(sentence_list) / 3))
    best_sentences = map(itemgetter(0), sentences_by_rank[:summary_size])
    best_sentences_in_order = sorted(best_sentences)
    return ' '.join(sentence_list[index] for index in best_sentences_in_order)
Beispiel #34
0
    def getGraphInfo(self, model, geneList):
        #get undirected graph
        undirected = self.to_undirected()

        #calculate 5th percentile weight
        sort = list()
        for edge in self.edges(data=True):
            sort.append(edge[2]['weight'])
        sort.sort()
        fifth = sort[int(math.ceil(len(sort))*0.05-1)]

        genes = self.geneToNode.keys()

        geneTuples = set()
        for gene in genes:
            geneTuples.add((gene,''))
            geneTuples.add((gene,"NOT"))


        subTerms = set()
        test = Graph()
        length = 0

        copyGraph = self.createDiGraphCopy(geneTuples)

        subTerms = set()
        for gene in list(geneList):
            subTerms.update(self.getNodesByGene(gene))

        undirected = self.augmentGraph(undirected, list(subTerms), geneTuples, fifth)
        test = make_steiner_tree(undirected, list(subTerms))
        length = 0
        for subEdge in test.edges():
            length += test.edge[subEdge[0]][subEdge[1]]['weight']

        prob = calcProb(length, len(geneList), model)

        return prob, test
Beispiel #35
0
def sample_edges_ic(graph: nx.Graph, seed_set: Sequence[NxDocumentNode]) -> Sequence[NxDocumentNode]:
    """
    Samples every edge in the graph with the probability = similarity.

    Args:
        graph: The graph on which we should operate.
        seed_set: A set of nodes which are 'active' at the beginning.

    Returns:
        The set of reachable nodes given the seed set and the edges we sampled.
    """

    sampled = nx.Graph(graph)
    sampled.remove_edges_from(sampled.edges())

    for from_node, to_node, data in graph.edges(data=True):
        if random.random() <= data['similarity']:
            # Note: Batching this (i.e. only add all sampled at once) actually
            # slows things down under NetworkX...
            sampled.add_edge(from_node, to_node)

    all_reached = DefaultReachability().compute_reachability(sampled, seed_set)
    return all_reached
Beispiel #36
0
def read_graph(path):
    # Error object to be used if parsing fails
    error = IOError("Format of file %s is illegal" % path)

    with open(path) as graph_file:
        g = Graph()

        # Read the first line for number of nodes and number of edges
        nv, ne = read_line(graph_file.readline())

        # Traverse all lines
        for line in graph_file.readlines():
            n1, n2 = read_line(line)

            # Check whether the nodes are in a legal range
            if (n1 > nv or n1 < 1 or n2 > nv or n2 < 1):
                raise error
            g.add_edge(n1, n2)

        # Check the number of edges is correct
        if len(g.edges()) != ne:
            raise error

        return g
from networkx import Graph
entries = Graph()
#entries.add_node('@davidmartinb')
#entries.add_node('@emartinborregon')
entries.add_edge('@davidmartinb','@emartinborregon')
#entries.add

entries2 = entries.copy()
#entries.add_node('@davidmartinb')
#entries.add_node('@emartinborregon')
entries2.add_edge('@davidmartinb','@test')
entries.add_edge('@davidmartinb','@emartinborregon')
#entries.add
print set(entries2.nodes())-set(entries.nodes())
edges1=entries.edges()
entries2.remove_edges_from( edges1 )
print entries2.edges()
Beispiel #38
0
    ips = {}
    # filter all relays in this consensus to those that
    # have a descriptor, are running, and are fast
    for relay in consensus.relays:
        if (relay in descriptors):
            sd = descriptors[relay] # server descriptor
            rse = consensus.relays[relay] # router status entry
            if "Running" in rse.flags and "Fast" in rse.flags:
                if relay not in ips: ips[relay] = []
                ips[relay].append(sd.address)
    # build edges between every relay that could have been
    # selected in a path together
    for r1 in ips:
        for r2 in ips:
            if r1 is r2: continue
            g.add_edges_from(product(ips[r1], ips[r2]))                    
    nsf_i += 1
    # check if we should do a checkpoint and save our progress
    if nsf_i == nsf_len or "01-00-00-00" in fname:
        chkpntstart = fname[0:10]
        with open("relaypairs.{0}--{1}.json".format(chkpntstart, chkpntend), 'wb') as f: json.dump(g.edges(), f)

print ""
print('Num addresses: {0}'.format(g.number_of_nodes()))
print('Num unique pairs: {0}'.format(g.number_of_edges()))

# write final graph to disk
with open(out_file, 'wb') as f: json.dump(g.edges(), f)
##########

degreeMap = nx.degree(random_bipartite_graph)
sortedval = sorted(degreeMap.items(),key = lambda x : x[1],reverse=True)

for val in range(10):

    if val == 5:
        for node_value in range(min_value_x+10):
            node = random_bipartite_graph.nodes()[node_value]

            if not node_value in corrupted_node:
                corrupted_node[node_value] = {}

            corrupted_node[node_value]['old'] = degreeMap[node_value]
            compare_val = min_value + 0.9*(max_value - min_value)
            for node_val in range(min_value,int(compare_val)):
                edgeArr = random_bipartite_graph.edges()
                if not (node,node_val) in edgeArr:
                    random_bipartite_graph.add_edge(node,node_val)

    pageRankMap = nx.pagerank(random_bipartite_graph)
    for i in pageRankMap:
        if i not in pageRankNodeMap:
            pageRankNodeMap[i] = []

        x = Decimal(pageRankMap[i]).quantize(Decimal('0.000000001'))
        pageRankNodeMap[i].append(float(x))


degreeMap = nx.degree(random_bipartite_graph)

for el in corrupted_node:
Beispiel #40
0
class Topo(object):
    '''Data center network representation for structured multi-trees.'''

    def __init__(self):
        '''Create Topo object.

        '''
        self.g = Graph()
        self.node_info = {}  # dpids hash to Node objects
        self.edge_info = {}  # (src_dpid, dst_dpid) tuples hash to Edge objects
        self.ports = {}  # ports[src][dst] is port on src that connects to dst
        self.id_gen = NodeID  # class used to generate dpid

    def add_node(self, dpid, node):
        '''Add Node to graph.

        @param dpid dpid
        @param node Node object
        '''
        self.g.add_node(dpid)
        self.node_info[dpid] = node

    def add_edge(self, src, dst, edge = None):
        '''Add edge (Node, Node) to graph.

        @param src src dpid
        @param dst dst dpid
        @param edge Edge object
        '''
        src, dst = tuple(sorted([src, dst]))
        self.g.add_edge(src, dst)
        if not edge:
            edge = Edge()
        self.edge_info[(src, dst)] = edge
        self.add_port(src, dst)

    def add_port(self, src, dst):
        '''Generate port mapping for new edge.

        @param src source switch DPID
        @param dst destination switch DPID
        '''
        src_base = SWITCH_PORT_BASE if self.is_switch(src) else 0
        dst_base = SWITCH_PORT_BASE if self.is_switch(dst) else 0
        if src not in self.ports:
            self.ports[src] = {}
        if dst not in self.ports[src]:
            # num outlinks
            self.ports[src][dst] = len(self.ports[src]) + src_base
        if dst not in self.ports:
            self.ports[dst] = {}
        if src not in self.ports[dst]:
            # num outlinks
            self.ports[dst][src] = len(self.ports[dst]) + dst_base

    def node_enabled(self, dpid):
        '''Is node connected, admin on, powered on, and fault-free?

        @param dpid dpid

        @return bool node is enabled
        '''
        ni = self.node_info[dpid]
        return ni.connected and ni.admin_on and ni.power_on and not ni.fault

    def nodes_enabled(self, dpids, enabled = True):
        '''Return subset of enabled nodes

        @param dpids list of dpids
        @param enabled only return enabled nodes?

        @return dpids filtered list of dpids
        '''
        if enabled:
            return [n for n in dpids if self.node_enabled(n)]
        else:
            return dpids

    def nodes(self, enabled = True):
        '''Return graph nodes.

        @param enabled only return enabled nodes?

        @return dpids list of dpids
        '''
        return self.nodes_enabled(self.g.nodes(), enabled)

    def nodes_str(self, dpids):
        '''Return string of custom-encoded nodes.

        @param dpids list of dpids

        @return str string
        '''
        return [str(self.id_gen(dpid = dpid)) for dpid in dpids]

    def is_switch(self, n):
        '''Returns true if node is a switch.'''
        return self.node_info[n].is_switch

    def switches(self, enabled = True):
        '''Return switches.

        @param enabled only return enabled nodes?

        @return dpids list of dpids
        '''
        nodes = [n for n in self.g.nodes() if self.is_switch(n)]
        return self.nodes_enabled(nodes, enabled)

    def hosts(self, enabled = True):
        '''Return hosts.

        @param enabled only return enabled nodes?

        @return dpids list of dpids
        '''

        def is_host(n):
            '''Returns true if node is a host.'''
            return not self.node_info[n].is_switch

        nodes = [n for n in self.g.nodes() if is_host(n)]
        return self.nodes_enabled(nodes, enabled)

    def edge_enabled(self, edge):
        '''Is edge admin on, powered on, and fault-free?

        @param edge (src, dst) dpid tuple

        @return bool edge is enabled
        '''
        src, dst = edge
        src, dst = tuple(sorted([src, dst]))
        ei = self.edge_info[tuple(sorted([src, dst]))]
        return ei.admin_on and ei.power_on and not ei.fault

    def edges_enabled(self, edges, enabled = True):
        '''Return subset of enabled edges

        @param edges list of edges
        @param enabled only return enabled edges?

        @return edges filtered list of edges
        '''
        if enabled:
            return [e for e in edges if self.edge_enabled(e)]
        else:
            return edges

    def edges(self, enabled = True):
        '''Return edges.

        @param enabled only return enabled edges?

        @return edges list of dpid pairs
        '''
        return self.edges_enabled(self.g.edges(), enabled)

    def edges_str(self, dpid_pairs):
        '''Return string of custom-encoded node pairs.

        @param dpid_pairs list of dpid pairs (src, dst)

        @return str string
        '''
        edges = []
        for pair in dpid_pairs:
            src, dst = pair
            src = str(self.id_gen(dpid = src))
            dst = str(self.id_gen(dpid = dst))
            edges.append((src, dst))
        return edges

    def port(self, src, dst):
        '''Get port number.

        @param src source switch DPID
        @param dst destination switch DPID
        @return tuple (src_port, dst_port):
            src_port: port on source switch leading to the destination switch
            dst_port: port on destination switch leading to the source switch
        '''
        if src in self.ports and dst in self.ports[src]:
            assert dst in self.ports and src in self.ports[dst]
            return (self.ports[src][dst], self.ports[dst][src])

    def enable_edges(self):
        '''Enable all edges in the network graph.

        Set admin on, power on, and fault off.
        '''
        for e in self.g.edges():
            src, dst = e
            ei = self.edge_info[tuple(sorted([src, dst]))]
            ei.admin_on = True
            ei.power_on = True
            ei.fault = False

    def enable_nodes(self):
        '''Enable all nodes in the network graph.

        Set connected on, admin on, power on, and fault off.
        '''
        for node in self.g.nodes():
            ni = self.node_info[node]
            ni.connected = True
            ni.admin_on = True
            ni.power_on = True
            ni.fault = False

    def enable_all(self):
        '''Enable all nodes and edges in the network graph.'''
        self.enable_nodes()
        self.enable_edges()

    def name(self, dpid):
        '''Get string name of node ID.

        @param dpid DPID of host or switch
        @return name_str string name with no dashes
        '''
        return self.id_gen(dpid = dpid).name_str()

    def ip(self, dpid):
        '''Get IP dotted-decimal string of node ID.

        @param dpid DPID of host or switch
        @return ip_str
        '''
        return self.id_gen(dpid = dpid).ip_str()
Beispiel #41
0
def multigraph_to_graph(g: MultiGraph) -> Graph:
    gx = Graph()
    gt = Graph(g)
    gx.add_nodes_from(gt.nodes())
    gx.add_edges_from(gt.edges())
    return gx
class SocialNetwork(object):
    """Object oriented interface for conducting social network analysis."""
    valid_indexes = []
    for index_name in conf.INDEXES.keys():
            valid_indexes.append(index_name)
            
    cache = None
    
    def __init__(self):
        logging.info("libSNA object created.")
        self.graph = Graph()
        self.measures = {}
        self.nodesmeasures = {}
        self.edgesmeasures = {}
        for index in self.valid_indexes: self.measures[index] = None
        
    def getNodes(self):
        nodes = self.graph.nodes()
        nodes.sort()
        return nodes
        
    def getEdges(self):
        edges = self.graph.edges()
        return edges
        
    def loadGraph(self, nodes, edges):
        logging.info("Loading network from input variables")
        for node in nodes:
            self.graph.add_node(node)
        for edge in edges:
            self.graph.add_edge(edge[0], edge[1])
        self.graph.name = "Social Network"
        logging.info("Finished loading network.")

    def runMeasure(self, measure_name, backend):
        if measure_name in self.valid_indexes:
            eval('self.calculate_' + measure_name.replace(' ', '_') + '(backend)')
        else:
            logging.error("Unable to calculate the measure (%s)"%(measure_name))
            
    def returnResults(self, measure_name, value = 'value'):
        if measure_name in self.valid_indexes:
            if value == 'value': return self.measures[measure_name]
            elif value == 'nodes': return self.nodesmeasures[measure_name]
            elif value == 'edges': return self.edgesmeasures[measure_name]
        else:
            return None
            
    def displayResults(self, measure_name, value = 'value'):
        if measure_name in self.valid_indexes:
            if value == 'value': logging.info((conf.INDEX_TYPES[measure_name] + '.') % self.measures[measure_name])
            elif value == 'nodes': logging.info(str(self.nodesmeasures[measure_name] or '<null>'))
            elif value == 'edges': logging.info(str(self.edgesmeasures[measure_name] or '<null>'))
        else:
            logging.error("Unable to calculate the measure (%s)"%(measure_name))
            
    def calculateMeasures(self, backend=False):
        for measure_name in self.valid_indexes:
            self.runMeasure(measure_name, backend=False)
    
    def calculate_density(self, backend=False):        
        logging.info("Calculating density.")
        
        nodes = self.graph.nodes()
        edges = self.graph.edges()
        tot_edges = float(len(nodes) * (len(nodes)-1))
        tot_edges = tot_edges / 2
        num_edges = float(len(edges))
        
        w = {}
        for n1 in nodes:
            for n2 in nodes:
                w[n1,n2] = 0.0
        
        for n1,n2 in edges:
            w[n1,n2] = 1.0
            
        
        self.measures['density'] = num_edges / tot_edges * 100
        self.nodesmeasures['density'] = None
        self.edgesmeasures['density'] = w 
        
    def calculate_geodesic(self, backend=False):        
        logging.info("Calculating geodesic.")
        
        path = self.floyd_warshall(backend)
        nodes = self.graph.nodes()
        dividend = 0
        geodesic = float(0)
        geodesic_edges = {}
        
        for i in nodes:
            for j in nodes:
                try:
                    geodesic_edges[i,j] = path[i,j]
                    geodesic += path[i,j]
                    dividend += 1
                except KeyError:
                    pass
        
        geodesic /= dividend
        
        self.measures['geodesic'] = geodesic
        self.nodesmeasures['geodesic'] = None
        self.edgesmeasures['geodesic'] = geodesic_edges
        
    def calculate_fragmentation(self, backend=False):        
        logging.info("Calculating fragmentation.")
        
        nodes = self.graph.nodes()
        w = self.floyd_warshall(backend)
        fragmentation = float(0)
        
        for i in nodes:
            for j in nodes:
                try:
                    w[i,j]
                except KeyError:
                    fragmentation += 1
                    pass
        
        fragmentation /= len(nodes)*(len(nodes)-1)
        self.measures['fragmentation'] = fragmentation * 100
        self.nodesmeasures['fragmentation'] = None
        self.edgesmeasures['fragmentation'] = w
        
    def calculate_diameter(self, backend=False):        
        logging.info("Calculating diameter.")
        
        path = self.floyd_warshall(backend)
        nodes = self.graph.nodes()
        diameter = float(0)
        
        for i in nodes:
            for j in nodes:
                try:
                    diameter = max(diameter, path[i,j])
                except KeyError:
                    pass
    
        self.measures['diameter'] = diameter
        self.nodesmeasures['diameter'] = None
        self.edgesmeasures['diameter'] = path
        
    def calculate_degree(self, backend=False):
        logging.info("Calculating degree.")
        
        degrees = degree_centrality(self.graph)
        degree = float(sum(degrees.values())/len(degrees.values()))
        
        self.measures['degree'] = degree * 100
        self.nodesmeasures['degree'] = degrees
        self.edgesmeasures['degree'] = None
        
    def calculate_centralization(self, backend=False):
        logging.info("Calculating centralization.")
        
        degrees = degree_centrality(self.graph)
        centralization = float(0)
        maxdegree = max(degrees.values())
        for degree in degrees.values():
            centralization += maxdegree-degree
        centralization /= len(degrees.values())-1
        
        self.measures['centralization'] = centralization * 100
        self.nodesmeasures['centralization'] = degrees
        self.edgesmeasures['centralization'] = None
        
    def calculate_closeness(self, backend=False):        
        logging.info("Calculating closeness.")

        closenesses = closeness_centrality(self.graph)
        closeness = float(sum(closenesses.values())/len(closenesses.values()))
        
        self.measures['closeness'] = closeness * 100
        self.nodesmeasures['closeness'] = closenesses
        self.edgesmeasures['closeness'] = None
        
    def calculate_eigenvector(self, backend=False):        
        logging.info("Calculating eigenvector.")
        
        eigenvectors = eigenvector_centrality(self.graph)
        eigenvector = float(sum(eigenvectors.values())/len(eigenvectors.values()))
        
        self.measures['eigenvector'] = eigenvector * 100
        self.nodesmeasures['eigenvector'] = eigenvectors
        self.edgesmeasures['eigenvector'] = None
        
    def calculate_betweenness(self, backend=False):
        logging.info("Calculating betweenness.")
        
        betweennesses = betweenness_centrality(self.graph)
        betweenness = float(sum(betweennesses.values())/len(betweennesses.values()))
        
        self.measures['betweenness'] = betweenness * 100
        self.nodesmeasures['betweenness'] = betweennesses
        self.edgesmeasures['betweenness'] = None

    def calculate_cliques(self, backend=False):
        logging.info("Calculating cliques.")
        cliques = list(find_cliques(self.graph))
        
        w = {}
        nodes = self.graph.nodes()
        for node in nodes:
            w[node] = 0.0
            for clique in cliques:
                if node in clique:
                    w[node] += 1
        
        self.measures['cliques'] = len(cliques)
        self.nodesmeasures['cliques'] = w
        self.edgesmeasures['cliques'] = None
                
    def calculate_comembership(self, backend=False):
        logging.info("Calculating comembership.")
        
        nodes = self.graph.nodes()
        n = len(nodes)
        if not backend and n > 500:
            raise network_big.NetworkTooBigException(n)
        
        cliques = list(find_cliques(self.graph))
        
        w = {}
        for clique in cliques:
            for node1 in clique:
                for node2 in clique:
                    try:
                        w[node1,node2] += 1
                    except KeyError:
                        w[node1,node2] = 1
                        
        nodes = w.keys()
        comembership = float(0)
        for node1, node2 in nodes:
            if node1 != node2: comembership += w[node1,node2]
            
        num_nodes = len(self.graph.nodes())
        comembership /= num_nodes*(num_nodes-1)
        
        self.measures['comembership'] = comembership
        self.nodesmeasures['comembership'] = None
        self.edgesmeasures['comembership'] = w
        
    def calculate_components(self, backend=False):
        logging.info("Calculating components.")
        components = nx.connected_component_subgraphs(self.graph)
        
        w = {}
        nodes = self.graph.nodes()
        for node in nodes:
            w[node] = 0.0
        
        for component in components:
            if len(component) > 1:
                for node in component:
                    w[node] += 1
        
        self.measures['components'] = len(components)
        self.nodesmeasures['components'] = w
        self.edgesmeasures['components'] = None
    
    def floyd_warshall(self, backend):
        nodes = self.graph.nodes()
        
        if not backend and len(nodes) > 400:
            raise network_big.NetworkTooBigException(len(nodes))
        
        logging.info("Computing Floyd-Warshall.")
        
        infvalue = 127 #sys.maxint
        F = nx.floyd_warshall_numpy(self.graph, dtype=np.int8, infvalue=infvalue)
       
        w = {}
        for i in range(0, len(nodes)):
            for j in range(0, len(nodes)):
                if not F[i,j] == infvalue:
                    w[nodes[i],nodes[j]] = F[i,j]
        
        return w
Beispiel #43
0
class WishPool:
    def __init__( self,
                  wishes,
                  min_edge_score = MIN_EDGE_SCORE,
                  # min_number_of_edges = MIN_NUMBER_OF_EDGES,
                  connector = default_connector ):
        """
        A filterable pool of wishes represented as nodes. Is used to find
        relations between wishes.

        @param connector: default connector is jaccard
        @return:
        """

        self.graph                 = Graph()
        self.min_edge_weight       = min_edge_score
        # self.min_number_of_edges   = min_number_of_edges

        for wish in wishes:
            self.graph.add_node( wish )
            # loops through the existing nodes in the graph
            for other in self.graph.nodes_iter():
                # compares candidate to all existing nodes except itself
                if other != wish and other.person != wish.person:
                    score = connector( wish, other )
                    if score > self.min_edge_weight:
                        self.graph.add_edge( wish, other, weight=score )

        ## processes the graph, excludes lonely nodes
        self.connected_nodes = self.update_connected_nodes()
        debug_graph(self.graph, message="Connected nodes are set")
        self.lonely_nodes = self.update_lonely_nodes()
        self.update_cliques()

        ## evaluates alternatives, gathers suggestions for each wish
        # this implies that some cliques occur twice
        self.suggestions = self.update_suggestions()

    def update_connected_nodes( self ):
        connected = set()
        for n in self.graph.edges():
            connected.add( n[0] )
        return connected

    def update_lonely_nodes( self ):
        whole_graph = set( self.graph.nodes() )
        return whole_graph.difference( self.connected_nodes )

    def remove_lonely_nodes( self ):
        raise NotImplementedError

    def update_cliques( self ):
        result = set()
        for c in find_cliques( self.graph ):
            if len(c) > 1:
                result.add( Clique(c) )
        self.cliques = result
        return result

    def get_distributed_cliques( self ):
        self.cliques_for_wish = {}
        for n in self.graph.nodes():
            clique_buffer = []
            for c in self.cliques:
                if n in c.nodes:
                    clique_buffer.append( c )
            if len(clique_buffer):
                self.cliques_for_wish[n.pk] = [
                    c for c in clique_buffer if len(c.nodes) > 1 ]
        return self.cliques_for_wish

    def get_conflicting_cliques( self ):
        result = {}
        for w,c in self.get_distributed_cliques():
            if len(c) > 1:
                result[w] = c
        return result

    def update_suggestions( self ):
        suggestions = []
        for wish_pk, cliques in self.get_distributed_cliques().items():
            suggestion = Suggestion(
                Wish.objects.get(pk=wish_pk), cliques )
            suggestions.append( suggestion )
        self.suggestions = suggestions
        return suggestions

    def create_groups( self ):
        distinct_cliques = set()

        for s in self.suggestions:
            distinct_cliques.add( s.get_best_clique() )

        for c in distinct_cliques:
            c.create_group()

    def get_suggestion_pool( self ):
        return SuggestionPool( self.suggestions )
Beispiel #44
0
    def mergeAugmented(self, model, maxProb=0.05, maxMergedGeneCount=200, minGeneAutoMerge=5, minLevel=0):
        #get undirected graph
        undirected = self.to_undirected()

        #calculate descendant dictionary
        descendantDict = dict()
        sortedNodes = topological_sort(self)
        sortedNodes.reverse()
        for node in sortedNodes:
            descendants = descendantDict.get(node, set())
            descendants.add(node)
            descendantDict[node] = descendants

            for parent in self.predecessors(node):
                if parent not in descendantDict:
                    descendantDict[parent] = set(descendants)
                else:
                    descendantDict[parent].update(descendants)

        #calculate 5th percentile weight
        sort = list()
        for edge in self.edges(data=True):
            sort.append(edge[2]['weight'])
        sort.sort()
        fifth = sort[int(math.ceil(len(sort))*0.05-1)]

        genes = self.geneToNode.keys()

        geneTuples = set()
        for gene in genes:
            geneTuples.add((gene,''))
            geneTuples.add((gene,"NOT"))


        subTerms = set()
        test = Graph()
        length = 0

        copyGraph = self.createDiGraphCopy(geneTuples)

        queue = []
        leafs = set()
        for node in self.nodes():
            if len(self.edges(node)) == 0:
                leafs.add(node)
                for parent in self.predecessors(node):
                    heappush(queue, (self.edge[parent][node]['weight'], (parent, node)))
                    
        while len(queue) > 0:
            edge = heappop(queue)

            loss = copyGraph.node[edge[1][0]]['infoLoss'] + edge[0] + copyGraph.node[edge[1][1]]['infoLoss']
            mergedNodes = copyGraph.node[edge[1][0]]['mergeCount'] + 1 + copyGraph.node[edge[1][1]]['mergeCount']
            mergedGenes = len(copyGraph.node[edge[1][0]]['mergeGene'].union(copyGraph.node[edge[1][1]]['mergeGene']).union(copyGraph.node[edge[1][1]]['gene']).union(copyGraph.node[edge[1][0]]['gene']))
            genesCount = len(copyGraph.node[edge[1][1]]['mergeGene'].union(copyGraph.node[edge[1][1]]['gene']))

            if mergedGenes <= maxMergedGeneCount and self.getLevel(edge[1][0]) >= minLevel:
                subNodes = descendantDict[edge[1][0]]
                subGraph = undirected.subgraph(subNodes.intersection(self.nodes())).copy()

                subRootGeneTuples = copyGraph.node[edge[1][0]]['mergeGene'].union(copyGraph.node[edge[1][1]]['mergeGene']).union(copyGraph.node[edge[1][1]]['gene']).union(copyGraph.node[edge[1][0]]['gene']).intersection(geneTuples)
                subRootGenes = set()
                for geneGroup in list(subRootGeneTuples):
                    subRootGenes.add(geneGroup[0])

                subTerms = set()
                for gene in list(subRootGenes):
                    subTerms.update(self.getNodesByGene(gene))
                subTerms.intersection_update(subGraph.nodes())

                subGraph = self.augmentGraph(subGraph, list(subTerms), geneTuples, fifth)
                test = make_steiner_tree(subGraph, list(subTerms))
                length = 0
                for subEdge in test.edges():
                    length += test.edge[subEdge[0]][subEdge[1]]['weight']

                prob = calcProb(length, mergedGenes, model)
            else:
                prob = 1 + maxProb

            if prob < maxProb or genesCount <= minGeneAutoMerge:
                parent = edge[1][0]
                predecessors = copyGraph.predecessors(edge[1][1])
                copyGraph.node[edge[1][0]]['mergeGene'].update(copyGraph.node[edge[1][1]]['mergeGene'])
                copyGraph.node[edge[1][0]]['mergeGene'].update(copyGraph.node[edge[1][1]]['gene'])
                copyGraph.node[edge[1][0]]['mergePMID'].update(copyGraph.node[edge[1][1]]['mergeGene'])
                copyGraph.node[edge[1][0]]['mergePMID'].update(copyGraph.node[edge[1][1]]['pmid'])
                copyGraph.remove_edge(edge[1][0], edge[1][1])
                copyGraph.remove_node(edge[1][1])
                
                for pred in predecessors:
                    if len(copyGraph.edges(pred)) == 0:
                        copyGraph = self.delCopyGraphEmptyNode(copyGraph, pred)

                copyGraph.node[parent]['infoLoss'] = length
                copyGraph.node[parent]['mergeCount'] = mergedNodes

                queue = []
                leafs = set()
                for node in copyGraph.nodes():
                    if len(copyGraph.edges(node)) == 0:
                        leafs.add(node)
                        for parent in copyGraph.predecessors(node):
                            heappush(queue, (copyGraph.edge[parent][node]['weight'], (parent, node)))

        nodes = self.nodes()

        for node in nodes:
            if node not in copyGraph:
                self.remove_node(node)
            else:
                self.node[node]['data'].addMergedGenes(copyGraph.node[node]['mergeGene'])
                self.node[node]['data'].setInfoLoss(copyGraph.node[node]['infoLoss'])
                self.node[node]['data'].setMergedCount(copyGraph.node[node]['mergeCount'])
                self.node[node]['data'].setMergedPMIDs(copyGraph.node[node]['mergePMID'])
        return self, leafs, copyGraph
Beispiel #45
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 #46
0
    print('{0}/{1} nodes processed'.format(i, n))
    print('Delete {0} orphaned nodes'.format(len(orphaned)))
    graph.remove_nodes_from(orphaned)

    print('Calculate offset')
    points = [node[1]['pos'] for node in graph.nodes(data=True)]
    min_x = min(points, key=lambda p: p[0])[0]
    min_y = min(points, key=lambda p: p[1])[1]
    for node in graph.nodes_iter():
        pos = (graph.node[node]['pos'][0] - min_x, graph.node[node]['pos'][1] - min_y)
        graph.node[node]['pos'] = pos
    print('Translated data by ({0}, {1})'.format(-min_x, -min_y))

    print('Calculate edge weights')
    n = graph.number_of_edges()
    i = 0
    for edge in graph.edges():
        lat1 = math.radians(graph.node[edge[0]]['lat'])
        lon1 = math.radians(graph.node[edge[0]]['lon'])
        lat2 = math.radians(graph.node[edge[1]]['lat'])
        lon2 = math.radians(graph.node[edge[1]]['lon'])
        graph[edge[0]][edge[1]]['weight'] = distance(lat1, lon1, lat2, lon2)
        i += 1
        print('{0}/{1} edges processed'.format(i, n), end='\r')
    print('{0}/{1} edges processed'.format(i, n))

    print('Write {0}'.format(output_file))
    write_gpickle(graph, output_file)
    
    stop = timeit.default_timer()
    print('Program ran in {0} seconds'.format(stop - start))
Beispiel #47
0
class Topo(object):
    "Data center network representation for structured multi-trees."

    def __init__(self, hopts=None, sopts=None, lopts=None, ropts=None):
        """Topo object:
           hinfo: default host options
           sopts: default switch options
           lopts: default link options"""
        self.g = Graph()
        self.node_info = {}
        self.link_info = {}  # (src, dst) tuples hash to EdgeInfo objects
        self.hopts = {} if hopts is None else hopts
	self.ropts = {} if ropts is None else ropts
        self.sopts = {} if sopts is None else sopts
        self.lopts = {} if lopts is None else lopts
        self.ports = {}  # ports[src][dst] is port on src that connects to dst

    def addNode(self, name, **opts):
        """Add Node to graph.
           name: name
           opts: node options
           returns: node name"""
        self.g.add_node(name)
        self.node_info[name] = opts
        return name

    def addHost(self, name, **opts):
        """Convenience method: Add host to graph.
           name: host name
           opts: host options
           returns: host name"""

        if not opts:
            if self.hopts:
                opts = self.hopts
            elif self.ropts:
                opts = self.ropts

        return self.addNode(name, **opts)

    def addSwitch(self, name, **opts):
        """Convenience method: Add switch to graph.
           name: switch name
           opts: switch options
           returns: switch name"""
        if not opts and self.sopts:
            opts = self.sopts
        result = self.addNode(name, isSwitch=True, **opts)
        return result

    def addLink(self, node1, node2, port1=None, port2=None,
                **opts):
        """node1, node2: nodes to link together
           port1, port2: ports (optional)
           opts: link options (optional)
           returns: link info key"""
        if not opts and self.lopts:
            opts = self.lopts
        self.addPort(node1, node2, port1, port2)
        key = tuple(self.sorted([node1, node2]))
        self.link_info[key] = opts
        self.g.add_edge(*key)
        return key

    def addPort(self, src, dst, sport=None, dport=None):
        '''Generate port mapping for new edge.
        @param src source switch name
        @param dst destination switch name
        '''
        self.ports.setdefault(src, {})
        self.ports.setdefault(dst, {})
        # New port: number of outlinks + base
        src_base = 1 if self.isSwitch(src) else 0
        dst_base = 1 if self.isSwitch(dst) else 0
        if sport is None:
            sport = len(self.ports[src]) + src_base
        if dport is None:
            dport = len(self.ports[dst]) + dst_base
        self.ports[src][dst] = sport
        self.ports[dst][src] = dport

    def nodes(self, sort=True):
        "Return nodes in graph"
        if sort:
            return self.sorted( self.g.nodes() )
        else:
            return self.g.nodes()

    def isSwitch(self, n):
        '''Returns true if node is a switch.'''
        info = self.node_info[n]
        return info and info.get('isSwitch', False)

    def switches(self, sort=True):
        '''Return switches.
        sort: sort switches alphabetically
        @return dpids list of dpids
        '''
        return [n for n in self.nodes(sort) if self.isSwitch(n)]

    def hosts(self, sort=True):
        '''Return hosts.
        sort: sort hosts alphabetically
        @return dpids list of dpids
        '''
        return [n for n in self.nodes(sort) if not self.isSwitch(n)]

    def links(self, sort=True):
        '''Return links.
        sort: sort links alphabetically
        @return links list of name pairs
        '''
        if not sort:
            return self.g.edges()
        else:
            links = [tuple(self.sorted(e)) for e in self.g.edges()]
            return sorted( links, key=naturalSeq )

    def port(self, src, dst):
        '''Get port number.

        @param src source switch name
        @param dst destination switch name
        @return tuple (src_port, dst_port):
            src_port: port on source switch leading to the destination switch
            dst_port: port on destination switch leading to the source switch
        '''
        if src in self.ports and dst in self.ports[src]:
            assert dst in self.ports and src in self.ports[dst]
            return (self.ports[src][dst], self.ports[dst][src])

    def linkInfo( self, src, dst ):
        "Return link metadata"
        src, dst = self.sorted([src, dst])
        return self.link_info[(src, dst)]

    def setlinkInfo( self, src, dst, info ):
        "Set link metadata"
        src, dst = self.sorted([src, dst])
        self.link_info[(src, dst)] = info

    def nodeInfo( self, name ):
        "Return metadata (dict) for node"
        info = self.node_info[ name ]
        return info if info is not None else {}

    def setNodeInfo( self, name, info ):
        "Set metadata (dict) for node"
        self.node_info[ name ] = info

    @staticmethod
    def sorted( items ):
        "Items sorted in natural (i.e. alphabetical) order"
        return sorted(items, key=natural)
Beispiel #48
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()))