def perform_thresholding(conn_matrix, thr, min_span_tree, dens_thresh, disp_filt): """ References ---------- .. [1] Fornito, A., Zalesky, A., & Bullmore, E. T. (2016). Fundamentals of Brain Network Analysis. In Fundamentals of Brain Network Analysis. https://doi.org/10.1016/C2012-0-06036-X """ import numpy as np import networkx as nx from pynets.core import thresholding thr_perc = 100 - np.abs(100 * float(thr)) if min_span_tree is True: print("Using local thresholding from the " "Minimum Spanning Tree (MST)...\n") if dens_thresh is True: print("Ignoring -dt flag since local density thresholding is not" " currently supported.") thr_type = "MST" edge_threshold = f"{str(thr_perc)}%" conn_matrix_thr = thresholding.local_thresholding_prop( conn_matrix, thr) elif disp_filt is True: thr_type = "DISPARITY" edge_threshold = f"{str(thr_perc)}%" G1 = thresholding.disparity_filter( nx.from_numpy_array(np.abs(conn_matrix))) print(f"Computing edge disparity significance with alpha = {thr}") print(f"Filtered graph: nodes = {G1.number_of_nodes()}, " f"edges = {G1.number_of_edges()}") conn_matrix_bin = thresholding.binarize( nx.to_numpy_array(G1, nodelist=sorted(G1.nodes()), dtype=np.float64)) # Enforce original dimensionality by padding with zeros. conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin) else: if dens_thresh is False: thr_type = "PROP" edge_threshold = f"{str(thr_perc)}{'%'}" print(f"\nThresholding proportionally at: {thr_perc}% ...\n") conn_matrix_thr = thresholding.threshold_proportional( conn_matrix, float(thr)) else: thr_type = "DENS" edge_threshold = None print(f"\nThresholding to achieve density of: {thr_perc}% ...\n") conn_matrix_thr = thresholding.density_thresholding( conn_matrix, float(thr)) return thr_type, edge_threshold, conn_matrix_thr
def test_density(x, thr): d_known = thresholding.est_density( thresholding.threshold_absolute(x, thr, copy=True)) x = thresholding.density_thresholding(x, d_known) d_test = thresholding.est_density(x) assert np.equal(np.round(d_known, 1), np.round(d_test, 1))
def perform_thresholding(conn_matrix, coords, labels, thr, thr_perc, min_span_tree, dens_thresh, disp_filt): from pynets.core import thresholding if min_span_tree is True: print( 'Using local thresholding option with the Minimum Spanning Tree (MST)...\n' ) if dens_thresh is True: print( 'Ignoring -dt flag since local density thresholding is not currently supported.' ) thr_type = 'MST_thr' edge_threshold = "%s%s" % (str(thr_perc), '%') [conn_matrix_thr, coords, labels ] = thresholding.local_thresholding_prop(conn_matrix, coords, labels, thr) elif disp_filt is True: thr_type = 'DISP_alpha' edge_threshold = "%s%s" % (str(thr_perc), '%') G1 = thresholding.disparity_filter( nx.from_numpy_array(np.abs(conn_matrix))) # G2 = nx.Graph([(u, v, d) for u, v, d in G1.edges(data=True) if d['alpha'] < thr]) print('Computing edge disparity significance with alpha = %s' % thr) print('Filtered graph: nodes = %s, edges = %s' % (G1.number_of_nodes(), G1.number_of_edges())) # print('Backbone graph: nodes = %s, edges = %s' % (G2.number_of_nodes(), G2.number_of_edges())) # print(G2.edges(data=True)) conn_matrix_bin = thresholding.binarize( nx.to_numpy_array(G1, nodelist=sorted(G1.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) else: if dens_thresh is False: thr_type = 'prop' edge_threshold = "%s%s" % (str(thr_perc), '%') print("%s%.2f%s" % ('\nThresholding proportionally at: ', thr_perc, '% ...\n')) conn_matrix_thr = thresholding.threshold_proportional( conn_matrix, float(thr)) else: thr_type = 'dens' edge_threshold = None print("%s%.2f%s" % ('\nThresholding to achieve density of: ', thr_perc, '% ...\n')) conn_matrix_thr = thresholding.density_thresholding( conn_matrix, float(thr)) return thr_type, edge_threshold, conn_matrix_thr, coords, labels
def thresh_struct(dens_thresh, thr, conn_matrix, conn_model, network, ID, dir_path, roi, node_size, min_span_tree, disp_filt, parc, prune, atlas, uatlas, labels, coords, norm, binary, target_samples, track_type, atlas_mni, streams, directget, max_length): """ Threshold a structural connectivity matrix using any of a variety of methods. Parameters ---------- dens_thresh : bool Indicates whether a target graph density is to be used as the basis for thresholding. thr : float A value, between 0 and 1, to threshold the graph using any variety of methods triggered through other options. conn_matrix : array Adjacency matrix stored as an m x n array of nodes and edges. conn_model : str Connectivity estimation model (e.g. corr for correlation, cov for covariance, sps for precision covariance, partcorr for partial correlation). sps type is used by default. network : str Resting-state network based on Yeo-7 and Yeo-17 naming (e.g. 'Default') used to filter nodes in the study of brain subgraphs. ID : str A subject id or other unique identifier. dir_path : str Path to directory containing subject derivative data for given run. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. node_size : int Spherical centroid node size in the case that coordinate-based centroids are used as ROI's. min_span_tree : bool Indicates whether local thresholding from the Minimum Spanning Tree should be used. disp_filt : bool Indicates whether local thresholding using a disparity filter and 'backbone network' should be used. parc : bool Indicates whether to use parcels instead of coordinates as ROI nodes. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. atlas : str Name of atlas parcellation used. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. labels : list List of string labels corresponding to ROI nodes. coords : list List of (x, y, z) tuples corresponding to a coordinate atlas used or which represent the center-of-mass of each parcellation node. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. target_samples : int Total number of streamline samples specified to generate streams. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). atlas_mni : str File path to atlas parcellation Nifti1Image in T1w-warped MNI space. streams : str File path to save streamline array sequence in .trk format. directget : str The statistical approach to tracking. Options are: det (deterministic), closest (clos), boot (bootstrapped), and prob (probabilistic). max_length : int Maximum fiber length threshold in mm to restrict tracking. Returns ------- conn_matrix_thr : array Weighted, thresholded, NxN matrix. edge_threshold : str The string percentage representation of thr. est_path : str File path to the thresholded graph, conn_matrix_thr, saved as a numpy array in .npy format. thr : float The value, between 0 and 1, used to threshold the graph using any variety of methods triggered through other options. node_size : int Spherical centroid node size in the case that coordinate-based centroids are used as ROI's. network : str Resting-state network based on Yeo-7 and Yeo-17 naming (e.g. 'Default') used to filter nodes in the study of brain subgraphs. conn_model : str Connectivity estimation model (e.g. corr for correlation, cov for covariance, sps for precision covariance, partcorr for partial correlation). sps type is used by default. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. ID : str A subject id or other unique identifier. dir_path : str Path to directory containing subject derivative data for given run. atlas : str Name of atlas parcellation used. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. labels : list List of string labels corresponding to ROI nodes. coords : list List of (x, y, z) tuples corresponding to a coordinate atlas used or which represent the center-of-mass of each parcellation node. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. target_samples : int Total number of streamline samples specified to generate streams. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). atlas_mni : str File path to atlas parcellation Nifti1Image in T1w-warped MNI space. streams : str File path to save streamline array sequence in .trk format. directget : str The statistical approach to tracking. Options are: det (deterministic), closest (clos), boot (bootstrapped), and prob (probabilistic). max_length : int Maximum fiber length threshold in mm to restrict tracking. """ import gc from pynets.core import utils, thresholding thr_perc = 100 * float(thr) if parc is True: node_size = 'parc' if np.count_nonzero(conn_matrix) == 0: raise ValueError('ERROR: Raw connectivity matrix contains only zeros.') # Save unthresholded utils.save_mat(conn_matrix, utils.create_raw_path_diff(ID, network, conn_model, roi, dir_path, node_size, target_samples, track_type, parc, directget, max_length)) if min_span_tree is True: print('Using local thresholding option with the Minimum Spanning Tree (MST)...\n') if dens_thresh is False: print('Ignoring -dt flag since local density thresholding is not currently supported.') thr_type = 'MST_thr' edge_threshold = "%s%s" % (str(np.abs(1 - thr_perc)), '%') [conn_matrix_thr, coords, labels] = thresholding.local_thresholding_prop(conn_matrix, coords, labels, thr) elif disp_filt is True: thr_type = 'DISP_alpha' edge_threshold = "%s%s" % (str(np.abs(1 - thr_perc)), '%') G1 = thresholding.disparity_filter(nx.from_numpy_array(conn_matrix)) # G2 = nx.Graph([(u, v, d) for u, v, d in G1.edges(data=True) if d['alpha'] < thr]) print('Computing edge disparity significance with alpha = %s' % thr) print('Filtered graph: nodes = %s, edges = %s' % (G1.number_of_nodes(), G1.number_of_edges())) # print('Backbone graph: nodes = %s, edges = %s' % (G2.number_of_nodes(), G2.number_of_edges())) # print(G2.edges(data=True)) conn_matrix_thr = nx.to_numpy_array(G1) else: if dens_thresh is False: thr_type = 'prop' edge_threshold = "%s%s" % (str(np.abs(thr_perc)), '%') print("%s%.2f%s" % ('\nThresholding proportionally at: ', thr_perc, '% ...\n')) conn_matrix_thr = thresholding.threshold_proportional(conn_matrix, float(thr)) else: thr_type = 'dens' edge_threshold = "%s%s" % (str(np.abs(1 - thr_perc)), '%') print("%s%.2f%s" % ('\nThresholding to achieve density of: ', thr_perc, '% ...\n')) conn_matrix_thr = thresholding.density_thresholding(conn_matrix, float(thr)) if not nx.is_connected(nx.from_numpy_matrix(conn_matrix_thr)): print('Warning: Fragmented graph') # Save thresholded mat est_path = utils.create_est_path_diff(ID, network, conn_model, thr, roi, dir_path, node_size, target_samples, track_type, thr_type, parc, directget, max_length) utils.save_mat(conn_matrix_thr, est_path) gc.collect() return conn_matrix_thr, edge_threshold, est_path, thr, node_size, network, conn_model, roi, prune, ID, dir_path, atlas, uatlas, labels, coords, norm, binary, target_samples, track_type, atlas_mni, streams, directget, max_length
def perform_thresholding(conn_matrix, thr, min_span_tree, dens_thresh, disp_filt): ''' References ---------- .. [1] Fornito, A., Zalesky, A., & Bullmore, E. T. (2016). Fundamentals of Brain Network Analysis. In Fundamentals of Brain Network Analysis. https://doi.org/10.1016/C2012-0-06036-X ''' import numpy as np import networkx as nx from pynets.core import thresholding thr_perc = 100 - np.abs(100 * float(thr)) if min_span_tree is True: print( 'Using local thresholding option with the Minimum Spanning Tree (MST)...\n' ) if dens_thresh is True: print( 'Ignoring -dt flag since local density thresholding is not currently supported.' ) thr_type = 'MST' edge_threshold = f"{str(thr_perc)}%" conn_matrix_thr = thresholding.local_thresholding_prop( conn_matrix, thr) elif disp_filt is True: thr_type = 'DISPARITY' edge_threshold = f"{str(thr_perc)}%" G1 = thresholding.disparity_filter( nx.from_numpy_array(np.abs(conn_matrix))) # G2 = nx.Graph([(u, v, d) for u, v, d in G1.edges(data=True) if d['alpha'] < thr]) print(f"Computing edge disparity significance with alpha = {thr}") print( f'Filtered graph: nodes = {G1.number_of_nodes()}, edges = {G1.number_of_edges()}' ) # print(f'Backbone graph: nodes = {G2.number_of_nodes()}, edges = {G2.number_of_edges()}") # print(G2.edges(data=True)) conn_matrix_bin = thresholding.binarize( nx.to_numpy_array(G1, nodelist=sorted(G1.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) else: if dens_thresh is False: thr_type = 'PROP' edge_threshold = f"{str(thr_perc)}{'%'}" print(f"\nThresholding proportionally at: {thr_perc}% ...\n") conn_matrix_thr = thresholding.threshold_proportional( conn_matrix, float(thr)) else: thr_type = 'DENS' edge_threshold = None print(f"\nThresholding to achieve density of: {thr_perc}% ...\n") conn_matrix_thr = thresholding.density_thresholding( conn_matrix, float(thr)) return thr_type, edge_threshold, conn_matrix_thr