def get_degree_of_separation_visualisation(self, author1, author2):
        
        if author1 == '' or author2 == '':
            return Graph()
        
        if author1 == author2:
            return Graph()
        
        # Compute all the shortest paths from author1 to author2
        try:
            list_of_paths = all_shortest_paths(self.authors_graph, self.author_idx[author1], self.author_idx[author2])
        except NetworkXError as e:
            return "Not found"

        g = Graph()
        # Add the shortest paths to the graph
        try:
            for path in list_of_paths:
                g.add_path(path)
        except NetworkXNoPath as e:
            return Graph()

        # Add attributes to nodes
        for i in g.nodes():
            g.node[i]['name']=self.authors[i].name
        print g.nodes(data=True)
        return g
Beispiel #2
0
def find_communities(graph: networkx.Graph, logger=None) -> list:
    """

    :param graph: a Graph instance from networkx
    :type graph: networkx.Graph

    :param logger: optional logger. A default null one will be created if none is provided.
    :type logger: (None|logging.Logger)

    This function is a wrapper around the networkX methods to find
    cliques and communities inside a graph.
    The method takes as input a precomputed graph and returns
    two lists:
        - cliques
        - communities
    """
    if logger is None:
        logger = create_null_logger()

    logger.debug("Creating the communities for %s", logger.name)
    communities = [frozenset(comm) for comm in networkx.connected_components(graph)]

    logger.debug("Communities for %s:\n\t\t%s", logger.name, "\n\t\t".join(
        [str(_) for _ in communities]))
    # result = [frozenset(x) for x in communities.values()]
    for element in set.difference(set(graph.nodes()), set(chain(*communities[:]))):
        communities.append(frozenset([element]))
    return set(communities)
Beispiel #3
0
 def test_maximal_cliques(self):
     """Test maximal_cliques."""
     G = Graph()
     G.add_edge('b','c')
     G.add_edge('b','d')
     G.add_edge('b','e')
     G.add_edge('b','f')
     G.add_edge('b','a')
     G.add_edge('a','c')
     G.add_edge('a','d')
     G.add_edge('a','e')
     G.add_edge('c','d')
     G.add_edge('c','e')
     G.add_edge('c','f')
     G.add_edge('c','g')
     G.add_edge('d','e')
     G.add_edge('d','g')
     G.add_edge('e','g')
     G.add_edge('f','g')
     # A clique of 'a, b, c, d, e' and some other edges.
     nodes = G.nodes()
     S, H = pClique.convert_graph_connectivity_to_sparse(G, nodes)
     i = nodes.index('a')
     tQ = pClique.grasp(S, H, 1, 5, i)
     c = [nodes[i] for i in tQ]
     print c
     self.assertTrue(set(c) == set(['a', 'b', 'c', 'd', 'e']))
Beispiel #4
0
def polygon_skeleton(polygon, density=10):
    """ Given a buffer polygon, return a skeleton graph.
    """
    skeleton = Graph()
    points = []
    
    for ring in polygon_rings(polygon):
        points.extend(densify_line(list(ring.coords), density))
    
    if len(points) <= 4:
        # don't bother with this one
        return skeleton
    
    print >> stderr, ' ', len(points), 'perimeter points',
    
    rbox = '\n'.join( ['2', str(len(points))] + ['%.2f %.2f' % (x, y) for (x, y) in points] + [''] )
    
    qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE)
    output, error = qvoronoi.communicate(rbox)
    voronoi_lines = output.splitlines()
    
    if qvoronoi.returncode:
        raise _QHullFailure('Failed with code %s' % qvoronoi.returncode)
    
    vert_count, poly_count = map(int, voronoi_lines[1].split()[:2])
    
    for (index, line) in enumerate(voronoi_lines[2:2+vert_count]):
        point = Point(*map(float, line.split()[:2]))
        if point.within(polygon):
            skeleton.add_node(index, dict(point=point))
    
    for line in voronoi_lines[2+vert_count:2+vert_count+poly_count]:
        indexes = map(int, line.split()[1:])
        for (v, w) in zip(indexes, indexes[1:] + indexes[:1]):
            if v not in skeleton.node or w not in skeleton.node:
                continue
            v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point']
            line = LineString([(v1.x, v1.y), (v2.x, v2.y)])
            if line.within(polygon):
                skeleton.add_edge(v, w, dict(line=line, length=line.length))
    
    removing = True
    
    while removing:
        removing = False
    
        for index in skeleton.nodes():
            if skeleton.degree(index) == 1:
                depth = skeleton.node[index].get('depth', 0)
                if depth < 20:
                    other = skeleton.neighbors(index)[0]
                    skeleton.node[other]['depth'] = depth + skeleton.edge[index][other]['line'].length
                    skeleton.remove_node(index)
                    removing = True
    
    print >> stderr, 'contain', len(skeleton.edge), 'internal edges.'
    
    return skeleton
def make_colors(graph: nx.Graph) -> map:
    names = graph.nodes()
    longest = max(names)
    raw = [levenshtein_distance(x, longest) for x in names]
    largest_raw = max(raw)
    degrees = [graph.degree(x) for x in graph]
    largest_degrees = max(degrees)
    return map(lambda x, y: x + y,
               [int(10 * x/largest_degrees) for x in degrees],
               [10 * x/largest_raw for x in raw])
Beispiel #6
0
def polygon_dots_skeleton(polygon, points):
    '''
    '''
    skeleton = Graph()

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

    cliqueGraph = nx.Graph()

    with click.progressbar(graph.nodes(), label='building cliques') as bar:
        for n in bar:
            attr_dict = graph.node[n]
            if 'same_as' in attr_dict:
                for m in attr_dict['same_as']:
                    cliqueGraph.add_edge(n,
                                         m,
                                         provided_by=attr_dict['provided_by'])
                    for key, value in graph.node[n].items():
                        update(cliqueGraph.node[n], key, value)
                    update(cliqueGraph.node[n], 'is_node', True)

    return cliqueGraph
Beispiel #8
0
    def test_bad_input_vertex_position(self):
        graph = Graph()
        positions = [(1.0, 1.0), (1.5, 2.0), (1.0, 3.0), (2.0, 3.0),
                     (3.0, 3.0), (2.0, 2.0)]

        [e1, e12, e2, e23, e3,
         e31] = self.create_nodes(graph, 1, 'E', positions)
        self.create_edges_chain(graph, [e1, e12, e2, e23, e3, e31, e1])

        i = add_interior(graph, e1, e2, e3)

        with self.assertRaises(AssertionError):
            [i1, i3, i2a, i2b] = P5().apply(graph, [i])
        self.assertEqual(len(graph.nodes()), 7)
        self.assertEqual(len(graph.edges()), 9)

        if self.showPlots:
            pyplot.title("Wrong vertex position", fontsize=16)
            visualize_graph_3d(graph)
            pyplot.show()
Beispiel #9
0
def _node_coords(g: nx.Graph, l: dict) -> Tuple:
    """Converts coordinates for the graph nodes 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 accessed as keys of a dictionary
    """
    n_x = []
    n_y = []

    for n in g.nodes():
        n_x.append(l[n][0])
        n_y.append(l[n][1])

    return {"x": n_x, "y": n_y}
Beispiel #10
0
def quadratic_funding(G: nx.Graph, total_pot: float) -> dict:
    G = G.copy()
    grants = {
        label
        for label, node in G.nodes(data=True) if node["type"] == "grant"
    }
    M = nx.get_node_attributes(G, "match")

    total_match = sum(M.values())
    F = {}
    if total_match > total_pot:
        F = {g: total_pot * M[g] / total_match for g in grants}
    else:
        if total_match == 0:
            total_match = 1.0
        F = {
            g: M[g] + (1 + np.log(total_pot / total_match) / 100)
            for g in grants
        }
    return F
Beispiel #11
0
def _create_strtree(_graph: nx.Graph) -> strtree.STRtree:
    # create an STRtree
    points = []
    for n, n_d in _graph.nodes(data=True):
        # x coordinate
        if 'x' not in _graph.nodes[n]:
            raise KeyError(
                f'Encountered node missing "x" coordinate attribute at node {n}.'
            )
        x = _graph.nodes[n]['x']
        # y coordinate
        if 'y' not in _graph.nodes[n]:
            raise KeyError(
                f'Encountered node missing "y" coordinate attribute at node {n}.'
            )
        y = _graph.nodes[n]['y']
        p = geometry.Point(x, y)
        p.uid = n
        points.append(p)
    return strtree.STRtree(points)
def simulate_inoculation(net: Graph, patient_zero: str,
                         infection_probability: float, inoculator: str,
                         inoculation_probability: float):
    """Simulate worm and inoculation propagation through a given network,
       from two given nodes. Returns the number of rounds to either fully
       infect or fully cure the network."""
    infected = set(patient_zero)
    inoculated = set(inoculator)
    round_count = 0
    print('Infecting ' + str(len(net.nodes())) + ' nodes, starting from '
          + patient_zero + ', and inoculating from ' + inoculator + '.')
    while len(infected) > 0:
        currently_infected = len(infected)
        currently_inoculated = len(inoculated)
        new_infections = 0
        if currently_infected > 0:
            for node in net.neighbors(choice(tuple(infected))):
                if node not in infected and node not in inoculated:
                    if random() <= infection_probability:
                        infected.add(node)
                        new_infections += 1
        for node in net.neighbors(choice(tuple(inoculated))):
            if node not in inoculated:
                if random() <= inoculation_probability:
                    inoculated.add(node)
                    if node in infected:
                        infected.remove(node)
        for node in inoculated:
            if node in infected:
                infected.remove(node)
        round_count += 1
        infection_delta = str(len(infected) - currently_infected)
        inoculation_delta = str(len(inoculated) - currently_inoculated)
        if not (infection_delta == '0' and inoculation_delta == '0'):
            print('Round: ' + str(round_count) +
                  ', infection delta: ' + infection_delta +
                  ' (' + str(new_infections) + ' new infections)' +
                  ', inoculation delta: ' + inoculation_delta +
                  ', total infected: ' + str(len(infected)) +
                  ', total inoculated: ' + str(len(inoculated)))
    return round_count
Beispiel #13
0
def add_distance_threshold(
    G: nx.Graph, long_interaction_threshold: int, threshold: float = 5.0
):
    """
    Adds edges to any nodes within a given distance of each other. Long interaction threshold is used
    to specify minimum separation in sequence to add an edge between networkx nodes within the distance threshold

    :param G: Protein Structure graph to add distance edges to
    :type G: nx.Graph
    :param long_interaction_threshold: minimum distance in sequence for two nodes to be connected
    :type long_interaction_threshold: int
    :param threshold: Distance in angstroms, below which two nodes are connected
    :type threshold: float
    :return: Graph with distance-based edges added
    """
    pdb_df = filter_dataframe(
        G.graph["pdb_df"], "node_id", list(G.nodes()), True
    )
    dist_mat = compute_distmat(pdb_df)
    interacting_nodes = get_interacting_atoms(threshold, distmat=dist_mat)
    interacting_nodes = zip(interacting_nodes[0], interacting_nodes[1])

    log.info(f"Found: {len(list(interacting_nodes))} distance edges")
    for a1, a2 in interacting_nodes:
        n1 = G.graph["pdb_df"].loc[a1, "node_id"]
        n2 = G.graph["pdb_df"].loc[a2, "node_id"]
        n1_chain = G.graph["pdb_df"].loc[a1, "chain_id"]
        n2_chain = G.graph["pdb_df"].loc[a2, "chain_id"]
        n1_position = G.graph["pdb_df"].loc[a1, "residue_number"]
        n2_position = G.graph["pdb_df"].loc[a2, "residue_number"]

        condition_1 = n1_chain != n2_chain
        condition_2 = (
            abs(n1_position - n2_position) > long_interaction_threshold
        )

        if condition_1 or condition_2:
            if G.has_edge(n1, n2):
                G.edges[n1, n2]["kind"].add("distance_threshold")
            else:
                G.add_edge(n1, n2, kind={"distance_threshold"})
def convert_nx_to_rdkit(graph: nx.Graph) -> 'Chem.Mol':
    """Convert a networkx graph to a RDKit Molecule

    Args:
        graph (nx.Graph) Graph format of the molecule
    Returns:
        (Chem.RWMol): Molecule to be converted
    """
    mol = Chem.RWMol()

    # Special case: empty-graph
    if graph is None:
        return mol

    atomic_nums = nx.get_node_attributes(graph, 'atomic_num')
    chiral_tags = nx.get_node_attributes(graph, 'chiral_tag')
    formal_charges = nx.get_node_attributes(graph, 'formal_charge')
    node_is_aromatics = nx.get_node_attributes(graph, 'is_aromatic')
    node_hybridizations = nx.get_node_attributes(graph, 'hybridization')
    num_explicit_hss = nx.get_node_attributes(graph, 'num_explicit_hs')
    node_to_idx = {}
    for node in graph.nodes():
        a = Chem.Atom(atomic_nums[node])
        a.SetChiralTag(chiral_tags[node])
        a.SetFormalCharge(formal_charges[node])
        a.SetIsAromatic(node_is_aromatics[node])
        a.SetHybridization(node_hybridizations[node])
        a.SetNumExplicitHs(num_explicit_hss[node])
        idx = mol.AddAtom(a)
        node_to_idx[node] = idx

    bond_types = nx.get_edge_attributes(graph, 'bond_type')
    for edge in graph.edges():
        first, second = edge
        ifirst = node_to_idx[first]
        isecond = node_to_idx[second]
        bond_type = bond_types[first, second]
        mol.AddBond(ifirst, isecond, bond_type)

    Chem.SanitizeMol(mol)
    return mol
def quadratic_match(G: nx.Graph, threshold: float) -> dict:
    t1 = time()
    G = G.copy()
    raw_contributions = G.edges(data=True)

    grants_set = {
        n
        for n, attrs in G.nodes(data=True) if attrs["type"] == "grant"
    }

    contributions = []
    for contrib in raw_contributions:
        amount = contrib[2]["amount"]
        grant = contrib[1]
        if grant not in grants_set:
            grant = contrib[0]
            contributor = contrib[1]
        else:
            contributor = contrib[0]
        # {'grant': {match, user, grant, amount}}
        element = {grant: (None, contributor, grant, amount)}
        contributions.append(element)

    contrib_dict = aggregate_contributions(contributions)
    pt_t1 = time()
    pair_totals = get_totals_by_pair(contrib_dict)
    pt_t2 = time()
    matches = {
        proj: match_project(contribz, pair_totals, threshold)
        for proj, contribz in contrib_dict.items()
    }
    pt_t3 = time()
    pair_totals_time = pt_t2 - pt_t1
    match_vector_time = pt_t3 - pt_t2
    t2 = time()
    total_time = t2 - t1
    return {
        'total_time': total_time,
        'pair_totals_time': pair_totals_time,
        'match_vector_time': match_vector_time
    }
Beispiel #16
0
def extract_subgraph_from_chains(
    g: nx.Graph,
    chains: 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 chain.

    :param g: The graph to extract the subgraph from.
    :type g: nx.Graph
    :param chain: The chain(s) to extract.
    :type chain: List[str]
    :param filter_dataframe: Whether to filter the pdb_df dataframe of the graph. Defaults to True.
    :type filter_dataframe: bool
    :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
    :return: The subgraph or node list if return_node_list is True.
    :rtype: Union[nx.Graph, List[str]]
    """
    node_list: List = [
        n for n, d in g.nodes(data=True) if d["chain_id"] in chains
    ]

    node_list = list(set(node_list))
    log.debug(f"Found {len(node_list)} nodes in the chain subgraph.")
    return extract_subgraph_from_node_list(
        g,
        node_list,
        filter_dataframe=filter_dataframe,
        update_coords=update_coords,
        recompute_distmat=recompute_distmat,
        inverse=inverse,
        return_node_list=return_node_list,
    )
Beispiel #17
0
def add_sidechain_vector(g: nx.Graph,
                         scale: bool = True,
                         reverse: bool = False):
    """Adds vector from node to average position of sidechain atoms.

    We compute the mean of the sidechain atoms for each node. For this we use the ``rgroup_df`` dataframe.
    If the graph does not contain the ``rgroup_df`` dataframe, we compute it from the ``raw_pdb_df``.
    If scale, we scale the vector to the unit vector. If reverse is True,
    we reverse the vector (``sidechain - node``). If reverse is false (default) we compute (``node - sidechain``).

    :param g: Graph to add vector to.
    :type g: nx.Graph
    :param scale: Scale vector to unit vector. Defaults to ``True``.
    :type scale: bool
    :param reverse: Reverse vector. Defaults to ``False``.
    :type reverse: bool
    """
    # Get or compute R-Group DF
    if "rgroup_df" not in g.graph.keys():
        g.graph["rgroup_df"] = compute_rgroup_dataframe(g.graph["raw_pdb_df"])

    sc_centroid = g.graph["rgroup_df"].groupby("node_id").mean()

    # Iterate over nodes and compute vector
    for n, d in g.nodes(data=True):
        if d["residue_name"] == "GLY":
            # If GLY, set vector to 0
            vec = np.array([0, 0, 0])
        else:
            if reverse:
                vec = d["coords"] - np.array(
                    sc_centroid.loc[n][["x_coord", "y_coord", "z_coord"]])
            else:
                vec = (np.array(
                    sc_centroid.loc[n][["x_coord", "y_coord", "z_coord"]]) -
                       d["coords"])

            if scale:
                vec = vec / np.linalg.norm(vec)

        d["sidechain_vector"] = vec
Beispiel #18
0
def atoms_neighborhoods_charges(
        graph: nx.Graph, nauty: Nauty, shell: int,
        atom_type_key: str) -> Generator[Tuple[Atom, str, float], None, None]:
    """Yields neighborhood hash and partial charge for each atom.

    Args:
        nauty: The Nauty instance to use to canonize the neighborhoods.
        shell: The shell size to use to make the neighborhood
        atom_type_key: The name of the atom type attribute to use

    Yields:
        Tuples containing an atom, the neighborhood hash, and the \
                partial charge of the atom.
    """
    for atom in graph.nodes():
        if 'partial_charge' not in graph.node[atom]:
            raise KeyError(
                'Missing property "partial_charge" for atom {}'.format(atom))
        partial_charge = graph.node[atom]['partial_charge']
        key = nauty.canonize_neighborhood(graph, atom, shell, atom_type_key)
        yield atom, key, partial_charge
Beispiel #19
0
    def __init__(self, graph: Graph, start: int = 1):
        super().__init__()
        self.start: int = start
        self.nodes: List[int] = [self.start]
        self.cost: float = 0
        self.tau_0: float = 0

        n = len(graph)
        current = self.start

        unvisited = [x for x in graph.nodes() if x != self.start]
        while unvisited:
            costs = [graph.edges[current, x]['weight'] for x in unvisited]
            index = np.argmin(costs)
            self.cost += np.min(costs)
            current = unvisited[index]
            del unvisited[index]
        self.cost += graph.edges[current, self.start]['weight']
        self.tau_0 = 1 / (n * self.cost)
        for u, v in graph.edges:
            graph.edges[u, v].setdefault('pheromone', self.tau_0)
Beispiel #20
0
def rotate_right_to_right(graph: nx.Graph) -> None:
    """Rotate the graph so that the partisan_retweet:right nodes are to the right.
    
    Assign the rotated positions to the graph nodes.
    """
    partisan = nx.get_node_attributes(graph, 'partisan_retweet')
    right_nodes = list(filter(lambda n: partisan[n] == 'right', graph.nodes()))

    positions = nx.get_node_attributes(graph, 'position')

    best_rotation = 0
    max_sum_x = 0
    for rotation in range(0, 350, 10):
        rotated_positions = {n: rotate(x=positions[n][0], y=positions[n][1], d=rotation) for n in right_nodes}
        sum_x = sum([p[0] for p in rotated_positions.values()])
        if sum_x > max_sum_x:
            max_sum_x = sum_x
            best_rotation = rotation

    for n in graph.nodes:
        graph.nodes[n]['position'] = rotate(x=positions[n][0], y=positions[n][1], d=best_rotation)
Beispiel #21
0
def plot_original(G: nx.Graph, out_name) -> None:
    pos_dot = nx.nx_agraph.graphviz_layout(G, prog="dot")
    pos_twopi = nx.nx_agraph.graphviz_layout(G, prog="twopi")
    color_map = []
    for node in G.nodes(data=True):
        if node[1]['type'] == 'T':
            color_map.append('red')
        if node[1]['type'] == 'M':
            color_map.append('orange')
        if node[1]['type'] == 'CP':
            color_map.append('yellow')
        if node[1]['type'] == 'C':
            color_map.append('purple')
    plt.figure(3, figsize=(12, 12))
    nx.draw(G, pos=pos_dot, node_size=150, node_color=color_map, width=0.5)
    plt.savefig(out_name + "_dot.pdf", format="pdf")
    plt.close()
    plt.figure(3, figsize=(12, 12))
    nx.draw(G, pos=pos_twopi, node_size=150, node_color=color_map, width=0.5)
    plt.savefig(out_name + "_twopi.pdf", format="pdf")
    plt.close()
Beispiel #22
0
def get_unconnected_pairs(G: nx.Graph):
    # TODO: convert to sparse matrix
    node_list = list(G.nodes())
    adj_G = nx.adj_matrix(G)

    # get unconnected node-pairs
    all_unconnected_pairs = []

    # traverse adjacency matrix. find all unconnected node with maximum 2nd order
    offset = 0
    for i in tqdm(range(adj_G.shape[0])):
        for j in range(offset, adj_G.shape[1]):
            if i != j:
                if nx.shortest_path_length(G, i, j) <= 2:
                    if adj_G[i, j] == 0:
                        all_unconnected_pairs.append(
                            [node_list[i], node_list[j]])

        offset = offset + 1

    return all_unconnected_pairs
def draw_available_subgraph(G: nx.Graph, s: int, t: int, remove_rest: bool = False, pos=None):
    """
    Draw available subgraph of G for path from s to t.
    :param G: graph
    :param s: source node
    :param t: target node
    :param remove_rest: if True draw whole G graph with marked subgraph, otherwise draw only subgraph
    :param pos: nodes position
    :return:
    """
    if pos is None:
        pos = nx.spring_layout(G)
    H = available_subgraph(G, s, t)
    if remove_rest:
        draw_weighted_graph(H, pos)
    else:
        nodes_colors = ['red' if H.has_node(v) else 'green' for v in G.nodes()]
        edges_color = ['red' if H.has_edge(e[0], e[1]) else 'black' for e in G.edges()]
        nx.draw(G, pos=pos, with_labels=True, edge_color=edges_color, node_color=nodes_colors)
        nx.draw_networkx_edge_labels(G, pos=pos, edge_labels=nx.get_edge_attributes(G, 'throughput'))
    return pos
Beispiel #24
0
def adjust_dfs_to_graph(
    df_train: pd.DataFrame,
    df_val: pd.DataFrame,
    df_test: pd.DataFrame,
    G: nx.Graph,
    column_to_predict: str,
) -> T.Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:

    # We remove the users' rows who didn't rate `item_to_predict`
    df_train_adjusted = df_train.dropna(subset=[column_to_predict],
                                        axis="rows")
    df_val_adjusted = df_val.dropna(subset=[column_to_predict], axis="rows")
    df_test_adjusted = df_test.dropna(subset=[column_to_predict], axis="rows")

    # We remove those beers which were left out of the graph G
    beers_in_G = list(G.nodes())
    df_train_adjusted = df_train_adjusted[beers_in_G]
    df_val_adjusted = df_val_adjusted[beers_in_G]
    df_test_adjusted = df_test_adjusted[beers_in_G]

    return (df_train_adjusted, df_val_adjusted, df_test_adjusted)
Beispiel #25
0
def persona_graph(
    G: nx.Graph,
    clustering: Callable[
        [nx.Graph], Iterable[Sequence[Hashable]]] = nx.connected_components,
) -> nx.Graph:
    """
    Construct the persona graph of a graph G, this preserves any edge attributes.

    :param G: input graph
    :param clustering: algorithm to cluster node on a graph, a callable taking a graph to an iterable of hashable
    sequences
    :return: persona graph
    """
    # TODO preserve node data
    edge_remap = {}
    for n in G.nodes():
        _, persona_remap = create_personas(G, n, clustering)
        edge_remap[n] = persona_remap
    persona_graph_edges = [(edge_remap[start][end], edge_remap[end][start],
                            data) for start, end, data in G.edges(data=True)]
    return nx.from_edgelist(persona_graph_edges)
Beispiel #26
0
def nx_to_gdf(g: nx.Graph, nodes: bool = True, edges: bool = True) -> \
        Union[gpd.GeoDataFrame, Tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]]:
    """
    Converts a networkx Graph to a GeoDataFrame.

    :param nx.Graph g: networkx Graph.
    :param bool nodes: return a Point GeoDataFrame, derived from the network Graph nodes, default True.
    :param bool edges: return a LineString GeoDataFrame, derived from the network Graph edges, default True.
    :return Union[gpd.GeoDataFrame, Tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]]: a Point GeoDataFrame and / or LineString
        GeoDataFrame, derived from the networkx Graph nodes and / or edges, respectively.
    """

    logger.info("Loading NetworkX graph into GeoPandas GeoDataFrame.")

    # Generate GeoDataFrames for both networkx nodes and edges.
    gdf_nodes, gdf_edges = None, None

    # Compile node geometry and attributes.
    if nodes:
        node_xy, node_data = zip(*g.nodes(data=True))
        gdf_nodes = gpd.GeoDataFrame(
            list(node_data), geometry=[Point(i, j) for i, j in node_xy])
        gdf_nodes.crs = g.graph['crs']

    # Compile edge geometry and attributes.
    if edges:
        starts, ends, edge_data = zip(*g.edges(data=True))
        gdf_edges = gpd.GeoDataFrame(list(edge_data))
        gdf_edges.crs = g.graph['crs']

    logger.info(
        "Successfully loaded GeoPandas GeoDataFrame into NetworkX graph.")

    # Conditionally return nodes and / or edges.
    if all([nodes, edges]):
        return gdf_nodes, gdf_edges
    elif nodes is True:
        return gdf_nodes
    else:
        return gdf_edges
Beispiel #27
0
def qubo_circuit(graph: nx.Graph, steps: int, beta: Sequence,
                 gamma: Sequence) -> Circuit:
    """
    A QAOA circuit for the Quadratic Unconstrained Binary Optimization
    problem (i.e. an Ising model).

    Args:
        graph : a networkx graph instance with optional edge and node weights
        steps : number of QAOA steps
        beta  : driver parameters (One per step)
        gamma : cost parameters (One per step)

    """

    qubits = list(graph.nodes())

    # Initialization
    circ = Circuit()
    for q0 in qubits:
        circ += H(q0)

    # Run for given number of QAOA steps
    for p in range(0, steps):

        # Cost
        for q0, q1 in graph.edges():
            weight = graph[q0][q1].get('weight', 1.0)
            # Note factor of pi due to parameterization of ZZ gate
            circ += ZZ(-weight * gamma[p] / np.pi, q0, q1)

        for q0 in qubits:
            node_weight = graph.nodes[q0].get('weight', None)
            if node_weight is not None:
                circ += RZ(node_weight, q0)

        # Drive
        for q0 in qubits:
            circ += RX(beta[p], q0)

    return circ
Beispiel #28
0
def to_dataframe(G: nx.Graph,
                 properties = tuple()):

    # Error check
    valid_properties = ('betweenness',
                        'eigenvector centrality',
                        'degree',
                        'in-degree',
                        'out-degree')

    for property in properties:
        if property not in valid_properties:
            raise Exception('Invalid property: "' + property + '"')

    # ---
    data_frame = pd.DataFrame.from_dict(dict(G.nodes(data=True)),
                                        orient='index')

    for property in properties:
        if property == 'betweenness':
            data_frame[property] = \
                w.graph.betweenness(G)

        if property == 'degree':
            data_frame[property] = \
                w.graph.degrees(G)

        if property == 'eigenvector centrality':
            data_frame[property] = \
                w.graph.eigenvector_centrality(G)

        elif property == 'in-degree':
                data_frame[property] = \
                    w.graph.degrees(G, direction='in')

        elif property == 'out-degree':
            data_frame[property] = \
                w.graph.degrees(G, direction='out')

    return data_frame
Beispiel #29
0
def add_beta_carbon_vector(g: nx.Graph,
                           scale: bool = True,
                           reverse: bool = False):
    """Adds vector from node (typically alpha carbon) to position of beta carbon.

    Glycine does not have a beta carbon, so we set it to ``np.array([0, 0, 0])``.
    We extract the position of the beta carbon from the unprocessed atomic PDB dataframe.
    For this we use the ``raw_pdb_df`` dataframe.
    If scale, we scale the vector to the unit vector. If reverse is True,
    we reverse the vector (``C beta - node``). If reverse is false (default) we compute (``node - C beta``).

    :param g: Graph to add vector to.
    :type g: nx.Graph
    :param scale: Scale vector to unit vector. Defaults to ``True``.
    :type scale: bool
    :param reverse: Reverse vector. Defaults to ``False``.
    :type reverse: bool
    """

    c_beta_coords = filter_dataframe(g.graph["raw_pdb_df"],
                                     "atom_name", ["CB"],
                                     boolean=True)
    c_beta_coords.index = c_beta_coords["node_id"]

    # Iterate over nodes and compute vector
    for n, d in g.nodes(data=True):
        if d["residue_name"] == "GLY":
            vec = np.array([0, 0, 0])
        else:
            if reverse:
                vec = d["coords"] - np.array(
                    c_beta_coords.loc[n][["x_coord", "y_coord", "z_coord"]])
            else:
                vec = (np.array(
                    c_beta_coords.loc[n][["x_coord", "y_coord", "z_coord"]]) -
                       d["coords"])

            if scale:
                vec = vec / np.linalg.norm(vec)
        d["c_beta_vector"] = vec
Beispiel #30
0
    def _make_nodes(self, source_graph: nx.Graph) -> None:

        logger.info("Grouping Nodes by type")

        # Group nodes by class
        sorted_nodes = sorted(
            [node["data"] for _, node in source_graph.nodes(data=True)],
            key=lambda node: node.__name__,
            reverse=True,
        )

        nodes_by_type = itertools.groupby(sorted_nodes,
                                          key=lambda node: node.__name__)

        for node_type, nodes in nodes_by_type:

            # remove whitespaces
            node_type = node_type.replace(" ", "_")

            self._create_constraint(node_type)

            cypher_nodes = list(map(self._node_as_cypher, nodes))

            logger.debug(
                f"Inserting {len(cypher_nodes)} {node_type} nodes into Neo4J")

            for i in range(0, len(cypher_nodes), self.batch_size):

                start = i
                end = i + self.batch_size

                cypher = f"UNWIND [{', '.join(cypher_nodes[start: end])}] as row\n"

                cypher += f"CREATE (node:{node_type} {{_key: row._key}}) SET node = row"

                with self.neo4j.session() as session:
                    session.write_transaction(lambda tx: tx.run(cypher))

                logger.debug(f"Finished batch {i+1} ({start} -> {end})")
Beispiel #31
0
    def add_graph(self, graph: nx.Graph) -> None:
        """Draws nodes and edges from graph onto the given canvas

        :param graph: graph whose nodes and edges will be drawn
        :return: None
        """
        for node in graph.nodes():
            x = graph.nodes[node]['x']
            y = graph.nodes[node]['y']
            r = graph.nodes[node]['r']

            degree = min(graph.degree(node), len(COLORS) - 1)

            # always draw degree 0, as it is not visible in 'edge only' mode
            if not self.draw_nodes and degree > 0:
                continue

            cid = graph.nodes[node].get('cluster', 0)  # 0 means no cluster assigned
            ctag = 'c{}'.format(cid)
            ntag = 'n{}'.format(node)

            tags = ('Node', ntag,)
            if cid != 0:
                tags += (ctag, )

            draw_id = self.canvas.create_oval(x - r, y - r, x + r, y + r, outline=COLORS[degree], width=2,
                                              activefill='turquoise1',
                                              tags=tags)
            self.canvas.tag_bind(draw_id, '<ButtonPress-1>', lambda event, cid=cid: self.highlight(cid))

        dash = (4, 1) if self.draw_nodes else None

        for n1, n2 in graph.edges:
            n1_x = graph.nodes[n1]['x']
            n1_y = graph.nodes[n1]['y']
            n2_x = graph.nodes[n2]['x']
            n2_y = graph.nodes[n2]['y']

            self.canvas.create_line(n1_x, n1_y, n2_x, n2_y, dash=dash)
Beispiel #32
0
def hits_in_blob(track_graph: Graph, radius: float,
                 extreme: Voxel) -> Sequence[BHit]:
    """Returns the hits that belong to a blob."""
    distances = shortest_paths(track_graph)
    dist_from_extreme = distances[extreme]
    blob_pos = blob_centre(extreme)
    diag = np.linalg.norm(extreme.size)

    blob_hits = []
    # First, consider only voxels at a certain distance from the end-point, along the track.
    # We allow for 1 extra contiguity, because this distance is calculated between
    # the centres of the voxels, and not the hits. In the second step we will refine the
    # selection, using the euclidean distance between the blob position and the hits.
    for v in track_graph.nodes():
        voxel_distance = dist_from_extreme[v]
        if voxel_distance < radius + diag:
            for h in v.hits:
                hit_distance = np.linalg.norm(blob_pos - h.pos)
                if hit_distance < radius:
                    blob_hits.append(h)

    return blob_hits
Beispiel #33
0
def subset_by_node_feature_value(
    G: nx.Graph, feature_name: str, feature_value: Any
) -> nx.Graph:
    """
    Extracts a subgraph from a protein structure graph based on nodes with a certain feature value

    :param G: nx.Graph protein structure graph to extract a subgraph from
    :type G: nx.Graph
    :param feature_name: Name of feature to base subgraph extraction from
    :type feature_name: str
    :param feature_value: Value of feature to select
    :type feature_value: Any
    :return: Subgraph of G based on nodes with a given feature value
    :rtype: nx.Graph
    """
    node_list = []
    for n, d in G.nodes(data=True):

        if d[feature_name] == feature_value:
            node_list.append(n)

    return G.subgraph(node_list)
Beispiel #34
0
def make_random_walks(G: nx.Graph, num_walk, length_of_walk) -> List[List[str]]:
    # ランダムウォークで歩いたノードを入れるlistを生成
    paths = list()
    # ランダムウォークを擬似的に行う
    for i in range(num_walk):
        node_list = list(G.nodes())
        for node in node_list:
            now_node = node
            # 到達したノードを追加する用のリストを用意する
            path = list()
            path.append(str(now_node))
            for j in range(length_of_walk):
                # 次に到達するノードを選択する
                next_node = random.choice(list(G.neighbors(now_node)))
                # リストに到達したノードをリストに追加する
                path.append(str(next_node))
                # 今いるノードを「現在地」とする
                now_node = next_node
            # ランダムウォークしたノードをリストに追加
            paths.append(path)
        # 訪れたノード群を返す
        return paths
Beispiel #35
0
def analyze_graph(graph: nx.Graph):
    """check the graph we have built is well-formed:
    ideally you have 4 corners, not less,
    edges count is a multiple of 4,
    and insiders count is the square of edges_count/4.
    (If not, good luck to you, I cannot help.)
    """
    print(f"{len(graph)} tiles total")
    counts = {i: 0 for i in range(2, 5)}
    for n in graph.nodes():
        neighbors_count = len(list(nx.neighbors(graph, n)))
        counts[neighbors_count] += 1
    corners = counts[2]
    edges = counts[3]
    insiders = counts[4]
    print(f"-> {corners} corners")
    print(f"-> {edges} edges")
    print(f"-> {insiders} insiders")
    if corners != 4 or edges % 4 > 0 or (edges / 4) ** 2 != insiders:
        print(f"{u.RED}Your graph is pourri!{u.NORMAL}")
    else:
        print(f"{u.GREEN}Your graph is OK!{u.NORMAL}")
def _compute_ricci_curvature(G: nx.Graph, weight="weight", **kwargs):
    """Compute Ricci curvature of edges and nodes.
    The node Ricci curvature is defined as the average of node's adjacency edges.

    Parameters
    ----------
    G : NetworkX graph
        A given directional or undirectional NetworkX graph.
    weight : str
        The edge weight used to compute Ricci curvature. (Default value = "weight")
    **kwargs
        Additional keyword arguments passed to `_compute_ricci_curvature_edges`.

    Returns
    -------
    G: NetworkX graph
        A NetworkX graph with "ricciCurvature" on nodes and edges.
    """

    # compute Ricci curvature for all edges
    edge_ricci = _compute_ricci_curvature_edges(G, weight=weight, **kwargs)

    # Assign edge Ricci curvature from result to graph G
    nx.set_edge_attributes(G, edge_ricci, "ricciCurvature")

    # Compute node Ricci curvature
    for n in G.nodes():
        rc_sum = 0  # sum of the neighbor Ricci curvature
        if G.degree(n) != 0:
            for nbr in G.neighbors(n):
                if 'ricciCurvature' in G[n][nbr]:
                    rc_sum += G[n][nbr]['ricciCurvature']

            # Assign the node Ricci curvature to be the average of node's adjacency edges
            G.nodes[n]['ricciCurvature'] = rc_sum / G.degree(n)
            logger.debug("node %s, Ricci Curvature = %f" %
                         (n, G.nodes[n]['ricciCurvature']))

    return G
    def _get_fbvs(self, graph: Graph):
        # get the list of cycles
        cycles = cycle_basis(graph)

        # if the graph is already acyclic, there's nothing to remove, so return an empty set
        if len(cycles) == 0:
            return set()

        # get the set of nodes that is in at least one cycle
        nodes_in_cycles = set([item for sublist in cycles for item in sublist])

        min_num_to_remove = sys.maxsize
        min_nodes_to_remove = set()

        for node in nodes_in_cycles:
            # make an induced subgraph with the current node removed
            nodes = graph.nodes()
            nodes.remove(node)
            nodes_set = frozenset(nodes)

            if nodes_set in self.cacheDict:
                # if we have previously calculated the min fbvs for this induced subgraph, get that
                # fbvs from the cache dict
                nodes_to_remove = self.cacheDict[nodes_set]
            else:
                # otherwise we have to calculate it
                new_graph = graph.subgraph(nodes)
                nodes_to_remove = self._get_fbvs(new_graph)

                # add the newly calculated fbvs to the cache dict
                self.cacheDict[nodes_set] = nodes_to_remove

            if len(nodes_to_remove) < min_num_to_remove:
                min_num_to_remove = len(nodes_to_remove)
                nodes_to_remove.add(node)
                min_nodes_to_remove = nodes_to_remove

        return min_nodes_to_remove
class SimpleSectorNetworkCase(unittest.TestCase):

	def setUp(self):
		self.G = Graph()
		self.G.add_node(0, coord=(0., 0.))
		self.G.add_node(1, coord=(1., 0.))
		self.G.add_node(2, coord=(-0.5, np.sqrt(3.)/2.))
		self.G.add_node(3, coord=(0.5, np.sqrt(3.)/2.))
		self.G.add_node(4, coord=(1.5, np.sqrt(3.)/2.))
		self.G.add_node(5, coord=(0., np.sqrt(3.)))
		self.G.add_node(6, coord=(1., np.sqrt(3.)))

	def show_network(self, show=True):
		plt.scatter(*zip(*[self.G.node[n]['coord'] for n in self.G.nodes()]), marker='s', color='r', s=50)

		if show:
			plt.show()

	def show_polygons(self, show=True):
		for pol in self.G.polygons.values():
			plt.fill(*zip(*list(pol.exterior.coords)), alpha=0.4)

		if show:
			plt.show()
Beispiel #39
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)
# number_of_fake_nodes = 5
min_value_x = min(x)
max_value = max(y)
min_value = min(y)

count = 1

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] = []
Beispiel #41
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
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()
class HybridNetworkCase(unittest.TestCase):
	def setUp(self):
		#super(HybridNetworkCase, self).__init__()
		self.G = Graph()
		self.G.add_node(0, coord=(0., 0.))
		self.G.add_node(1, coord=(1., 0.))
		self.G.add_node(2, coord=(-0.5, np.sqrt(3.)/2.))
		self.G.add_node(3, coord=(0.5, np.sqrt(3.)/2.))
		self.G.add_node(4, coord=(1.5, np.sqrt(3.)/2.))
		self.G.add_node(5, coord=(0., np.sqrt(3.)))
		self.G.add_node(6, coord=(1., np.sqrt(3.)))

		self.G.G_nav = Graph()
		l = np.sqrt(3.)
		#pouet = []

		# Put six points inside the central sector
		center = np.array([0.5, l/2.])
		for i in range(6):
			angle = float(i)/6.*2.*np.pi
			point = center + 0.25*np.array([np.cos(angle), np.sin(angle)])
			#pouet.append(list(point))
			self.G.G_nav.add_node(i, coord=point)

		# Put two points in the 6 outer sectors
		for i in range(12):
			angle = 1./24.*(2.*np.pi) + float(i)/12.*(2.*np.pi)
			point = center + 1.25*np.array([np.cos(angle), np.sin(angle)])
			self.G.G_nav.add_node(6 + i, coord=point)

		self.G.G_nav.add_node(18, coord=center)

		self.G.airports = []
		self.G.G_nav.airports = []

		def get_airports(G):
			return G.airports

		self.G.get_airports = types.MethodType(get_airports, self.G)
		self.G.G_nav.get_airports = types.MethodType(get_airports, self.G.G_nav)

		self.G.G_nav.navpoints_borders = []

	def give_nodes_to_secs(self):
		self.G.node[3]['navs'] = list(range(6)) + [18]
		self.G.node[0]['navs'] = [13, 14]
		self.G.node[1]['navs'] = [15, 16]
		self.G.node[2]['navs'] = [11, 12]
		self.G.node[4]['navs'] = [6, 17]
		self.G.node[5]['navs'] = [9, 10]
		self.G.node[6]['navs'] = [7, 8]
		
		for i in range(6):
			self.G.G_nav.node[i]['sec'] = 3
		self.G.G_nav.node[18]['sec'] = 3
		self.G.G_nav.node[6]['sec'] = self.G.G_nav.node[17]['sec'] = 4
		self.G.G_nav.node[7]['sec'] = self.G.G_nav.node[8]['sec'] = 6
		self.G.G_nav.node[9]['sec'] = self.G.G_nav.node[10]['sec'] = 5
		self.G.G_nav.node[11]['sec'] = self.G.G_nav.node[12]['sec'] = 2
		self.G.G_nav.node[13]['sec'] = self.G.G_nav.node[14]['sec'] = 0
		self.G.G_nav.node[15]['sec'] = self.G.G_nav.node[16]['sec'] = 1

	def give_full_connections(self):
		for i in range(7):
			if i!=3:
				self.G.add_edge(3, i)

		periph_secs = [0, 1, 4, 6, 5, 2]
		for idx, n in enumerate(periph_secs):
			self.G.add_edge(n, periph_secs[(idx+1)%len(periph_secs)])

		for i in range(6):
			self.G.G_nav.add_edge(18, i)
			self.G.G_nav.add_edge(i, (i+1)%6)
			self.G.G_nav.add_edge(i, 2*i+6)
			coin = (2*i+5) if (2*i+5)!=5 else 17
			self.G.G_nav.add_edge(i, coin)

		for i in range(6, 18):
			coin = i+1 if i+1 != 18 else 6
		 	self.G.G_nav.add_edge(i, coin)

		# print "TEST: Creating the following edges:"
		# print self.G.G_nav.edges()

	def do_voronoi(self):
		self.G, vor = compute_voronoi(self.G, xlims=(-1., 2.), ylims=(-0.5, 2.5))
		self.G.polygons = {i:pol for i, pol in self.G.polygons.items() if type(pol)==type(Polygon())}
		self.G.global_shape = cascaded_union(self.G.polygons.values())

	def show_network(self, secs=True, navs=True, show=True):
		if secs:
			plt.scatter(*zip(*[self.G.node[n]['coord'] for n in self.G.nodes()]), marker='s', color='r', s=50)

		if navs:
			plt.scatter(*zip(*[self.G.G_nav.node[n]['coord'] for n in self.G.G_nav.nodes()]), marker='o')
	
		if show:
			plt.show()

	def show_polygons(self, show=True):
		for pol in self.G.polygons.values():
			plt.fill(*zip(*list(pol.exterior.coords)), alpha=0.4)

		if show:
			plt.show()
Beispiel #44
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 #45
0
class LangGraph(object):
	"""
	A graph of all the relationships in a document and/or sentence
	"""
	def __init__(self, directed=False):
		"""
		Builds a graph out of the given document
		"""
		self.isDirected = directed

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

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

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

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

		return result

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

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

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

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

		return results

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

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

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

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

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

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

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

		#add the new type
		types.add(type)

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

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

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

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

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

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

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

		return result

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

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

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

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

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

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

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

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

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

		return results

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

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

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

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

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

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

		return results

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

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

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

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

		self.removeNodes(toRemove)

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

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

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

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

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

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

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

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

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

		newGraph.setStart(newInst[self.start])

		return newGraph

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

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

	def __repr__(self):
		"""
		Returns a summary string of the graph
		"""
		return "LangGraph {} nodes, {} edges".format(len(self.graph.nodes()), len(self.graph.edges()))
Beispiel #46
0
def make_steiner_tree(G, voi, generator=None):
        mst = Graph()
        for v in voi:
                if not v in G:
                        raise ValueError, "make_steiner_tree(): Some vertice not in original graph"
        if len(voi) == 0:
                return mst
        if len(voi) == 1:
                mst.add_node(voi[0])
                return mst

        # Initially, use (a version of) Kruskal's algorithm to extract a minimal spanning tree
        # from a weighted graph.  This algorithm differs in that only a subset of vertices are
        # going to be present in the final subgraph (which is not truely a MST - must use Prim's
        # algorithm later.

        # extract all shortest paths among the voi
        heapq = []
        paths = {}

        # load all the paths bwteen the Steiner vertices. Store them in a heap queue
        # and reconstruct the MST of the complete graph using Kruskal's algorithm
        for i in range(len(voi) - 1):
                v1 = voi[i]
                for v2  in voi[i+1:]:
                        result = bidirectional_dijkstra(G, v1, v2)
                        if result == False:
                                raise RuntimeError, "The two vertices given (%s, %s) don't exist on the same connected graph" % (v1, v2)
                                #print "The two vertices given (%s, %s) don't exist on the same connected graph" % (v1, v2)
                        distance, vertList = result
                        keys = [v1, v2]
                        keys.sort()
                        key = "%s:%s" % tuple(keys)
                        paths[key] = (vertList)
                        heappush(heapq, (distance, v1, v2))

                                
        # construct the minimum spanning tree of the complete graph
        while heapq:
                w, v1, v2 = heappop(heapq)
                # if no path exists yet between v1 and v2, add this one
                if v1 not in mst or v2 not in mst or not has_path(mst, v1, v2):
                        mst.add_edge(v1, v2,weight=w)

        # check if the graph is tree and correct
        sTree = set(mst.nodes())
        sSteiner = set(voi)
        if sTree ^ sSteiner:
                raise RuntimeError, 'Failed to construct MST spanning tree'
        
        # reconstruct subgraph of origGraph using the paths
        if generator is None:
                subgraph  = Graph()
        else:
                subgraph = generator()
        for edge in mst.edges_iter(data=True):
                keys = [edge[0],edge[1]]
                keys.sort()
                key = "%s:%s" % tuple(keys)
                vList = paths[key]
                for i in range(len(vList) - 1):
                        v1 = vList[i]
                        v2 = vList[i+1]
                        w = G[v1][v2]
                        subgraph.add_edge(v1, v2, w)
        # get rid of possible loops - result will be a true MST
        subgraph = make_prim_mst(subgraph, generator)

        # remove intermediate nodes in paths that are not in list of voi
        return _trimTree(subgraph, voi)
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 #48
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 #49
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
    def run(self, manager):
        manager.logger.info("=" * 80)
        manager.logger.info("Assembling with Connected Components Assembly strategy")
        bg = manager.data["gos-asm"]["bg"]

        log_bg_stats(bg=bg, logger=manager.logger)
        target_multicolor = manager.data["gos-asm"]["target_multicolor"]
        assembly_cnt = 0
        ap_header_printed = False

        kbreaks = []
        for cc_cnt, cc in enumerate(bg.connected_components_subgraphs(copy=False)):
            possible_assemblies_graph = Graph()
            for vertex in (v for v in cc.nodes() if v.is_regular_vertex):
                if suitable_for_assembly_fragment_ends_vertex(graph=bg, reg_vertex=vertex, target_multicolor=target_multicolor):
                    possible_assemblies_graph.add_node(vertex)
            if len(list(possible_assemblies_graph.nodes())) > 1000:
                continue
            for v1, v2 in itertools.combinations(list(possible_assemblies_graph.nodes()), 2):
                if assembly_is_allowed(graph=bg, vertex1=v1, vertex2=v2, target_multicolor=target_multicolor, data=manager.data):
                    possible_assemblies_graph.add_edge(v1, v2)
            reg_vertices_for_assembly = set()
            for pag_cc in nx.connected_component_subgraphs(possible_assemblies_graph, copy=False):
                if len(list(pag_cc.nodes())) != 2:
                    continue
                reg_vertices_for_assembly.add(tuple(pag_cc.nodes()))

            for vertex_pair in reg_vertices_for_assembly:
                v1, v2 = vertex_pair
                if v1.block_name == v2.block_name:
                    continue
                for color in target_multicolor.colors:
                    iedge1 = get_irregular_edge_by_vertex_color(graph=bg, vertex=v1, color=color)
                    iedge2 = get_irregular_edge_by_vertex_color(graph=bg, vertex=v2, color=color)
                    s_edge = bg.get_condensed_edge(vertex1=v1, vertex2=v2) if bg.has_edge(vertex1=v1, vertex2=v2) else None
                    r1_name, r1_dir = get_repeat_info(iedge1)
                    r2_name, r2_dir = get_repeat_info(iedge2)
                    r1_entry = get_repeat_entry(repeat_name=r1_name, repeat_direction=r1_dir)
                    r2_entry = get_repeat_entry(repeat_name=r2_name, repeat_direction=r2_dir)
                    repeat_info = {
                        "repeat_name_1": r1_name,
                        "repeat_name_2": r2_name,
                        "repeat_dir_1": r1_dir,
                        "repeat_dir_2": r2_dir
                    }
                    try:
                        repeat_guidance = get_repeat_guidance(genome=color, repeat1_entry=r1_entry, repeat2_entry=r2_entry, data=manager.data)
                    except nx.networkx.exception.NetworkXNoPath:
                        raise Exception("Pair of edges must suitable for assembly with repeats guidance")
                    repeat_info["repeat_guidance"] = repeat_guidance
                    evolutionary_scenarios = {}
                    full_ie1_multicolor = get_full_irregular_multicolor(vertex=v1, data=manager.data, graph=bg)
                    full_ie2_multicolor = get_full_irregular_multicolor(vertex=v2, data=manager.data, graph=bg)
                    sedge_multicolor = s_edge.multicolor if s_edge is not None else Multicolor()
                    for e_scenario_name, e_scenario in non_conflicting_evolutionary_scenarios:
                        evolutionary_scenarios[e_scenario_name] = get_assembly_score(full_ie1_multicolor=full_ie1_multicolor,
                                                                                     full_ie2_multicolor=full_ie2_multicolor,
                                                                                     sedge_multicolor=sedge_multicolor,
                                                                                     target_multicolor=target_multicolor,
                                                                                     evolutionary_scenario=e_scenario, data=manager.data)

                    api = AssemblyPointInfo(support_edge=s_edge, iedge1=iedge1, iedge2=iedge2,
                                            evolutionary_scenarios=evolutionary_scenarios,
                                            allowed=True, repeat_info=repeat_info, target_multicolor=target_multicolor,
                                            target_color=Multicolor(color))
                    ap = AssemblyPoint(vertex1=v1, vertex2=v2, additional_information=api)
                    ap.cc_id = cc_cnt
                    if not ap_header_printed:
                        ap_header_printed = True
                        manager.logger.debug("-"*32 + "-"*len(AssemblyPoint.logger_file_header_string()))
                        manager.logger.debug(" "*32 + AssemblyPoint.logger_file_header_string())
                        manager.logger.debug("-"*32 + "-"*len(AssemblyPoint.logger_file_header_string()))
                    manager.logger.debug("Identified an assembly point :: {ap}".format(ap=ap.as_logger_entry()))
                    manager.data["gos-asm"]["assembly_points"].append(ap)
                    k_break = create_k_break_from_assembly_point(assembly_point=ap)
                    kbreaks.append(k_break)
        manager.logger.debug("-"*32 + "-"*len(AssemblyPoint.logger_file_header_string()))
        for k_break in kbreaks:
            bg.apply_kbreak(kbreak=k_break, merge=False)
            assembly_cnt += 1
        manager.logger.info("Identified and performed {gluing_cnt} assemblies with Connected Components Assembly strategy"
                            "".format(gluing_cnt=assembly_cnt))
        log_bg_stats(bg=bg, logger=manager.logger)
Beispiel #51
0
        elif isinstance(item, Node):
            pos = utm.from_latlon(item.lat, item.lon, force_zone_number=utm_zone_number)
            if not utm_zone_number:
                utm_zone_number = pos[2]
            graph.add_node(item.id, lat=item.lat, lon=item.lon, pos=pos[:2])
            #nodes += 1
        items += 1
        print('{0} items processed'.format(items), end='\r')

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

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

    print('Search for orphaned nodes')
    orphaned = set()
    n = graph.number_of_nodes()
    i = 0
    for node in graph.nodes_iter():
        if graph.degree(node) == 0:
            orphaned.add(node)
        i += 1