def generate_ss(modDir, ssDir, cases, ncpu, cut_coords): # reorder both skeleton/* and warped/* according to caseId warpedImgs = glob(pjoin(modDir, 'warped', '*_to_target.nii.gz')) warpedImgs.sort() skelImgs = glob(pjoin(modDir, 'skeleton', '*_to_target_skel.nii.gz')) skelImgs.sort() makeDirectory(ssDir) pool = Pool(ncpu) for fg, bg, c in zip(image.iter_img(skelImgs), image.iter_img(warpedImgs), cases): print('Taking screen shot of ', c) output_file = pjoin(ssDir, f'{c}.png') pool.apply_async(func=plotting.plot_stat_map, args=(fg, ), kwds={ 'bg_img': bg, 'dim': False, 'annotate': False, 'draw_cross': False, 'cut_coords': cut_coords, 'resampling_interpolation': 'nearest', 'output_file': output_file }, error_callback=RAISE) pool.close() pool.join() '''
def plot_ica_components(components_img, **kwargs): """ Plot the components IC spatial maps in a grid.""" import math from nilearn.image import iter_img from nilearn.plotting import plot_stat_map from matplotlib import pyplot as plt from matplotlib import gridspec n_ics = len(list(iter_img(components_img))) n_rows = math.ceil(n_ics / 2) fig = plt.figure(figsize=(6, 3 * n_rows), facecolor='black') gs = gridspec.GridSpec(n_rows, 2) plots = [] for i, ic_img in enumerate(iter_img(components_img)): ax = plt.subplot(gs[i]) p = plot_stat_map(ic_img, display_mode="z", title="IC {}".format(i + 1), cut_coords=1, colorbar=False, figure=fig, axes=ax, **kwargs) plots.append(p) for p in plots: p.close() return fig
def test_plot_img_comparison(): fig, axes = plt.subplots(2, 1) axes = axes.ravel() kwargs = {"shape": (3, 2, 4), "length": 5} query_images, mask_img = data_gen.generate_fake_fmri( rand_gen=np.random.RandomState(0), **kwargs) # plot_img_comparison doesn't handle 4d images ATM query_images = list(image.iter_img(query_images)) target_images, _ = data_gen.generate_fake_fmri( rand_gen=np.random.RandomState(1), **kwargs) target_images = list(image.iter_img(target_images)) target_images[0] = query_images[0] masker = NiftiMasker(mask_img).fit() correlations = plotting.plot_img_comparison( target_images, query_images, masker, axes=axes, src_label="query") assert len(correlations) == len(query_images) assert correlations[0] == pytest.approx(1.) ax_0, ax_1 = axes # 5 scatterplots assert len(ax_0.collections) == 5 assert len(ax_0.collections[0].get_edgecolors() == masker.transform( target_images[0]).ravel().shape[0]) assert ax_0.get_ylabel() == "query" assert ax_0.get_xlabel() == "image set 1" # 5 regression lines assert len(ax_0.lines) == 5 assert ax_0.lines[0].get_linestyle() == "--" assert ax_1.get_title() == "Histogram of imgs values" assert len(ax_1.patches) == 5 * 2 * 128 correlations_1 = plotting.plot_img_comparison( target_images, query_images, masker, plot_hist=False) assert np.allclose(correlations, correlations_1)
def cluster_binary_img(binary_img, mask_img, min_region_size='exhaustive'): # get voxel resolution in binary_img # NOTE: function currently assumes equal width in x,y,z direction voxel_sizes = binary_img.header.get_zooms() # if not specfied by user, cluster exhaustive, i.e. assign each and every # voxel to one and only one cluster if min_region_size == 'exhaustive': min_region_size_ = _get_voxel_volume(voxel_sizes) - 1 else: min_region_size_ = min_region_size # count overall number of 1s in the binary image total_n_voxels = np.count_nonzero(binary_img.get_fdata()) # extract clusters in binary image cluster_imgs, indices = connected_regions( maps_img=binary_img, min_region_size=min_region_size_, extract_type='connected_components', smoothing_fwhm=None, mask_img=mask_img) # Get sizes of clusters (number of voxels that have been assigned to each region) # As a sanity check + for user information get size of every region and # count overall number of voxels that have been assigned to that region cluster_sizes = [] total_n_voxels_assigned = 0 for idx, cluster_img in enumerate(iter_img(cluster_imgs)): cluster_img_data = cluster_img.get_fdata() cluster_img_size = np.count_nonzero(cluster_img_data) cluster_sizes.append(cluster_img_size) total_n_voxels_assigned += cluster_img_size if total_n_voxels_assigned != total_n_voxels: raise ValueError( 'Number of voxels in output clustered image is different from total number of voxels in input binary image ' ) # Collapse the extracted cluster images to one cluster atlas image cluster_imgs_labeled = [] for idx, cluster_img in enumerate(iter_img(cluster_imgs), start=1): cluster_img_labeled = math_img( f"np.where(cluster_img == 1,{idx},cluster_img)", cluster_img=cluster_img) cluster_imgs_labeled.append(cluster_img_labeled) cluster_img_atlas = math_img("np.sum(imgs,axis=3)", imgs=cluster_imgs_labeled) # plot the cluster atlas image plotting.plot_roi(cluster_img_atlas, title='Clustered Binary Image', draw_cross=False) return cluster_sizes, cluster_img_atlas
def generate_ss(modDir, ssDir, cases, ncpu, cut_coords): # reorder both skeleton/* and warped/* according to caseId warpedImgs= glob(pjoin(modDir, 'warped', '*_to_target.nii.gz')) warpedImgs.sort() skelImgs= glob(pjoin(modDir, 'skeleton', '*_to_target_skel.nii.gz')) skelImgs.sort() makeDirectory(ssDir) pool= Pool(ncpu) for fg,bg,c in zip(image.iter_img(skelImgs), image.iter_img(warpedImgs), cases): print('Taking screen shot of ', c) output_file = pjoin(ssDir, f'{c}.png')
def load_vols(niimgs): """Loads a nifti image (or a bail of) into a list qof 3D volumes. Parameters ---------- niimgs: 3 or 4D Niimg-like object If niimgs is an iterable, checks if data is really 4D. Then, considering that it is a list of niimg and load them one by one. If niimg is a string, consider it as a path to Nifti image and call nibabel.load on it. If it is an object, check if get_data and get_affine methods are present, raise an Exception otherwise. Returns ------- niimgs_: list of nifti image objects The loaded volumes. """ # try loading 4d try: niimgs = list(check_niimg_4d(niimgs, return_iterator=True)) except TypeError: # probably not 4d niimgs = [check_niimg(niimgs)] except ValueError: # probably inconsisten affines pass try: # try loading volumes one-by-one if isinstance(niimgs, _basestring): niimgs = [niimgs] return [check_niimg(niimg, ensure_ndim=3) for niimg in niimgs] except TypeError: pass # collect the loaded volumes into a list if is_niimg(niimgs): # should be 3d, squash 4th dimension otherwise if niimgs.shape[-1] == 1: return [ nibabel.Nifti1Image(niimgs.get_data()[:, :, :, 0], niimgs.get_affine()) ] else: return list(iter_img(niimgs)) else: niimgs = list(niimgs) if len(niimgs) == 1: niimgs = niimgs[0] return list(iter_img(niimgs))
def test_component_sign(): # We should have a heuristic that flips the sign of components in # CanICA to have more positive values than negative values, for # instance by making sure that the largest value is positive. # make data (SVD) rng = np.random.RandomState(0) shape = (20, 10, 1) affine = np.eye(4) components = _make_canica_components(shape) # make +ve for mp in components: mp[rng.randn(*mp.shape) > .8] *= -5. assert_less_equal(mp.max(), -mp.min()) # goal met ? # synthesize data with given components data = _make_data_from_components(components, affine, shape, rng=rng, n_subjects=2) mask_img = nibabel.Nifti1Image(np.ones(shape, dtype=np.int8), affine) # run CanICA many times (this is known to produce different results) canica = CanICA(n_components=4, random_state=rng, mask=mask_img) for _ in range(3): canica.fit(data) for mp in iter_img(canica.masker_.inverse_transform( canica.components_)): mp = mp.get_data() assert_less_equal(-mp.min(), mp.max())
def test_iterator_generator(): # Create a list of random images rng = np.random.RandomState(42) list_images = [ Nifti1Image( rng.random_sample((10, 10, 10)), np.eye(4) ) for i in range(10) ] cc = _utils.concat_niimgs(list_images) assert cc.shape[-1] == 10 assert_array_almost_equal(get_data(cc)[..., 0], get_data(list_images[0])) # Same with iteration i = image.iter_img(list_images) cc = _utils.concat_niimgs(i) assert cc.shape[-1] == 10 assert_array_almost_equal(get_data(cc)[..., 0], get_data(list_images[0])) # Now, a generator b = [] g = nifti_generator(b) cc = _utils.concat_niimgs(g) assert cc.shape[-1] == 10 assert len(b) == 10
def create_provenance_dataframe(bids_sources, harmonized_niis, b0_means, harmonization_corrections): series_confounds = [] nvols_per_image = [get_nvols(img) for img in harmonized_niis] total_vols = np.sum(nvols_per_image) # Check whether the bids sources are per file or per volume if not len(bids_sources) == total_vols: images_per_volume = [] for source_image, img_nvols in zip(bids_sources, nvols_per_image): images_per_volume.extend([source_image] * img_nvols) if not len(images_per_volume) == total_vols: raise Exception("Mismatch in number of images and BIDS sources") bids_sources = images_per_volume for correction, harmonized_nii, b0_mean, nvols in zip(harmonization_corrections, harmonized_niis, b0_means, nvols_per_image): series_confounds.append( pd.DataFrame({ "image_mean": [img.get_fdata().mean() for img in iter_img(harmonized_nii)], "series_b0_mean": [b0_mean] * nvols, "series_b0_correction": [correction] * nvols})) image_df = pd.concat(series_confounds, axis=0, ignore_index=True) image_df['original_file'] = bids_sources return image_df
def plotrsn10(nii_ff, workdir, resultjpg_ff, threshold): ''' plotrsn10('PNAS_Smith09_rsn10.nii.gz',r'c:\temp',r'c:\temp\test.jpg') ''' z = [8, -4, -10, 30, -34, 50, 14, 22, 46, 48] ii = 0 images = [] fig = plt.figure(figsize=(4, 6), dpi=300) for img in image.iter_img(nii_ff): # img is now an in-memory 3D img tempimage = join(workdir, 'RSN%02d.jpg' % (ii + 1)) display = plotting.plot_stat_map(img, figure=fig, threshold=threshold, display_mode="z", cut_coords=[(z[ii])], colorbar=False) display.annotate(size=30) display.savefig(tempimage) images.append(tempimage) plt.clf() ii += 1 plt.close() row1 = concat_n_images(images[0:5]) row2 = concat_n_images(images[5:10]) output = np.vstack((row1, 255 * np.ones( (10, row1.shape[1], 3), dtype=np.uint8), row2)) fig = plt.figure(figsize=(output.shape[0] // 30, output.shape[1] // 30), dpi=100) plt.axis('off') plt.imshow(output) fig.savefig(resultjpg_ff, bbox_inches='tight')
def get_prob_atlas_label(prob_map, prob_labels, coord, thresh=None): label_prob = list() for slices in iter_img(prob_map): label_prob.append(slices.get_data()[coord[0], coord[1], coord[2]]) # Get probability above a certain threshold or max: if thresh is None: thresh = np.max(label_prob) if thresh == 0: thresh = 1 label_idx = np.where(np.asarray(label_prob) >= thresh)[0] labels_out = list() proba_out = list() for idx in label_idx: proba_out.append(label_prob[idx]) labels_out.append(prob_labels[idx]) return labels_out, proba_out
def filter_ics(comps_img, mask, zscore=2., mode='+-'): """ Generator for masking and thresholding each IC spatial map. Parameters ---------- comps_img: img-like The 'raw' ICC maps image. mask: img-like If not None. Will apply this masks in the end of the process. thr: float The threshold value. zscore: bool If True will calculate the z-score of the ICC before thresholding. mode: str Choices: '+' for positive threshold, '+-' for positive and negative threshold and '-' for negative threshold. Returns ------- icc_filts: list of nibabel.NiftiImage Thresholded and masked ICCs. """ # store the average value of the blob in a list mask = niimg.load_img(mask) for i, icimg in enumerate(iter_img(comps_img)): yield filter_icc(icimg, mask=mask, thr=zscore, zscore=True, mode=mode)
def plot_pro(self, ita, save=False, item_file='group', name='vmf', choose=None, cut_coords=None): ita[ita > 0.1] = 0 for component in ita: if component.max() < -component.min(): component *= -1 if hasattr(self, "masker_"): self.components_img_ = self.masker_.inverse_transform(ita) components_img = self.components_img_ warnings.filterwarnings("ignore") for i, cur_img in enumerate(iter_img(components_img)): if cut_coords is not None and i in cut_coords.keys(): display = plot_stat_map(cur_img, cut_coords=cut_coords[i], dim=-.5, threshold=4e-3, cmap=plt.get_cmap('autumn')) else: display = plot_stat_map(cur_img, dim=-.5, threshold=4e-3, cmap=plt.get_cmap('autumn')) if save: if choose is not None: display.savefig('{}/brain/{}/{}/SVAE-item{}-c.png'.format(RESULT_DIR, name, item_file, choose[i] + 1), dpi=200) else: display.savefig('{}/brain/{}/{}/SVAE-item{}-c.png'.format(RESULT_DIR, name, item_file, i + 1), dpi=200) if save is False: show()
def get_peak_coords(clust_img): """ Gets MNI coordinates of peak voxels within each cluster of `clust_img` Parameters ---------- clust_img : 4D-niimg_like 4D image of brain regions, where each volume is a separated cluster Returns ------ coords : (N, 3) numpy.ndarray Coordinates of peak voxels in `clust_img` """ # check cluster image and make it 4D, if not already clust_img = check_niimg(clust_img, atleast_4d=True) # create empty arrays to hold cluster size + peak coordinates clust_size = np.zeros(clust_img.shape[-1]) maxcoords = np.zeros((clust_img.shape[-1], 3)) # iterate through clusters and get info for n, cluster in enumerate(image.iter_img(clust_img)): cluster = np.abs(cluster.get_data()) clust_size[n] = np.sum(cluster != 0) maxcoords[n] = center_of_mass(cluster == cluster.max()) # sort peak coordinates by cluster size maxcoords = np.floor(maxcoords)[np.argsort(clust_size)[::-1]] # convert coordinates to MNI space coords = coord_ijk_to_xyz(clust_img.affine, maxcoords) return coords
def plot(self, downsample=1, out_base="."): out_path = os.path.join(out_base, self.subject, self.name, self.task) os.makedirs(out_path, exist_ok=True) raw = nib.load(self.path) M = np.max(raw.get_data()) n = raw.shape[3] mean = nimage.mean_img(raw) xyzcuts = nilplot.find_xyz_cut_coords(mean) xcuts = nilplot.find_cut_slices(mean, "x") ycuts = nilplot.find_cut_slices(mean, "y") zcuts = nilplot.find_cut_slices(mean, "z") del raw nrange = range(0, n, downsample) for i, img in enumerate(nimage.iter_img(self.path)): if i in nrange: nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/orth_epi%0d.png" % (out_path, i), annotate=True, cut_coords=xyzcuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/x_epi%0d.png" % (out_path, i), annotate=True, display_mode="x", cut_coords=xcuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/y_epi%0d.png" % (out_path, i), annotate=True, display_mode="y", cut_coords=ycuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/z_epi%0d.png" % (out_path, i), annotate=True, display_mode="z", cut_coords=zcuts, cmap="gist_heat") slice_names = ["orth_epi", "x_epi", "y_epi", "z_epi"] for slic in slice_names: filenames = ["%s/%s%0d.png" % (out_path, slic, i) for i in nrange] with imageio.get_writer('%s/%s.gif' % (out_path, slic), mode='I') as writer: for i, filename in zip(nrange, filenames): image = Image.open(filename) draw = ImageDraw.Draw(image) fnt = ImageFont.truetype('Pillow/Tests/fonts/FreeMono.ttf', 16) draw.text((2, 2), str(i), font=fnt, fill=(255, 0, 0, 255)) image.save(filename, "PNG") image = imageio.imread(filename) writer.append_data(image)
def load_vols(niimgs): """Loads a nifti image (or a bail of) into a list qof 3D volumes. Parameters ---------- niimgs: 3 or 4D Niimg-like object If niimgs is an iterable, checks if data is really 4D. Then, considering that it is a list of niimg and load them one by one. If niimg is a string, consider it as a path to Nifti image and call nibabel.load on it. If it is an object, check if get_data and get_affine methods are present, raise an Exception otherwise. Returns ------- niimgs_: list of nifti image objects The loaded volumes. """ # try loading 4d try: niimgs = list(check_niimg_4d(niimgs, return_iterator=True)) except TypeError: # probably not 4d niimgs = [check_niimg(niimgs)] except ValueError: # probably inconsisten affines pass try: # try loading volumes one-by-one if isinstance(niimgs, _basestring): niimgs = [niimgs] return [check_niimg(niimg, ensure_ndim=3) for niimg in niimgs] except TypeError: pass # collect the loaded volumes into a list if is_niimg(niimgs): # should be 3d, squash 4th dimension otherwise if niimgs.shape[-1] == 1: return [nibabel.Nifti1Image(niimgs.get_data()[:, :, :, 0], niimgs.get_affine())] else: return list(iter_img(niimgs)) else: niimgs = list(niimgs) if len(niimgs) == 1: niimgs = niimgs[0] return list(iter_img(niimgs))
def _process_inputs(self): """ validate and process inputs into useful form. Returns a list of nilearn maskers and the list of corresponding label names.""" import nilearn.input_data as nl import nilearn.image as nli label_data = nli.concat_imgs(self.inputs.label_files) maskers = [] # determine form of label files, choose appropriate nilearn masker if np.amax(label_data.dataobj) > 1: # 3d label file n_labels = np.amax(label_data.dataobj) maskers.append(nl.NiftiLabelsMasker(label_data)) else: # 4d labels n_labels = label_data.shape[3] if self.inputs.incl_shared_variance: # independent computation for img in nli.iter_img(label_data): maskers.append( nl.NiftiMapsMasker(self._4d(img.dataobj, img.affine)) ) else: # one computation fitting all maskers.append(nl.NiftiMapsMasker(label_data)) # check label list size if not np.isclose(int(n_labels), n_labels): raise ValueError( "The label files {} contain invalid value {}. Check input.".format( self.inputs.label_files, n_labels ) ) if len(self.inputs.class_labels) != n_labels: raise ValueError( "The length of class_labels {} does not " "match the number of regions {} found in " "label_files {}".format( self.inputs.class_labels, n_labels, self.inputs.label_files ) ) if self.inputs.include_global: global_label_data = label_data.dataobj.sum(axis=3) # sum across all regions global_label_data = ( np.rint(global_label_data).astype(int).clip(0, 1) ) # binarize global_label_data = self._4d(global_label_data, label_data.affine) global_masker = nl.NiftiLabelsMasker( global_label_data, detrend=self.inputs.detrend ) maskers.insert(0, global_masker) self.inputs.class_labels.insert(0, "GlobalSignal") for masker in maskers: masker.set_params(detrend=self.inputs.detrend) return maskers
def _filter_ic_imgs(self, ic_file): if self.zscore > 0: do_zscore = True else: do_zscore = False mask = niimg.load_img(self.mask_file) return [filter_icc(icimg, mask=mask, thr=self.zscore, zscore=do_zscore, mode=self.mode) for icimg in iter_img(ic_file)]
def plot_icmaps(self, outtype='png', **kwargs): """ Plot the thresholded IC spatial maps and store the outputs in the ICA results folder. Parameters ---------- outtype: str Extension (without the '.') of the output files, will specify which plot image file you want. Returns ------- all_icc_plot_f: str iccs_plot_f: str sliced_ic_plots: list of str """ # specify the file paths all_icc_plot_f = op.join( self.ica_dir, 'all_components_zscore_{}.{}'.format(self.zscore, outtype)) iccs_plot_f = op.join( self.ica_dir, 'ic_components_zscore_{}.{}'.format(self.zscore, outtype)) icc_multi_slice = op.join(self.ica_dir, 'ic_map_{}_zscore_{}.{}') # make the plots fig1 = plot_ica_components(self._icc_imgs, **kwargs) fig1.savefig(iccs_plot_f, facecolor=fig1.get_facecolor(), edgecolor='none') fig2 = plot_all_components(self._icc_imgs, **kwargs) fig2.savefig(all_icc_plot_f, facecolor=fig2.get_facecolor(), edgecolor='none') # make the multi sliced IC plots sliced_ic_plots = [] for i, img in enumerate(iter_img(self._icc_imgs)): fig3 = plot_multi_slices(img, cut_dir="z", n_cuts=24, n_cols=4, title="IC {}\n(z-score {})".format( i + 1, self.zscore), title_fontsize=32, plot_func=None, **kwargs) # prepare the output file name/path out_f = icc_multi_slice.format(i + 1, self.zscore, outtype) fig3.savefig(out_f, facecolor=fig3.get_facecolor(), edgecolor='none') sliced_ic_plots.append(out_f) return all_icc_plot_f, iccs_plot_f, sliced_ic_plots
def _save_results(annotated_names, maps_img, dimension): maps_img = nibabel.load(maps_img) for i, img in enumerate(image.iter_img(maps_img)): cut_coords = plotting.find_xyz_cut_coords(img) if annotated_names is not None: annotated_name = annotated_names.iloc[i].Difumo_names else: annotated_name = None _plot_dl_maps(img, cut_coords, annotated_name, i, dimension) return
def generate_ss(modDir, ssDir, cases, ncpu): # reorder both skeleton/* and warped/* according to caseId warpedImgs= glob(pjoin(modDir, 'warped', '*_to_target.nii.gz')) skelImgs= glob(pjoin(modDir, 'skeleton', '*_to_target_skel.nii.gz')) warpedImgs= orderCases(warpedImgs, cases) skelImgs= orderCases(skelImgs, cases) makeDirectory(ssDir) pool= Pool(ncpu) for fg,bg,c in zip(image.iter_img(skelImgs), image.iter_img(warpedImgs), cases): print('Taking screen shot of ', c) output_file = pjoin(ssDir, f'{c}.png') pool.apply_async(func= plotting.plot_stat_map, args= (fg, ), kwds= {'bg_img':bg, 'dim':False, 'annotate':False, 'draw_cross':False, 'output_file':output_file, }) pool.close() pool.join()
def get_image(self): image_path = self.update_image_path() # update image path to make sure get correct image if self.image_info is not None: img = nib.load(image_path) if len(img.shape) == 3: print("3D") return [img] else: print("4D") return list(image.iter_img(img))
def _run_interface(self, runtime): ext = '.nii.gz' if self.inputs.compress else '.nii' self._results['out_files'] = [] out_pattern = fname_presuffix(self.inputs.in_file, suffix='_%05d' + ext, newpath=runtime.cwd, use_ext=False) for i, im in enumerate(iter_img(nb.load(self.inputs.in_file))): out_file = out_pattern % i im.to_filename(out_file) self._results['out_files'].append(out_file) return runtime
def run_mini_pipeline(): atlas = datasets.fetch_atlas_msdl() atlas_img = atlas['maps'] labels = pd.read_csv(atlas['labels'])['name'] masker = NiftiMapsMasker(maps_img=atlas_img, standardize=True, memory='/tmp/nilearn', verbose=0) data = datasets.fetch_adhd(number_subjects) figures_folder = '../figures/' count=0 for func_file, confound_file in zip(data.func, data.confounds): # fit the data to the atlas mask, regress out confounds time_series = masker.fit_transform(func_file, confounds=confound_file) correlation = np.corrcoef(time_series.T) #plotting starts here plt.figure(figsize=(10, 10)) plt.imshow(correlation, interpolation="nearest") x_ticks = plt.xticks(range(len(labels)), labels, rotation=90) y_ticks = plt.yticks(range(len(labels)), labels) corr_file = figures_folder+'subject_number_' + str(count) + '_correlation.pdf' plt.savefig(corr_file) atlas_region_coords = [plotting.find_xyz_cut_coords(img) for img in image.iter_img(atlas_img)] threshold = 0.6 plotting.plot_connectome(correlation, atlas_region_coords, edge_threshold=threshold) connectome_file = figures_folder+'subject_number_' + str(count) + '_connectome.pdf' plt.savefig(connectome_file) #graph setup #binarize correlation matrix correlation[correlation<threshold] = 0 correlation[correlation != 0] = 1 graph = nx.from_numpy_matrix(correlation) partition=louvain.best_partition(graph) values = [partition.get(node) for node in graph.nodes()] plt.figure() nx.draw_spring(graph, cmap = plt.get_cmap('jet'), node_color = values, node_size=30, with_labels=True) graph_file = figures_folder+'subject_number_' + str(count) + '_community.pdf' plt.savefig(graph_file) count += 1 plt.close('all')
def _process_inputs(self): ''' validate and process inputs into useful form. Returns a list of nilearn maskers and the list of corresponding label names.''' import nilearn.input_data as nl import nilearn.image as nli label_data = nli.concat_imgs(self.inputs.label_files) maskers = [] # determine form of label files, choose appropriate nilearn masker if np.amax(label_data.get_data()) > 1: # 3d label file n_labels = np.amax(label_data.get_data()) maskers.append(nl.NiftiLabelsMasker(label_data)) else: # 4d labels n_labels = label_data.get_data().shape[3] if self.inputs.incl_shared_variance: # independent computation for img in nli.iter_img(label_data): maskers.append( nl.NiftiMapsMasker( self._4d(img.get_data(), img.affine))) else: # one computation fitting all maskers.append(nl.NiftiMapsMasker(label_data)) # check label list size if not np.isclose(int(n_labels), n_labels): raise ValueError( 'The label files {} contain invalid value {}. Check input.' .format(self.inputs.label_files, n_labels)) if len(self.inputs.class_labels) != n_labels: raise ValueError('The length of class_labels {} does not ' 'match the number of regions {} found in ' 'label_files {}'.format(self.inputs.class_labels, n_labels, self.inputs.label_files)) if self.inputs.include_global: global_label_data = label_data.get_data().sum( axis=3) # sum across all regions global_label_data = np.rint(global_label_data).astype(int).clip( 0, 1) # binarize global_label_data = self._4d(global_label_data, label_data.affine) global_masker = nl.NiftiLabelsMasker( global_label_data, detrend=self.inputs.detrend) maskers.insert(0, global_masker) self.inputs.class_labels.insert(0, 'GlobalSignal') for masker in maskers: masker.set_params(detrend=self.inputs.detrend) return maskers
def _calculate_nmse(self, original_nii, corrected_nii): """Calculate NMSE from the applied preprocessing operation.""" outputs = self._list_outputs() output_file = outputs.get('nmse_text') pres = [] posts = [] differences = [] for orig_img, corrected_img in zip(iter_img(original_nii), iter_img(corrected_nii)): orig_data = orig_img.get_fdata() corrected_data = corrected_img.get_fdata() baseline = orig_data.mean() pres.append(baseline) posts.append(corrected_data.mean()) scaled_diff = np.abs(corrected_data - orig_data).mean() / baseline differences.append(scaled_diff) title = str(self.__class__)[:-2].split('.')[-1] pd.DataFrame({ title + "_pre": pres, title + "_post": posts, title + "_change": differences }).to_csv(output_file, index=False)
def save_info(info, dimension): """Save found records Parameters ---------- info : dict Contains meta-data assigned to each atlas name such as overlap proportion, etc Each atlas dict contains following attributes: 'intersection' : sparse matrix dot product between DiFuMo regions and regions in target atlas (existing pre-defined) 'target_size' : np.ndarray Size of each region estimated in target atlas 'overlap_proportion' : list of pd.Series Each list contains the proportion of overlap estimated between this region and all region in target sizes. Sorted according to most strong hit in the overlap. 'overlap_size' : list Each list contain overlap in estimated sizes for all regions in target atlas. dimension : int DiFuMo atlas dimension Returns ------- data : pd.DataFrame """ html = "https://parietal-inria.github.io/DiFuMo/{0}/html/{1}.html" table = set_difumo_storage() maps_img = nibabel.load(fetch_difumo(dimension=dimension).maps) for i, img in enumerate(image.iter_img(maps_img)): cut_coords = plotting.find_xyz_cut_coords(img) for n in [64, 128, 256, 512, 1024]: labels = fetch_difumo(dimension=n).labels['Difumo_names'].to_list() # Proportion of overlap with each index of difumo component this_img_info = info[n]['overlap_proportion'][i] identified_components = this_img_info.index[1:6] if len(identified_components) != 0: # grabbing the top five from the overlapped list for identified_component in identified_components: table['dimension'].append(dimension) table['component'].append(i + 1) table['overlap_against'].append(n) table['identified'].append(identified_component + 1) table['label'].append(labels[identified_component]) return pd.DataFrame(table)
def test_threshold_img(): # to check whether passes with valid threshold inputs shape = (10, 20, 30) maps, _ = testing.generate_maps(shape, n_regions=4) affine = np.eye(4) mask_img = nibabel.Nifti1Image(np.ones((shape), dtype=np.int8), affine) for img in iter_img(maps): # when threshold is a float value thr_maps_img = threshold_img(img, threshold=0.8) # when we provide mask image thr_maps_percent = threshold_img(img, threshold=1, mask_img=mask_img) # when threshold is a percentile thr_maps_percent2 = threshold_img(img, threshold='2%')
def test_threshold_img(): # to check whether passes with valid threshold inputs shape = (10, 20, 30) maps, _ = data_gen.generate_maps(shape, n_regions=4) affine = np.eye(4) mask_img = nibabel.Nifti1Image(np.ones((shape), dtype=np.int8), affine) for img in iter_img(maps): # when threshold is a float value thr_maps_img = threshold_img(img, threshold=0.8) # when we provide mask image thr_maps_percent = threshold_img(img, threshold=1, mask_img=mask_img) # when threshold is a percentile thr_maps_percent2 = threshold_img(img, threshold='2%')
def split_4d(in_file, out_dir): """ Split 4D file into 3D files in out_dir """ img_4d = nib.load(in_file) if not op.isdir(out_dir): mkdir(out_dir) out_files = [] for i, img_3d in enumerate(image.iter_img(img_4d)): out_file = op.join(out_dir, 'f{0:05d}.nii.gz'.format(i)) img_3d.to_filename(out_file) out_files.append(out_file) return out_files
def plot_ica_components(components_img, **kwargs): """ Plot the components IC spatial maps in a grid.""" import math from nilearn.image import iter_img from nilearn.plotting import plot_stat_map from matplotlib import pyplot as plt from matplotlib import gridspec n_ics = len(list(iter_img(components_img))) n_rows = math.ceil(n_ics/2) fig = plt.figure(figsize=(6, 3*n_rows), facecolor='black') gs = gridspec.GridSpec(n_rows, 2) plots = [] for i, ic_img in enumerate(iter_img(components_img)): ax = plt.subplot(gs[i]) p = plot_stat_map(ic_img, display_mode="z", title="IC {}".format(i+1), cut_coords=1, colorbar=False, figure=fig, axes=ax, **kwargs) plots.append(p) for p in plots: p.close() return fig
def test_component_sign(): # Regression test # We should have a heuristic that flips the sign of components in # DictLearning to have more positive values than negative values, for # instance by making sure that the largest value is positive. data, mask_img, components, rng = _make_canica_test_data(n_subjects=2, noisy=True) for mp in components: assert_less_equal(-mp.min(), mp.max()) dict_learning = DictLearning(n_components=4, random_state=rng, mask=mask_img, smoothing_fwhm=0.0, alpha=1) dict_learning.fit(data) for mp in iter_img(dict_learning.masker_.inverse_transform(dict_learning.components_)): mp = mp.get_data() assert_less_equal(np.sum(mp[mp <= 0]), np.sum(mp[mp > 0]))
def test_component_sign(): # We should have a heuristic that flips the sign of components in # CanICA to have more positive values than negative values, for # instance by making sure that the largest value is positive. data, mask_img, components, rng = _make_canica_test_data(n_subjects=2, noisy=True) # run CanICA many times (this is known to produce different results) canica = CanICA(n_components=4, random_state=rng, mask=mask_img) for _ in range(3): canica.fit(data) for mp in iter_img(canica.components_img_): mp = get_data(mp) assert_less_equal(-mp.min(), mp.max())
def test_component_sign(): # We should have a heuristic that flips the sign of components in # CanICA to have more positive values than negative values, for # instance by making sure that the largest value is positive. data, mask_img, components, rng = _make_canica_test_data(n_subjects=2, noisy=True) # run CanICA many times (this is known to produce different results) canica = CanICA(n_components=4, random_state=rng, mask=mask_img) for _ in range(3): canica.fit(data) for mp in iter_img(canica.components_img_): mp = mp.get_data() assert_less_equal(-mp.min(), mp.max())
def get_largest_blobs(ic_maps): """ Generator for the largest blobs in each IC spatial map. These should be masked and thresholded. Parameters ---------- ic_maps: sequence of niimg-like Returns ------- blobs: generator of niimg-like """ # store the average value of the blob in a list for i, icimg in enumerate(iter_img(ic_maps)): yield niimg.new_img_like(icimg, largest_connected_component(icimg.get_data()))
def test_component_sign(): # Regression test # We should have a heuristic that flips the sign of pipelining in # DictLearning to have more positive values than negative values, for # instance by making sure that the largest value is positive. data, mask_img, components, init = _make_test_data(n_subjects=2, noisy=True) dict_fact = fMRIDictFact(n_components=4, random_state=0, mask=mask_img, smoothing_fwhm=0.) dict_fact.fit(data) for mp in iter_img(dict_fact.components_img_): mp = mp.get_data() assert(np.sum(mp[mp <= 0]) <= np.sum(mp[mp > 0]))
def plot_pro(self, ita, save=False, item_file='group', name='vmf', choose=None, cut_coords=None): for component in ita: if component.max() < -component.min(): component *= -1 if hasattr(self, "masker_"): self.components_img_ = self.masker_.inverse_transform(ita) components_img = self.components_img_ warnings.filterwarnings("ignore") display = plot_prob_atlas(components_img, title='All components', view_type='filled_contours') if save: display.savefig('{}/brain/{}/{}/pro.png'.format( RESULT_DIR, name, item_file), dpi=200) for i, cur_img in enumerate(iter_img(components_img)): if cut_coords is not None: display = plot_stat_map(cur_img, cut_coords=cut_coords[i], dim=-.5, threshold=1e-3, cmap=plt.get_cmap('autumn')) else: display = plot_stat_map(cur_img, dim=-.5, threshold=1e-3, cmap=plt.get_cmap('autumn')) if save: if choose is not None: display.savefig('{}/brain/{}/{}/item{}.png'.format( RESULT_DIR, name, item_file, choose[i] + 1), dpi=200) else: display.savefig('{}/brain/{}/{}/item{}.png'.format( RESULT_DIR, name, item_file, i + 1), dpi=200) if save is False: show()
def plot_icmaps(self, outtype='png', **kwargs): """ Plot the thresholded IC spatial maps and store the outputs in the ICA results folder. Parameters ---------- outtype: str Extension (without the '.') of the output files, will specify which plot image file you want. Returns ------- all_icc_plot_f: str iccs_plot_f: str sliced_ic_plots: list of str """ # specify the file paths all_icc_plot_f = op.join(self.ica_dir, 'all_components_zscore_{}.{}'.format(self.zscore, outtype)) iccs_plot_f = op.join(self.ica_dir, 'ic_components_zscore_{}.{}'.format(self.zscore, outtype)) icc_multi_slice = op.join(self.ica_dir, 'ic_map_{}_zscore_{}.{}') # make the plots fig1 = plot_ica_components(self._icc_imgs, **kwargs) fig1.savefig(iccs_plot_f, facecolor=fig1.get_facecolor(), edgecolor='none') fig2 = plot_all_components(self._icc_imgs, **kwargs) fig2.savefig(all_icc_plot_f, facecolor=fig2.get_facecolor(), edgecolor='none') # make the multi sliced IC plots sliced_ic_plots = [] for i, img in enumerate(iter_img(self._icc_imgs)): fig3 = plot_multi_slices(img, cut_dir="z", n_cuts=24, n_cols=4, title="IC {}\n(z-score {})".format(i+1, self.zscore), title_fontsize=32, plot_func=None, **kwargs) # prepare the output file name/path out_f = icc_multi_slice.format(i+1, self.zscore, outtype) fig3.savefig(out_f, facecolor=fig3.get_facecolor(), edgecolor='none') sliced_ic_plots.append(out_f) return all_icc_plot_f, iccs_plot_f, sliced_ic_plots
def test_iterator_generator(): # Create a list of random images l = [Nifti1Image(np.random.random((10, 10, 10)), np.eye(4)) for i in range(10)] cc = _utils.concat_niimgs(l) assert_equal(cc.shape[-1], 10) assert_array_almost_equal(cc.get_data()[..., 0], l[0].get_data()) # Same with iteration i = image.iter_img(l) cc = _utils.concat_niimgs(i) assert_equal(cc.shape[-1], 10) assert_array_almost_equal(cc.get_data()[..., 0], l[0].get_data()) # Now, a generator b = [] g = nifti_generator(b) cc = _utils.concat_niimgs(g) assert_equal(cc.shape[-1], 10) assert_equal(len(b), 10)
def split_bilateral_rois(maps_img): """Convenience function for splitting bilateral ROIs into two unilateral ROIs""" new_rois = [] for map_img in iter_img(maps_img): for hemi in ["L", "R"]: hemi_mask = HemisphereMasker(hemisphere=hemi) hemi_mask.fit(map_img) if hemi_mask.mask_img_.get_data().sum() > 0: hemi_vectors = hemi_mask.transform(map_img) hemi_img = hemi_mask.inverse_transform(hemi_vectors) new_rois.append(hemi_img.get_data()) new_maps_data = np.concatenate(new_rois, axis=3) new_maps_img = new_img_like(maps_img, data=new_maps_data, copy_header=True) print("Changed from %d ROIs to %d ROIs" % (maps_img.shape[-1], new_maps_img.shape[-1])) return new_maps_img
def plot_components(ica_image, hemi='', out_dir=None, bg_img=datasets.load_mni152_template()): print("Plotting %s components..." % hemi) # Determine threshoold and vmax for all the plots # get nonzero part of the image for proper thresholding of # r- or l- only component nonzero_img = ica_image.get_data()[np.nonzero(ica_image.get_data())] thr = stats.scoreatpercentile(np.abs(nonzero_img), 90) vmax = stats.scoreatpercentile(np.abs(nonzero_img), 99.99) for ci, ic_img in enumerate(iter_img(ica_image)): title = _title_from_terms(terms=ica_image.terms, ic_idx=ci, label=hemi) fh = plt.figure(figsize=(14, 6)) plot_stat_map(ic_img, axes=fh.gca(), threshold=thr, vmax=vmax, colorbar=True, title=title, black_bg=True, bg_img=bg_img) # Save images instead of displaying if out_dir is not None: save_and_close(out_path=op.join( out_dir, '%s_component_%i.png' % (hemi, ci)))
def plot_components_summary(ica_image, hemi='', out_dir=None, bg_img=datasets.load_mni152_template()): print("Plotting %s components summary..." % hemi) n_components = ica_image.get_data().shape[3] # Determine threshoold and vmax for all the plots # get nonzero part of the image for proper thresholding of # r- or l- only component nonzero_img = ica_image.get_data()[np.nonzero(ica_image.get_data())] thr = stats.scoreatpercentile(np.abs(nonzero_img), 90) vmax = stats.scoreatpercentile(np.abs(nonzero_img), 99.99) for ii, ic_img in enumerate(iter_img(ica_image)): ri = ii % 5 # row i ci = (ii / 5) % 5 # column i pi = ii % 25 + 1 # plot i fi = ii / 25 # figure i if ri == 0 and ci == 0: fh = plt.figure(figsize=(30, 20)) print('Plot %03d of %d' % (fi + 1, np.ceil(n_components / 25.))) ax = fh.add_subplot(5, 5, pi) title = _title_from_terms(terms=ica_image.terms, ic_idx=ii, label=hemi) colorbar = ci == 4 plot_stat_map( ic_img, axes=ax, threshold=thr, vmax=vmax, colorbar=colorbar, title=title, black_bg=True, bg_img=bg_img) if (ri == 4 and ci == 4) or ii == n_components - 1: out_path = op.join( out_dir, '%s_components_summary%02d.png' % (hemi, fi + 1)) save_and_close(out_path)
# first_rsn is a 3D image. # # We can then plot it plotting.plot_stat_map(first_rsn) ############################################################################### # Looping on all volumes in a 4D file # ----------------------------------- # # If we want to plot all the volumes in this 4D file, we can use iter_img # to loop on them. # # Then we give a few arguments to plot_stat_map in order to have a more # compact display. for img in image.iter_img(rsn): # img is now an in-memory 3D img plotting.plot_stat_map(img, threshold=3, display_mode="z", cut_coords=1, colorbar=False) ############################################################################### # plotting.show is useful to force the display of figures when running # outside IPython plotting.show() ######################################################################### # | # # ______ #
def _apply_mask_to_4dimg(self, imgs, **kwargs): masker = NiftiMasker(mask_img=self.load_mask(), **kwargs) return (masker.fit_transform(img) for img in iter_img(imgs))
correlation = connectome_measure.fit_transform([timeseries_each_subject]) # saving each subject correlation to correlations correlations.append(correlation) # Mean of all correlations import numpy as np mean_correlations = np.mean(correlations, axis=0).reshape(n_regions_extracted, n_regions_extracted) ############################################################################### # Plot resulting connectomes # ---------------------------- import matplotlib.pyplot as plt from nilearn import image regions_imgs = image.iter_img(regions_extracted_img) coords_connectome = [plotting.find_xyz_cut_coords(img) for img in regions_imgs] title = 'Correlation interactions between %d regions' % n_regions_extracted plt.figure() plt.imshow(mean_correlations, interpolation="nearest", vmax=1, vmin=-1, cmap=plt.cm.bwr) plt.colorbar() plt.title(title) plotting.plot_connectome(mean_correlations, coords_connectome, edge_threshold='90%', title=title) ################################################################################ # Plot regions extracted for only one specific network # ---------------------------------------------------- # First, we plot a network of index=4 without region extraction (left plot)
#################################################################### # To visualize we plot the outline of all components on one figure from nilearn.plotting import plot_prob_atlas # Plot all ICA components together plot_prob_atlas(canica_components_img, title='All ICA components') #################################################################### # Finally, we plot the map for each ICA component separately from nilearn.image import iter_img from nilearn.plotting import plot_stat_map, show for i, cur_img in enumerate(iter_img(canica_components_img)): plot_stat_map(cur_img, display_mode="z", title="IC %d" % i, cut_coords=1, colorbar=False) #################################################################### # Compare CanICA to dictionary learning # ------------------------------------------------------------- # Dictionary learning is a sparsity based decomposition method for extracting # spatial maps. It extracts maps that are naturally sparse and usually cleaner # than ICA. Here, we will compare networks built with CanICA to networks built # with Dictionary Learning. # # * Arthur Mensch et al. `Compressed online dictionary learning for fast resting-state fMRI decomposition # <https://hal.archives-ouvertes.fr/hal-01271033/>`_, # ISBI 2016, Lecture Notes in Computer Science
rois = labels['name'].T n_r = len(rois) l=360./n_r#roi label size in figures visu = atlas_filename all_ntwks = range(n_r) networks = {'Auditory': [0,1],'striate' : [2],'DMN': [3,4,5,6],'Occ post' :[7], 'Motor': [8],'Attentional' : [9,10,11,12,14,15,16,17,18], 'Basal' : [13],'Visual secondary' : [19,20,21], 'Salience':[22,23,24], 'Temporal(STS)':[25,26],'Langage':[27,28,29,30,31],'Cereb':[32], 'Dors PCC': [33],'cing ins' :[34,35,36],'Ant IPS': [37,38],'All ROIs':all_ntwks} coords = [] #chose regions representative coordinates, other wise it s computed with find_xyz_cut_coords #coords = np.vstack((labels['x'], labels['y'], labels['z'])).T if not coords: coords =[plotting.find_xyz_cut_coords(roi) for roi in image.iter_img(atlas_filename)] root='/neurospin/grip/protocols/MRI/AVCnn_Dhaif_2016/AVCnn/AVCnn_data/' #fichier reg et conca pret pour analyse func_type_list = [ 'controlRSc','patientsRSc_LD', 'patientsRSc_LG']# #name of each group's directory for functional images reg_dirs = [ root+'rgt']#name of each group's directory for regressors (regressor have to be .txt files) reg_prefix = 'art_mv_fmv_wm_vent_ext_hv_' #art_mv_fmv_wm_vent_ext_hv_regressor prefix (regressors must have corresponding functional file name after prefix: swars_ab_123456.nii and reg1_reg2_swars_ab_123456.txt) common = 4 #initial differing character between regressors and functional file names #choose report directory and name (default location is in root, default name is atlas_naabsolute main_title ='AVCnn_Cont_LG_LD_'+MC_correction # save_dir = root + 'reports_test/' try: os.makedirs(save_dir) except: print('Warning could not make dir '+save_dir) pass
def spatclust(img, min_cluster_size, threshold=None, index=None, mask=None): """ Spatially clusters `img` Parameters ---------- img : str or img_like Image file or object to be clustered min_cluster_size : int Minimum cluster size (in voxels) threshold : float, optional Whether to threshold `img` before clustering index : array_like, optional Whether to extract volumes from `img` for clustering mask : (S,) array_like, optional Boolean array for masking resultant data array Returns ------- clustered : :obj:`numpy.ndarray` Boolean array of clustered (and thresholded) `img` data """ # we need a 4D image for `niimg.iter_img`, below img = niimg.copy_img(check_niimg(img, atleast_4d=True)) # temporarily set voxel sizes to 1mm isotropic so that `min_cluster_size` # represents the minimum number of voxels we want to be in a cluster, # rather than the minimum size of the desired clusters in mm^3 if not np.all(np.abs(np.diag(img.affine)) == 1): img.set_sform(np.sign(img.affine)) # grab desired volumes from provided image if index is not None: if not isinstance(index, list): index = [index] img = niimg.index_img(img, index) # threshold image if threshold is not None: img = niimg.threshold_img(img, float(threshold)) clout = [] for subbrick in niimg.iter_img(img): # `min_region_size` is not inclusive (as in AFNI's `3dmerge`) # subtract one voxel to ensure we aren't hitting this thresholding issue try: clsts = connected_regions(subbrick, min_region_size=int(min_cluster_size) - 1, smoothing_fwhm=None, extract_type='connected_components')[0] # if no clusters are detected we get a TypeError; create a blank 4D # image object as a placeholder instead except TypeError: clsts = niimg.new_img_like(subbrick, np.zeros(subbrick.shape + (1,))) # if multiple clusters detected, collapse into one volume clout += [niimg.math_img('np.sum(a, axis=-1)', a=clsts)] # convert back to data array and make boolean clustered = utils.load_image(niimg.concat_imgs(clout).get_data()) != 0 # if mask provided, mask output if mask is not None: clustered = clustered[mask] return clustered
def plot_all(self): names = self.network_names for idx, rsn in enumerate(niimg.iter_img(self._img)): disp = niplot.plot_roi(rsn, title=names.get(idx, None))
def compare_components(images, labels, scoring="correlation", flip=True, memory=Memory(cachedir="nilearn_cache")): assert len(images) == 2 assert len(labels) == 2 assert images[0].shape == images[1].shape n_components = images[0].shape[3] # values @ 0 and 1 are the same labels = [l.upper() for l in labels] # make input labels case insensitive print("Loading images.") for img in images: img.get_data() # Just loaded to get them in memory.. print("Scoring closest components (by %s)" % str(scoring)) score_mat = np.zeros((n_components, n_components)) sign_mat = np.zeros((n_components, n_components), dtype=np.int) c1_data = [None] * n_components c2_data = [None] * n_components c1_images = list(iter_img(images[0])) c2_images = list(iter_img(images[1])) lh_masker = HemisphereMasker(hemisphere="L", memory=memory).fit() rh_masker = HemisphereMasker(hemisphere="R", memory=memory).fit() for c1i, comp1 in enumerate(c1_images): for c2i, comp2 in enumerate(c2_images): # Make sure the two images align (i.e. not R and L opposite), # and that only good voxels are compared (i.e. not full vs half) if "R" in labels and "L" in labels: if c1_data[c1i] is None or c2_data[c2i] is None: R_img = comp1 if labels.index("R") == 0 else comp2 # noqa L_img = comp1 if labels.index("L") == 0 else comp2 # noqa masker = lh_masker # use same masker; ensures same size if c1_data[c1i] is None: c1_data[c1i] = masker.transform(flip_img_lr(R_img)).ravel() if c2_data[c2i] is None: c2_data[c2i] = masker.transform(L_img).ravel() elif "R" in labels or "L" in labels: masker = rh_masker if "R" in labels else lh_masker if c1_data[c1i] is None: c1_data[c1i] = masker.transform(comp1).ravel() if c2_data[c2i] is None: c2_data[c2i] = masker.transform(comp2).ravel() else: if c1_data[c1i] is None: c1_data[c1i] = comp1.get_data().ravel() if c2_data[c2i] is None: c2_data[c2i] = comp2.get_data().ravel() # Choose a scoring system. # Score should indicate DISSIMILARITY # Component sign is meaningless, so try both unless flip = False, # and keep track of comparisons that had better score when flipping the sign score = np.inf if flip: signs = [1, -1] else: signs = [1] for sign in signs: c1d, c2d = c1_data[c1i], sign * c2_data[c2i] if not isinstance(scoring, string_types): # function sc = scoring(c1d, c2d) elif scoring == "l1norm": sc = np.linalg.norm(c1d - c2d, ord=1) elif scoring == "l2norm": sc = np.linalg.norm(c1d - c2d, ord=2) elif scoring == "correlation": sc = 1 - stats.stats.pearsonr(c1d, c2d)[0] else: raise NotImplementedError(scoring) if sc < score: sign_mat[c1i, c2i] = sign score = min(score, sc) score_mat[c1i, c2i] = score return score_mat, sign_mat
confound_filename = adhd_dataset.confounds[0] # Computing some confounds hv_confounds = mem.cache(nilearn.image.high_variance_confounds)( fmri_filename) time_series = masker.transform(fmri_filename, confounds=[hv_confounds, confound_filename]) print("-- Computing graph-lasso inverse matrix ...") from sklearn import covariance gl = covariance.GraphLassoCV(verbose=2) gl.fit(time_series) # Displaying results ########################################################## atlas_imgs = image.iter_img(msdl_atlas_dataset.maps) atlas_region_coords = [plotting.find_xyz_cut_coords(img) for img in atlas_imgs] title = "GraphLasso" plotting.plot_connectome(-gl.precision_, atlas_region_coords, edge_threshold='90%', title="Sparse inverse covariance") plotting.plot_connectome(gl.covariance_, atlas_region_coords, edge_threshold='90%', title="Covariance") plot_matrices(gl.covariance_, gl.precision_, title) plt.show()
def spatial_maps_goodness_of_fit(rsn_imgs, spatial_maps, mask_file, rsn_thr=4.0): """ Goodness-of-fit values described as in Zhou et al., 2010, Brain. Parameters ---------- rsn_imgs: list of niimg-like or 4D niimg-like The RSN maps. They should be thresholded beforehand if `rsn_thr` is lower or equal than 0. spatial_maps: list of niimg-like or 4D niimg-like mask_file: niimg-like An extra mask to apply to the thresholded RSN masks. This is used to exclude values outside of the RSN blobs. It is recommended to use a brain mask for this. rsn_thr: float, optional The threshold to apply to `rsn_imgs` to create the RSN masks. If rsn_thr <= 0, no thresholding will be applied. Returns ------- gof_df: np.ndarray A matrix of shape MxN, where M is len(rsn_imgs) and N is len(spatial_maps). It contains the goodness-of-fit values. Notes ----- "These ICN templates were thresholded at a z-score 4.0 to be visually comparable to the consistent ICNs published by Damoiseaux et al. (2006). A minor modification of previous goodness-of-fit methods (Seeley et al., 2007b, 2009) was included here for template matching, with goodness-of-fit scores calculated by multiplying (i) the average z-score difference between voxels falling within the template and voxels falling outside the template; and (ii) the difference in the percentage of positive z-score voxels inside and outside the template. This goodness-of-fit algorithm proves less vulnerable to inter-subject variability in shape, size, location and strength of each ICN", than the one published in Seeley et al., 2007b. This latter method only uses the value in (i). Extracted from Zhou et al., 2010, Brain. """ rsn_img = niimg.load_img(rsn_imgs) spm_img = niimg.load_img(spatial_maps) n_rsns = rsn_img.shape[-1] n_ics = spm_img.shape[-1] gofs = np.zeros((n_rsns, n_ics), dtype=float) # threshold the RSN templates if rsn_thr > 0: thr_rsns = (spatial_map(rsn, thr=rsn_thr, mode='+-') for rsn in niimg.iter_img(rsn_img)) else: thr_rsns = rsn_img # for each RSN template and IC image iter_rsn_ic = itertools.product(enumerate(niimg.iter_img(thr_rsns)), enumerate(niimg.iter_img( spm_img))) for (rsn_idx, rsn), (ic_idx, ic) in iter_rsn_ic: ref_vol = rsn.get_data() rsn_vol = np.zeros(rsn.shape, dtype=int) #rsn_in = niimg.math_img('np.abs(img) > 0', img=rsn) rsn_in = rsn_vol.copy() rsn_in[np.abs(ref_vol) > 0] = 1 #rsn_out = niimg.math_img('img == 0', img=rsn) rsn_out = rsn_vol.copy() rsn_out[ref_vol == 0] = 1 if mask_file is not None: # rsn_out = niimg.math_img('mask * img', mask=rsn_brain_mask, img=rsn_out) rsn_brain_mask = niimg.resample_to_img(mask_file, rsn, interpolation='nearest') rsn_out = rsn_brain_mask.get_data() * rsn_out # convert the mask arrays to image in order to resample rsn_in = niimg.new_img_like(rsn, rsn_in) rsn_out = niimg.new_img_like(rsn, rsn_out) rsn_in = niimg.resample_to_img(rsn_in, ic, interpolation='nearest') rsn_out = niimg.resample_to_img(rsn_out, ic, interpolation='nearest') # apply the mask #zscore_in = niimg.math_img('mask * img', mask=rsn_in, img=ic).get_data() zscore_in = rsn_in.get_data() * ic.get_data() #zscore_out = niimg.math_img('mask * img', mask=rsn_out, img=ic).get_data() zscore_out = rsn_out.get_data() * ic.get_data() #gof_term1 # calculate the the average z-score difference between voxels falling # within the template and voxels falling outside the template gof_term1 = zscore_in.mean() - zscore_out.mean() #gof_term2 # the difference in the percentage of positive z-score voxels inside and outside the template. n_pos_zscore_in = np.sum(zscore_in > 0) n_pos_zscore_out = np.sum(zscore_out > 0) n_pos_zscore_tot = n_pos_zscore_in + n_pos_zscore_out if n_pos_zscore_tot != 0: n_pos_zscore_pcnt = 100 / n_pos_zscore_tot gof_term2 = (n_pos_zscore_in - n_pos_zscore_out) * n_pos_zscore_pcnt else: gof_term2 = 0 # global gof gof = gof_term1 * gof_term2 # add the result gofs[rsn_idx][ic_idx] = gof return gofs
def spatial_maps_pairwise_similarity(imgs1, imgs2, mask_file, distance='correlation'): """ Similarity values of each image in `imgs1` to each image in `imgs2`, both masked by `mask_file`. These values are based on distance metrics, specified by `distance` argument. The resulting similarity value is the complementary value of the distance, i.e., '1 - <distance value>'. The images in `imgs1` will be resampled to `imgs2` if their affine matrix don't match. Parameters ---------- imgs1: list of niimg-like or 4D niimg-like imgs2: list of niimg-like or 4D niimg-like mask_file: niimg-like distance: str Valid values for `distance` are: From scikit-learn: ['cityblock', 'cosine', 'euclidean', 'l1', 'l2', 'manhattan']. From scipy.spatial.distance: ['braycurtis', 'canberra', 'chebyshev', 'correlation', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'] See the documentation for scipy.spatial.distance for details on these metrics. Returns ------- corrs: np.ndarray A matrix of shape MxN, where M is len(imgs1) and N is len(imgs2). It contains the similarity values. """ img1_ = niimg.load_img(imgs1) img2_ = niimg.load_img(imgs2) n_imgs1 = img1_.shape[-1] n_imgs2 = img2_.shape[-1] corrs = np.zeros((n_imgs1, n_imgs2), dtype=float) mask_trnsf = niimg.resample_to_img(mask_file, niimg.index_img(img2_, 0), interpolation='nearest', copy=True) for idx1, img1 in enumerate(niimg.iter_img(img1_)): img1_resamp = niimg.resample_to_img(img1, niimg.index_img(img2_, 0), copy=True) img1_masked = nimask.apply_mask(img1_resamp, mask_trnsf) for idx2, img2 in enumerate(niimg.iter_img(img2_)): img2_masked = nimask.apply_mask(img2, mask_trnsf) dist = pairwise_distances(img1_masked.reshape(1, -1), img2_masked.reshape(1, -1), metric=distance) # since this is a scalar value dist = dist[0][0] # since this is a distance, not a similarity value corr = 1 - dist # store it corrs[idx1, idx2] = corr return corrs
def plot_melodic_components(melodic_dir, in_file, tr=None, out_file='melodic_reportlet.svg', compress='auto', report_mask=None, noise_components_file=None): """ Plots the spatiotemporal components extracted by FSL MELODIC from functional MRI data. Parameters melodic_dir : str Path pointing to the outputs of MELODIC in_file : str Path pointing to the reference fMRI dataset. This file will be used to extract the TR value, if the ``tr`` argument is not set. This file will be used to calculate a mask if ``report_mask`` is not provided. tr : float Repetition time in seconds out_file : str Path where the resulting SVG file will be stored compress : ``'auto'`` or bool Whether SVG should be compressed. If ``'auto'``, compression will be executed if dependencies are installed (SVGO) report_mask : str Path to a brain mask corresponding to ``in_file`` noise_components_file : str A CSV file listing the indexes of components classified as noise by some manual or automated (e.g. ICA-AROMA) procedure. If a ``noise_components_file`` is provided, then components will be plotted with red/green colors (correspondingly to whether they are in the file -noise components, red-, or not -signal, green-). When all or none of the components are in the file, a warning is printed at the top. """ from nilearn.image import index_img, iter_img import nibabel as nb import numpy as np import pylab as plt import seaborn as sns from matplotlib.gridspec import GridSpec import os import re from io import StringIO sns.set_style("white") current_palette = sns.color_palette() in_nii = nb.load(in_file) if not tr: tr = in_nii.header.get_zooms()[3] units = in_nii.header.get_xyzt_units() if units: if units[-1] == 'msec': tr = tr / 1000.0 elif units[-1] == 'usec': tr = tr / 1000000.0 elif units[-1] != 'sec': NIWORKFLOWS_LOG.warning('Unknown repetition time units ' 'specified - assuming seconds') else: NIWORKFLOWS_LOG.warning( 'Repetition time units not specified - assuming seconds') from nilearn.input_data import NiftiMasker from nilearn.plotting import cm if not report_mask: nifti_masker = NiftiMasker(mask_strategy='epi') nifti_masker.fit(index_img(in_nii, range(2))) mask_img = nifti_masker.mask_img_ else: mask_img = nb.load(report_mask) mask_sl = [] for j in range(3): mask_sl.append(transform_to_2d(mask_img.get_data(), j)) timeseries = np.loadtxt(os.path.join(melodic_dir, "melodic_mix")) power = np.loadtxt(os.path.join(melodic_dir, "melodic_FTmix")) stats = np.loadtxt(os.path.join(melodic_dir, "melodic_ICstats")) n_components = stats.shape[0] Fs = 1.0 / tr Ny = Fs / 2 f = Ny * (np.array(list(range(1, power.shape[0] + 1)))) / (power.shape[0]) # Set default colors color_title = 'k' color_time = current_palette[0] color_power = current_palette[1] classified_colors = None warning_row = 0 # Do not allocate warning row # Only if the components file has been provided, a warning banner will # be issued if all or none of the components were classified as noise if noise_components_file: noise_components = np.loadtxt(noise_components_file, dtype=int, delimiter=',', ndmin=1) # Activate warning row if pertinent warning_row = int(noise_components.size == 0 or noise_components.size == n_components) classified_colors = {True: 'r', False: 'g'} n_rows = int((n_components + (n_components % 2)) / 2) fig = plt.figure(figsize=(6.5 * 1.5, (n_rows + warning_row) * 0.85)) gs = GridSpec(n_rows * 2 + warning_row, 9, width_ratios=[1, 1, 1, 4, 0.001, 1, 1, 1, 4, ], height_ratios=[5] * warning_row + [1.1, 1] * n_rows) if warning_row: ax = fig.add_subplot(gs[0, :]) ncomps = 'NONE of the' if noise_components.size == n_components: ncomps = 'ALL' ax.annotate( 'WARNING: {} components were classified as noise'.format(ncomps), xy=(0.0, 0.5), xycoords='axes fraction', xytext=(0.01, 0.5), textcoords='axes fraction', size=12, color='#ea8800', bbox=dict(boxstyle="round", fc='#f7dcb7', ec='#FC990E')) ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) titlefmt = "C{id:d}{noise}: Tot. var. expl. {var:.2g}%".format for i, img in enumerate( iter_img(os.path.join(melodic_dir, "melodic_IC.nii.gz"))): col = i % 2 row = i // 2 l_row = row * 2 + warning_row is_noise = False if classified_colors: # If a noise components list is provided, assign red/green is_noise = (i + 1) in noise_components color_title = color_time = color_power = classified_colors[is_noise] data = img.get_data() for j in range(3): ax1 = fig.add_subplot(gs[l_row:l_row + 2, j + col * 5]) sl = transform_to_2d(data, j) m = np.abs(sl).max() ax1.imshow(sl, vmin=-m, vmax=+m, cmap=cm.cold_white_hot, interpolation="nearest") ax1.contour(mask_sl[j], levels=[0.5], colors='k', linewidths=0.5) plt.axis("off") ax1.autoscale_view('tight') if j == 0: ax1.set_title( titlefmt(id=i + 1, noise=' [noise]' * is_noise, var=stats[i, 1]), x=0, y=1.18, fontsize=7, horizontalalignment='left', verticalalignment='top', color=color_title) ax2 = fig.add_subplot(gs[l_row, 3 + col * 5]) ax3 = fig.add_subplot(gs[l_row + 1, 3 + col * 5]) ax2.plot(np.arange(len(timeseries[:, i])) * tr, timeseries[:, i], linewidth=min(200 / len(timeseries[:, i]), 1.0), color=color_time) ax2.set_xlim([0, len(timeseries[:, i]) * tr]) ax2.axes.get_yaxis().set_visible(False) ax2.autoscale_view('tight') ax2.tick_params(axis='both', which='major', pad=0) sns.despine(left=True, bottom=True) for tick in ax2.xaxis.get_major_ticks(): tick.label.set_fontsize(6) tick.label.set_color(color_time) ax3.plot(f[0:], power[0:, i], color=color_power, linewidth=min(100 / len(power[0:, i]), 1.0)) ax3.set_xlim([f[0], f.max()]) ax3.axes.get_yaxis().set_visible(False) ax3.autoscale_view('tight') ax3.tick_params(axis='both', which='major', pad=0) for tick in ax3.xaxis.get_major_ticks(): tick.label.set_fontsize(6) tick.label.set_color(color_power) sns.despine(left=True, bottom=True) plt.subplots_adjust(hspace=0.5) image_buf = StringIO() fig.savefig(image_buf, dpi=300, format='svg', transparent=True, bbox_inches='tight', pad_inches=0.01) fig.clf() image_svg = image_buf.getvalue() if compress is True or compress == 'auto': image_svg = svg_compress(image_svg, compress) image_svg = re.sub(' height="[0-9]+[a-z]*"', '', image_svg, count=1) image_svg = re.sub(' width="[0-9]+[a-z]*"', '', image_svg, count=1) image_svg = re.sub(' viewBox', ' preseveAspectRation="xMidYMid meet" viewBox', image_svg, count=1) Path(out_file).write_text(image_svg)
canica = CanICA(n_components=20, smoothing_fwhm=6., memory="nilearn_cache", memory_level=5, threshold=3., verbose=10, random_state=0) canica.fit(func_filenames) # Retrieve the independent components in brain space components_img = canica.masker_.inverse_transform(canica.components_) # components_img is a Nifti Image object, and can be saved to a file with # the following line: components_img.to_filename('canica_resting_state.nii.gz') #################################################################### # To visualize we plot the outline of all components on one figure from nilearn.plotting import plot_prob_atlas # Plot all ICA components together plot_prob_atlas(components_img, title='All ICA components') #################################################################### # Finally, we plot the map for each ICA component separately from nilearn.image import iter_img from nilearn.plotting import plot_stat_map, show for i, cur_img in enumerate(iter_img(components_img)): plot_stat_map(cur_img, display_mode="z", title="IC %d" % i, cut_coords=1, colorbar=False) show()