Exemplo n.º 1
0
def local_thresholding_dens(conn_matrix, thr):
    """
    Threshold the adjacency matrix by building from the minimum spanning tree (MST) and adding
    successive N-nearest neighbour degree graphs to achieve target density threshold.

    Parameters
    ----------
    conn_matrix : array
        Weighted NxN matrix.
    thr : float
        A density threshold, between 0 and 1, to achieve through local thresholding.

    Returns
    -------
    conn_matrix_thr : array
        Weighted, MST local-thresholded, NxN matrix.
    """
    from pynets import thresholding
    from pynets.stats import netstats

    fail_tol = 10
    conn_matrix = np.nan_to_num(conn_matrix)
    G = nx.from_numpy_matrix(conn_matrix)
    if not nx.is_connected(G):
        [G, _] = netstats.prune_disconnected(G)

    maximum_edges = G.number_of_edges()
    G = thresholding.weight_to_distance(G)
    min_t = nx.minimum_spanning_tree(G, weight="distance")
    mst_density = nx.density(min_t)
    G_density = nx.density(G)
    if mst_density > G_density:
        print("%s%s%s" % (
            'Warning: The minimum spanning tree already has: ', thr,
            ' density. Local Threshold will be applied by just retaining the Minimum Spanning Tree'
        ))
        conn_matrix_thr = nx.to_numpy_array(G)
        return conn_matrix_thr

    k = 1
    dense_list = []
    while mst_density < float(thr) and (len(dense_list[-fail_tol:]) - len(
            set(dense_list[-fail_tol:]))) < (fail_tol - 1):
        print(k)
        print(mst_density)
        dense_list.append(mst_density)
        # Create nearest neighbour graph
        nng = thresholding.knn(conn_matrix, k)
        number_before = nng.number_of_edges()
        # Remove edges from the NNG that exist already in the new graph/MST
        nng.remove_edges_from(min_t.edges())
        if nng.number_of_edges() == 0 and number_before >= maximum_edges:
            break

        # Add weights to NNG
        for e in nng.edges():
            nng.edges[e[0], e[1]]['weight'] = float(conn_matrix[e[0], e[1]])

        # Obtain list of edges from the NNG in order of weight
        edge_list = sorted(nng.edges(data=True),
                           key=lambda t: t[2]['weight'],
                           reverse=True)
        # Add edges in order of connectivity strength
        for edge in edge_list:
            min_t.add_edges_from([edge])
            mst_density = thresholding.est_density((nx.to_numpy_array(min_t)))
            # print("%s%s" % ('Adding edge to mst: ', edge))
            if mst_density >= G_density or mst_density >= float(thr):
                # print(mst_density)
                break

        if (len(dense_list[-fail_tol:]) -
                len(set(dense_list[-fail_tol:]))) >= (fail_tol - 1):
            print("%s%s%s" %
                  ('Cannot apply local thresholding to achieve density of: ',
                   thr,
                   '. Using maximally saturated connected matrix instead...'))

        k += 1

    conn_matrix_thr = nx.to_numpy_array(min_t,
                                        nodelist=sorted(min_t.nodes()),
                                        dtype=np.float64)
    if len(min_t.nodes()) < conn_matrix.shape[0]:
        raise RuntimeWarning(
            "%s%s%s" %
            ('Cannot apply local thresholding to achieve density of: ', thr,
             '. Try a higher -thr or -min_thr'))

    return conn_matrix_thr
Exemplo n.º 2
0
def local_thresholding_prop(conn_matrix, thr):
    """
    Threshold the adjacency matrix by building from the minimum spanning tree (MST) and adding
    successive N-nearest neighbour degree graphs to achieve target proportional threshold.

    Parameters
    ----------
    conn_matrix : array
        Weighted NxN matrix.
    thr : float
        A proportional threshold, between 0 and 1, to achieve through local thresholding.

    Returns
    -------
    conn_matrix_thr : array
        Weighted, MST local-thresholded, NxN matrix.
    """
    from pynets import thresholding
    from pynets.stats import netstats

    fail_tol = 10
    conn_matrix = np.nan_to_num(conn_matrix)
    G = nx.from_numpy_matrix(conn_matrix)
    if not nx.is_connected(G):
        [G, _] = netstats.prune_disconnected(G)

    maximum_edges = G.number_of_edges()
    G = thresholding.weight_to_distance(G)
    min_t = nx.minimum_spanning_tree(G, weight="distance")
    len_edges = min_t.number_of_edges()
    upper_values = np.triu_indices(np.shape(conn_matrix)[0], k=1)
    weights = np.array(conn_matrix[upper_values])
    weights = weights[~np.isnan(weights)]
    edgenum = int(float(thr) * float(len(weights)))
    if len_edges > edgenum:
        print("%s%s%s" % (
            'Warning: The minimum spanning tree already has: ', len_edges,
            ' edges, select more edges. Local Threshold will be applied by just retaining the Minimum '
            'Spanning Tree'))
        conn_matrix_thr = nx.to_numpy_array(G)
        return conn_matrix_thr

    k = 1
    len_edge_list = []
    while len_edges < edgenum and k <= np.shape(conn_matrix)[0] and (
            len(len_edge_list[-fail_tol:]) -
            len(set(len_edge_list[-fail_tol:]))) < (fail_tol - 1):
        print(k)
        print(len_edges)
        len_edge_list.append(len_edges)
        # Create nearest neighbour graph
        nng = thresholding.knn(conn_matrix, k)
        number_before = nng.number_of_edges()
        # Remove edges from the NNG that exist already in the new graph/MST
        nng.remove_edges_from(min_t.edges())
        if nng.number_of_edges() == 0 and number_before >= maximum_edges:
            break

        # Add weights to NNG
        for e in nng.edges():
            nng.edges[e[0], e[1]]['weight'] = float(conn_matrix[e[0], e[1]])

        # Obtain list of edges from the NNG in order of weight
        edge_list = sorted(nng.edges(data=True),
                           key=lambda t: t[2]['weight'],
                           reverse=True)
        # Add edges in order of connectivity strength
        for edge in edge_list:
            # print("%s%s" % ('Adding edge to mst: ', edge))
            min_t.add_edges_from([edge])
            min_t_mx = nx.to_numpy_array(min_t)
            len_edges = nx.from_numpy_matrix(min_t_mx).number_of_edges()
            if len_edges >= edgenum:
                # print(len_edges)
                break

        if (len(len_edge_list[-fail_tol:]) -
                len(set(len_edge_list[-fail_tol:]))) >= (fail_tol - 1):
            print("%s%s%s" %
                  ('Cannot apply local thresholding to achieve threshold of: ',
                   thr,
                   '. Using maximally saturated connected matrix instead...'))

        k += 1

    conn_matrix_thr = nx.to_numpy_array(min_t,
                                        nodelist=sorted(min_t.nodes()),
                                        dtype=np.float64)
    if len(min_t.nodes()) < conn_matrix.shape[0]:
        raise RuntimeWarning(
            "%s%s%s" %
            ('Cannot apply local thresholding to achieve threshold of: ', thr,
             '. Try a higher -thr or -min_thr'))

    return conn_matrix_thr