def test_weight_to_distance(x): G = nx.from_numpy_matrix(x) w = thresholding.weight_to_distance(G) assert isinstance(w, nx.Graph)
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 local-thresholding using MST, NxN matrix. References ---------- .. [1] Alexander-Bloch, A. F., Gogtay, N., Meunier, D., Birn, R., Clasen, L., Lalonde, F., … Bullmore, E. T. (2010). Disrupted modularity and local connectivity of brain functional networks in childhood-onset schizophrenia. Frontiers in Systems Neuroscience. https://doi.org/10.3389/fnsys.2010.00147 .. [2] Tewarie, P., van Dellen, E., Hillebrand, A., & Stam, C. J. (2015). The minimum spanning tree: An unbiased method for brain network analysis. NeuroImage. https://doi.org/10.1016/j.neuroimage.2014.10.015 """ from pynets.core import thresholding fail_tol = 100 conn_matrix = np.nan_to_num(conn_matrix) G = nx.from_numpy_matrix(np.abs(conn_matrix)) maximum_edges = G.number_of_edges() Gcc = sorted(nx.connected_components(G), key=len, reverse=True) G0 = G.subgraph(Gcc[0]) min_t = nx.minimum_spanning_tree(thresholding.weight_to_distance(G0), weight="distance") min_t.add_nodes_from(G.nodes()) 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]) edgenum = int(float(thr) * float(len(weights[~np.isnan(weights)]))) if len_edges > edgenum: print( f"Warning: The minimum spanning tree already has: {len_edges} edges, select more edges. Local Threshold " f"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) # Remove edges from the NNG that exist already in the new graph/MST nng.remove_edges_from(min_t.edges()) number_before = nng.number_of_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(f"Adding edge to mst: {edge}") min_t.add_edges_from([edge]) len_edges = min_t.number_of_edges() if len_edges >= edgenum: # print(len_edges) break k += 1 conn_matrix_bin = thresholding.binarize( nx.to_numpy_array(min_t, nodelist=sorted(G.nodes()), dtype=np.float64)) try: conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin) return conn_matrix_thr except ValueError: print( "MST thresholding failed. Check raw graph output manually for debugging." )
def local_thresholding_prop(conn_matrix, coords, labels, 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.core import thresholding from pynets.stats import netstats fail_tol = 100 conn_matrix = np.nan_to_num(conn_matrix) G = nx.from_numpy_matrix(np.abs(conn_matrix)) if not nx.is_connected(G): [G, pruned_nodes] = netstats.prune_disconnected(G) pruned_nodes.sort(reverse=True) coords_pre = list(coords) labels_pre = list(labels) if len(pruned_nodes) > 0: for j in pruned_nodes: labels_pre.pop(j) coords_pre.pop(j) conn_matrix = nx.to_numpy_array(G) labels = labels_pre coords = coords_pre maximum_edges = G.number_of_edges() min_t = nx.minimum_spanning_tree(thresholding.weight_to_distance(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]) edgenum = int(float(thr) * float(len(weights[~np.isnan(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, coords, labels 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) # Remove edges from the NNG that exist already in the new graph/MST nng.remove_edges_from(min_t.edges()) number_before = nng.number_of_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]) len_edges = min_t.number_of_edges() if len_edges >= edgenum: print(len_edges) break k += 1 conn_matrix_bin = thresholding.binarize( nx.to_numpy_array(min_t, nodelist=sorted(min_t.nodes()), dtype=np.float64)) # Enforce original dimensionality by padding with zeros. if conn_matrix_bin.shape != conn_matrix.shape: if conn_matrix.shape[0] > conn_matrix_bin.shape[0]: result = np.zeros(conn_matrix.shape) result[:conn_matrix_bin.shape[0], :conn_matrix_bin. shape[1]] = conn_matrix_bin conn_matrix_thr = np.multiply(conn_matrix, result) else: result = np.zeros(conn_matrix_bin.shape) result[:conn_matrix.shape[0], :conn_matrix.shape[1]] = conn_matrix conn_matrix_thr = np.multiply(conn_matrix_bin, result) else: conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin) return conn_matrix_thr, coords, labels
def test_weight_to_distance(x): G = nx.from_numpy_matrix(x) w = thresholding.weight_to_distance(G) assert w is not None