def structural_plotting(conn_matrix_symm, label_names, atlas_select, ID, bedpostx_dir, network, parc, roi, coords, dir_path, conn_model, thr, node_size, smooth): import matplotlib matplotlib.use('agg') from matplotlib import pyplot as plt import nipype.interfaces.fsl as fsl import nipype.pipeline.engine as pe import seaborn as sns import pkg_resources from matplotlib import colors from nilearn import plotting as niplot from pynets.plotting import plot_gen, plot_graphs try: import cPickle as pickle except ImportError: import _pickle as pickle edge_threshold = 0.10 connectome_fdt_thresh = 90 dpi_resolution = 500 bpx_trx = False # # Auto-set INPUTS# # try: FSLDIR = os.environ['FSLDIR'] except NameError: print('FSLDIR environment variable not set!') nodif_brain_mask_path = "%s%s" % (bedpostx_dir, '/nodif_brain_mask.nii.gz') if parc is True: node_size = 'parc' if network: probtrackx_output_dir_path = "%s%s%s%s%s%s" % (dir_path, '/probtrackx_', str(node_size), '%s' % ("mm_" if node_size != 'parc' else "_"), "%s" % ("%s%s" % (smooth, 'fwhm_') if float(smooth) > 0 else 'nosm_'), network) else: probtrackx_output_dir_path = "%s%s%s%s%s" % (dir_path, '/probtrackx_WB_', str(node_size), '%s' % ("mm_" if node_size != 'parc' else "_"), "%s" % ("%s%s" % (smooth, 'fwhm') if float(smooth) > 0 else 'nosm')) # # Auto-set INPUTS# # # G_pre=nx.from_numpy_matrix(conn_matrix_symm) # if pruning is True: # [G, pruned_nodes] = most_important(G_pre) # else: # G = G_pre # conn_matrix = nx.to_numpy_array(G) # # pruned_nodes.sort(reverse=True) # for j in pruned_nodes: # del label_names[label_names.index(label_names[j])] # del coords[coords.index(coords[j])] # # pruned_edges.sort(reverse=True) # for j in pruned_edges: # del label_names[label_names.index(label_names[j])] # del coords[coords.index(coords[j])] # Plot adj. matrix based on determined inputs plot_graphs.plot_conn_mat_struct(conn_matrix_symm, conn_model, atlas_select, dir_path, ID, network, label_names, roi, thr, node_size, smooth) if bpx_trx is True: # Prepare glass brain figure fdt_paths_loc = "%s%s" % (probtrackx_output_dir_path, '/fdt_paths.nii.gz') # Create transform matrix between diff and MNI using FLIRT flirt = pe.Node(interface=fsl.FLIRT(cost_func='mutualinfo'), name='coregister') flirt.inputs.reference = "%s%s" % (FSLDIR, '/data/standard/MNI152_T1_1mm_brain.nii.gz') flirt.inputs.in_file = nodif_brain_mask_path flirt.inputs.out_matrix_file = "%s%s" % (bedpostx_dir, '/xfms/diff2MNI.mat') flirt.inputs.out_file = '/tmp/out_flirt.nii.gz' flirt.run() # Apply transform between diff and MNI using FLIRT flirt = pe.Node(interface=fsl.FLIRT(cost_func='mutualinfo'), name='coregister') flirt.inputs.reference = "%s%s" % (FSLDIR, '/data/standard/MNI152_T1_1mm_brain.nii.gz') flirt.inputs.in_file = nodif_brain_mask_path flirt.inputs.apply_xfm = True flirt.inputs.in_matrix_file = "%s%s" % (bedpostx_dir, '/xfms/diff2MNI.mat') flirt.inputs.out_file = "%s%s" % (bedpostx_dir, '/xfms/diff2MNI_affine.nii.gz') flirt.inputs.out_matrix_file = '/tmp/out_flirt.mat' flirt.run() flirt = pe.Node(interface=fsl.FLIRT(cost_func='mutualinfo'), name='coregister') flirt.inputs.reference = "%s%s" % (FSLDIR, '/data/standard/MNI152_T1_1mm_brain.nii.gz') flirt.inputs.in_file = fdt_paths_loc out_file_MNI = "%s%s" % (fdt_paths_loc.split('.nii')[0], '_MNI.nii.gz') flirt.inputs.out_file = out_file_MNI flirt.inputs.out_matrix_file = '/tmp/out_flirt.mat' flirt.inputs.apply_xfm = True flirt.inputs.in_matrix_file = "%s%s" % (bedpostx_dir, '/xfms/diff2MNI.mat') flirt.run() fdt_paths_MNI_loc = "%s%s" % (probtrackx_output_dir_path, '/fdt_paths_MNI.nii.gz') else: fdt_paths_MNI_loc = None colors.Normalize(vmin=-1, vmax=1) clust_pal = sns.color_palette("Blues_r", 4) clust_colors = colors.to_rgba_array(clust_pal) # Plotting with glass brain ch2better_loc = pkg_resources.resource_filename("pynets", "templates/ch2better.nii.gz") connectome = niplot.plot_connectome(np.zeros(shape=(1, 1)), [(0, 0, 0)], node_size=0.0001, black_bg=True) connectome.add_overlay(ch2better_loc, alpha=0.5, cmap=plt.cm.gray) [z_min, z_max] = -np.abs(conn_matrix_symm).max(), np.abs(conn_matrix_symm).max() connectome.add_graph(conn_matrix_symm, coords, edge_threshold=edge_threshold, node_color=clust_colors, edge_cmap=plt.cm.binary, edge_vmax=z_max, edge_vmin=z_min, node_size=4) if bpx_trx is True and fdt_paths_MNI_loc: connectome.add_overlay(img=fdt_paths_MNI_loc, threshold=connectome_fdt_thresh, cmap=niplot.cm.cyan_copper_r, alpha=0.6) # Plot connectome if roi: out_path_fig = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (dir_path, '/', ID, '_', str(atlas_select), '_', str(conn_model), '_', str(op.basename(roi).split('.')[0]), "%s" % ("%s%s%s" % ('_', network, '_') if network else "_"), str(thr), '_', str(node_size), '%s' % ("mm_" if node_size != 'parc' else "_"), "%s" % ("%s%s" % (smooth, 'fwhm_') if float(smooth) > 0 else 'nosm_'), 'struct_glass_viz.png') coord_path = "%s%s%s%s" % (dir_path, '/struct_coords_', op.basename(roi).split('.')[0], '_plotting.pkl') labels_path = "%s%s%s%s" % (dir_path, '/struct_labelnames_', op.basename(roi).split('.')[0], '_plotting.pkl') else: out_path_fig = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (dir_path, '/', ID, '_', str(atlas_select), '_', str(conn_model), "%s" % ("%s%s%s" % ('_', network, '_') if network else "_"), str(thr), '_', str(node_size), '%s' % ("mm_" if node_size != 'parc' else "_"), "%s" % ("%s%s" % (smooth, 'fwhm_') if float(smooth) > 0 else 'nosm_'), 'struct_glass_viz.png') coord_path = "%s%s" % (dir_path, '/struct_coords_plotting.pkl') labels_path = "%s%s" % (dir_path, '/struct_labelnames_plotting.pkl') # Save coords to pickle with open(coord_path, 'wb') as f: pickle.dump(coords, f, protocol=2) # Save labels to pickle with open(labels_path, 'wb') as f: pickle.dump(label_names, f, protocol=2) connectome.savefig(out_path_fig, dpi=dpi_resolution) # connectome.savefig(out_path_fig, dpi=dpi_resolution, facecolor ='k', edgecolor ='k') connectome.close() return
def plot_all_struct(conn_matrix, conn_model, atlas, dir_path, ID, network, labels, roi, coords, thr, node_size, edge_threshold, prune, uatlas, target_samples, norm, binary, track_type, directget, max_length): """ Plot adjacency matrix, connectogram, and glass brain for functional connectome. Parameters ---------- conn_matrix : array NxN matrix. 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. atlas : str Name of atlas parcellation used. dir_path : str Path to directory containing subject derivative data for given run. ID : str A subject id or other unique identifier. 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. labels : list List of string labels corresponding to ROI nodes. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. coords : list List of (x, y, z) tuples corresponding to an a-priori defined set (e.g. a coordinate atlas). thr : float A value, between 0 and 1, 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. edge_threshold : float The actual value, between 0 and 1, that the graph was thresholded (can differ from thr if target was not successfully obtained. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. target_samples : int Total number of streamline samples specified to generate streams. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). 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 matplotlib matplotlib.use('agg') import os import os.path as op from matplotlib import pyplot as plt from nilearn import plotting as niplot import pkg_resources import networkx as nx from matplotlib import colors import seaborn as sns from pynets.core import thresholding from pynets.plotting import plot_gen, plot_graphs from pynets.stats.netstats import most_important, prune_disconnected try: import cPickle as pickle except ImportError: import _pickle as pickle ch2better_loc = pkg_resources.resource_filename("pynets", "templates/ch2better.nii.gz") coords = list(coords) labels = list(labels) if len(coords) > 0: dpi_resolution = 500 if '\'b' in atlas: atlas = atlas.decode('utf-8') if (prune == 1 or prune == 2) and len(coords) == conn_matrix.shape[0]: G_pre = nx.from_numpy_matrix(np.abs(conn_matrix)) if prune == 1: [G, pruned_nodes] = prune_disconnected(G_pre) elif prune == 2: [G, pruned_nodes] = most_important(G_pre) else: G = G_pre pruned_nodes = [] 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 else: print('No nodes to prune for plot...') coords = list(tuple(x) for x in coords) namer_dir = dir_path + '/figures' if not os.path.isdir(namer_dir): os.makedirs(namer_dir, exist_ok=True) # Plot connectogram if len(conn_matrix) > 20: try: plot_gen.plot_connectogram(conn_matrix, conn_model, atlas, namer_dir, ID, network, labels) except RuntimeWarning: print('\n\n\nWarning: Connectogram plotting failed!') else: print('Warning: Cannot plot connectogram for graphs smaller than 20 x 20!') # Plot adj. matrix based on determined inputs if not node_size or node_size == 'None': node_size = 'parc' plot_graphs.plot_conn_mat_struct(conn_matrix, conn_model, atlas, namer_dir, ID, network, labels, roi, thr, node_size, target_samples, track_type, directget, max_length) # Plot connectome out_path_fig = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (namer_dir, '/', ID, '_modality-dwi_', '%s' % ("%s%s%s" % ('rsn-', network, '_') if network is not None else ''), '%s' % ("%s%s%s" % ('roi-', op.basename(roi).split( '.')[0], '_') if roi is not None else ''), 'est-', conn_model, '_', '%s' % ( "%s%s%s" % ('nodetype-spheres-', node_size, 'mm_') if ((node_size != 'parc') and (node_size is not None)) else 'nodetype-parc_'), "%s" % ("%s%s%s" % ( 'samples-', int(target_samples), 'streams_') if float(target_samples) > 0 else '_'), 'tt-', track_type, '_dg-', directget, '_ml-', max_length, '_thr-', thr, '_glass_viz.png') if roi: # Save coords to pickle coord_path = "%s%s%s%s" % (namer_dir, '/coords_', op.basename(roi).split('.')[0], '_plotting.pkl') with open(coord_path, 'wb') as f: pickle.dump(coords, f, protocol=2) # Save labels to pickle labels_path = "%s%s%s%s" % (namer_dir, '/labelnames_', op.basename(roi).split('.')[0], '_plotting.pkl') with open(labels_path, 'wb') as f: pickle.dump(labels, f, protocol=2) else: # Save coords to pickle coord_path = "%s%s" % (namer_dir, '/coords_plotting.pkl') with open(coord_path, 'wb') as f: pickle.dump(coords, f, protocol=2) # Save labels to pickle labels_path = "%s%s" % (namer_dir, '/labelnames_plotting.pkl') with open(labels_path, 'wb') as f: pickle.dump(labels, f, protocol=2) connectome = niplot.plot_connectome(np.zeros(shape=(1, 1)), [(0, 0, 0)], node_size=0.0001, black_bg=True) connectome.add_overlay(ch2better_loc, alpha=0.45, cmap=plt.cm.gray) #connectome.add_overlay(ch2better_loc, alpha=0.35, cmap=plt.cm.gray) conn_matrix = np.array(np.array(thresholding.autofix(conn_matrix))) [z_min, z_max] = -np.abs(conn_matrix).max(), np.abs(conn_matrix).max() if node_size == 'parc': node_size_plot = int(6) else: node_size_plot = int(node_size) if len(coords) != conn_matrix.shape[0]: raise RuntimeWarning('\nWARNING: Number of coordinates does not match conn_matrix dimensions.') else: norm = colors.Normalize(vmin=-1, vmax=1) clust_pal = sns.color_palette("Blues_r", conn_matrix.shape[0]) clust_colors = colors.to_rgba_array(clust_pal) fa_path = dir_path + '/../reg_dmri/dmri_tmp/DSN/Warped.nii.gz' if os.path.isfile(fa_path): connectome.add_overlay(img=fa_path, threshold=0.01, alpha=0.25, cmap=plt.cm.copper) connectome.add_graph(conn_matrix, coords, edge_threshold=edge_threshold, edge_cmap=plt.cm.binary, edge_vmax=float(z_max), edge_vmin=float(z_min), node_size=node_size_plot, node_color=clust_colors) connectome.savefig(out_path_fig, dpi=dpi_resolution) else: raise RuntimeError('\nERROR: no coordinates to plot! Are you running plotting outside of pynets\'s internal ' 'estimation schemes?') plt.close('all') return
def plot_all_struct(conn_matrix, conn_model, atlas, dir_path, ID, network, labels, roi, coords, thr, node_size, edge_threshold, prune, uatlas, target_samples, norm, binary, track_type, directget, min_length): """ Plot adjacency matrix, connectogram, and glass brain for functional connectome. Parameters ---------- conn_matrix : array NxN matrix. 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. atlas : str Name of atlas parcellation used. dir_path : str Path to directory containing subject derivative data for given run. ID : str A subject id or other unique identifier. 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. labels : list List of string labels corresponding to ROI nodes. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. coords : list List of (x, y, z) tuples corresponding to an a-priori defined set (e.g. a coordinate atlas). thr : float A value, between 0 and 1, 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. edge_threshold : float The actual value, between 0 and 1, that the graph was thresholded (can differ from thr if target was not successfully obtained. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. target_samples : int Total number of streamline samples specified to generate streams. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). directget : str The statistical approach to tracking. Options are: det (deterministic), closest (clos), boot (bootstrapped), and prob (probabilistic). min_length : int Minimum fiber length threshold in mm to restrict tracking. """ import matplotlib matplotlib.use('agg') import os import yaml import sys import os.path as op from matplotlib import pyplot as plt from nilearn import plotting as niplot import pkg_resources import networkx as nx from pynets.plotting import plot_gen, plot_graphs from pynets.plotting.plot_gen import create_gb_palette try: import cPickle as pickle except ImportError: import _pickle as pickle ch2better_loc = pkg_resources.resource_filename( "pynets", "templates/ch2better.nii.gz") with open(pkg_resources.resource_filename("pynets", "runconfig.yaml"), 'r') as stream: hardcoded_params = yaml.load(stream) try: color_theme = hardcoded_params['plotting']['structural'][ 'glassbrain']['color_theme'][0] connectogram = hardcoded_params['plotting']['connectogram'][0] glassbrain = hardcoded_params['plotting']['glassbrain'][0] adjacency = hardcoded_params['plotting']['adjacency'][0] dpi_resolution = hardcoded_params['plotting']['dpi'][0] except KeyError: print( 'ERROR: Plotting configuration not successfully extracted from runconfig.yaml' ) sys.exit(0) stream.close() if not isinstance(coords, list): coords = list(tuple(x) for x in coords) if not isinstance(labels, list): labels = list(labels) if len(coords) > 0: if '\'b' in atlas: atlas = atlas.decode('utf-8') namer_dir = dir_path + '/figures' if not os.path.isdir(namer_dir): os.makedirs(namer_dir, exist_ok=True) # Plot connectogram if connectogram is True: if len(conn_matrix) > 20: try: plot_gen.plot_connectogram(conn_matrix, conn_model, atlas, namer_dir, ID, network, labels) except RuntimeWarning: print('\n\n\nWarning: Connectogram plotting failed!') else: print( 'Warning: Cannot plot connectogram for graphs smaller than 20 x 20!' ) # Plot adj. matrix based on determined inputs if not node_size or node_size == 'None': node_size = 'parc' if adjacency is True: plot_graphs.plot_conn_mat_struct(conn_matrix, conn_model, atlas, namer_dir, ID, network, labels, roi, thr, node_size, target_samples, track_type, directget, min_length) if glassbrain is True: views = ['x', 'y', 'z'] # Plot connectome out_path_fig = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % ( namer_dir, '/', ID, '_modality-dwi_', '%s' % ("%s%s%s" % ('rsn-', network, '_') if network is not None else ''), '%s' % ("%s%s%s" % ('roi-', op.basename(roi).split('.')[0], '_') if roi is not None else ''), 'est-', conn_model, '_', '%s' % ("%s%s%s" % ('nodetype-spheres-', node_size, 'mm_') if ((node_size != 'parc') and (node_size is not None)) else 'nodetype-parc_'), "%s" % ("%s%s%s" % ('samples-', int(target_samples), 'streams_') if float(target_samples) > 0 else '_'), 'tt-', track_type, '_dg-', directget, '_ml-', min_length, '_thr-', thr, '_glass_viz.png') connectome = niplot.plot_connectome(np.zeros(shape=(1, 1)), [(0, 0, 0)], node_size=0.0001, black_bg=True) connectome.add_overlay(ch2better_loc, alpha=0.45, cmap=plt.cm.gray) [ conn_matrix, clust_pal_edges, clust_pal_nodes, node_sizes, edge_sizes, _, _, coords, labels ] = create_gb_palette(conn_matrix, color_theme, coords, labels) if roi: # Save coords to pickle coord_path = f"{namer_dir}{'/coords_'}{op.basename(roi).split('.')[0]}{'_plotting.pkl'}" with open(coord_path, 'wb') as f: pickle.dump(coords, f, protocol=2) # Save labels to pickle labels_path = f"{namer_dir}{'/labelnames_'}{op.basename(roi).split('.')[0]}{'_plotting.pkl'}" with open(labels_path, 'wb') as f: pickle.dump(labels, f, protocol=2) else: # Save coords to pickle coord_path = f"{namer_dir}{'/coords_plotting.pkl'}" with open(coord_path, 'wb') as f: pickle.dump(coords, f, protocol=2) # Save labels to pickle labels_path = f"{namer_dir}{'/labelnames_plotting.pkl'}" with open(labels_path, 'wb') as f: pickle.dump(labels, f, protocol=2) connectome.add_graph(conn_matrix, coords, edge_cmap=clust_pal_edges, edge_vmax=float(1), edge_vmin=float(1), node_size=node_sizes, node_color=clust_pal_nodes, edge_kwargs={ 'alpha': 0.50, "lineStyle": 'dashed' }) for view in views: mod_lines = [] for line, edge_size in list( zip(connectome.axes[view].ax.lines, edge_sizes)): line.set_lw(edge_size) mod_lines.append(line) connectome.axes[view].ax.lines = mod_lines connectome.savefig(out_path_fig, dpi=dpi_resolution) else: raise RuntimeError( '\nERROR: no coordinates to plot! Are you running plotting outside of pynets\'s ' 'internal estimation schemes?') plt.close('all') return