def load_or_generate_components(hemi, out_dir='.', plot_dir=None, force=False, *args, **kwargs): """Load an image and return if it exists, otherwise compute via ICA""" # Only re-run if image doesn't exist. img_path = op.join(out_dir, '%s_ica_components.nii.gz' % hemi) if not force and op.exists(img_path): img = NiftiImageWithTerms.from_filename(img_path) else: img = generate_components(hemi=hemi, out_dir=out_dir, *args, **kwargs) png_dir = op.join(out_dir, 'png') plot_components(img, hemi=hemi, out_dir=png_dir) plot_components_summary(img, hemi=hemi, out_dir=png_dir) return img
def image_analyses(components, dataset, memory=Memory(cachedir='nilearn_cache'), **kwargs): """ 1) Plot sparsity of ICA images for wb, R, and L. 2) Plot Hemispheric Participation Index (HPI) for wb ICA images """ out_dir = op.join('ica_imgs', dataset) images_key = ["R", "L", "wb"] sparsity_levels = ['pos_005', 'neg_005', 'abs_005'] # For calculating hemispheric participation index (HPI) from wb components, # prepare hemisphere maskers hemi_maskers = [HemisphereMasker(hemisphere=hemi, memory=memory).fit() for hemi in ['R', 'L']] # Store sparsity (and hpi for wb) vals in a DF columns = ["n_comp"] + sparsity_levels wb_columns = columns + ["pos_hpi", "neg_hpi"] hemi_dfs = {hemi: pd.DataFrame(columns=wb_columns if hemi == "wb" else columns) for hemi in images_key} # Loop over components for c in components: print("Simply loading component images for n_component = %s" % c) nii_dir = op.join('ica_nii', dataset, str(c)) for hemi in images_key: img_path = op.join(nii_dir, '%s_ica_components.nii.gz' % (hemi)) img = NiftiImageWithTerms.from_filename(img_path) data = pd.DataFrame({"n_comp": [c] * c}, columns=columns) # get mean sparsity for the ica iamge and store in sparsity dict for s in sparsity_levels: thresh = float('0.%s' % (re.findall('\d+', s)[0])) # sparsity is # of voxels above the given sparsity level for each component if 'pos' in s: data[s] = (img.get_data() > thresh).sum(axis=0).sum(axis=0).sum(axis=0) elif 'neg' in s: data[s] = (img.get_data() < -thresh).sum(axis=0).sum(axis=0).sum(axis=0) elif 'abs' in s: data[s] = (abs(img.get_data()) > thresh).sum(axis=0).sum(axis=0).sum(axis=0) # get hpi values for wb components if hemi == "wb": hemi_vectors = [masker.transform(img) for masker in hemi_maskers] # transform back so that values for each component can be calculated hemi_imgs = [masker.inverse_transform(vec) for masker, vec in zip(hemi_maskers, hemi_vectors)] # pos/neg_vals[0] = # voxels in R, pos/neg_vals[1] = # voxels in L pos_vals = [(hemi_img.get_data() > 0.005).sum(axis=0).sum(axis=0).sum(axis=0) for hemi_img in hemi_imgs] neg_vals = [(hemi_img.get_data() < -0.005).sum(axis=0).sum(axis=0).sum(axis=0) for hemi_img in hemi_imgs] for sign, val in zip(['pos', 'neg'], [pos_vals, neg_vals]): with np.errstate(divide="ignore", invalid="ignore"): # pos/neg HPI vals, calculated as (R-L)/(R+L) for num. of voxels above # the given threshold hpi = (val[0].astype(float) - val[1]) / (val[0] + val[1]) data["%s_hpi" % (sign)] = hpi hemi_dfs[hemi] = hemi_dfs[hemi].append(data) # Now plot: # 1) Sparsity for wb, R and L ICA images fh, axes = plt.subplots(1, 3, sharex=True, sharey=True, figsize=(18, 6)) sparsity_styles = {'pos_005': ['b', 'lightblue'], 'neg_005': ['r', 'lightpink'], 'abs_005': ['g', 'lightgreen']} for ax, hemi in zip(axes, images_key): df = hemi_dfs[hemi] by_comp = df.groupby('n_comp') for s in sparsity_levels: mean, sd = by_comp.mean()[s], by_comp.std()[s] ax.fill_between(components, mean + sd, mean - sd, linewidth=0, facecolor=sparsity_styles[s][1], alpha=0.5) ax.plot(components, mean, color=sparsity_styles[s][0], label=s) # Overlay individual points for absolute threshold ax.scatter(df.n_comp, df.abs_005, c=sparsity_styles['abs_005'][0]) ax.set_title("Sparsity of the %s components" % (hemi)) ax.set_xlim(xmin=components[0] - 1, xmax=components[-1] + 1) ax.set_xticks(components) plt.legend() fh.text(0.5, 0.04, "# of components", ha="center") fh.text(0.04, 0.5, "# of voxels above the threshold", va='center', rotation='vertical') out_path = op.join(out_dir, 'sparsity.png') save_and_close(out_path, fh=fh) # 2) HPI plot for wb components fh, axes = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(12, 6)) fh.suptitle("Hemispheric Participation Index for each component", fontsize=16) hpi_styles = {'pos': ['b', 'lightblue', 'above 0.005'], 'neg': ['r', 'lightpink', 'below -0.005']} df = hemi_dfs["wb"] by_comp = df.groupby("n_comp") for ax, sign in zip(axes, ['pos', 'neg']): mean, sd = by_comp.mean()["%s_hpi" % sign], by_comp.std()["%s_hpi" % sign] ax.fill_between(components, mean + sd, mean - sd, linewidth=0, facecolor=hpi_styles[sign][1], alpha=0.5) size = df['%s_005' % (sign)] ax.scatter(df.n_comp, df["%s_hpi" % sign], label=sign, c=hpi_styles[sign][0], s=size / 20) ax.plot(components, mean, c=hpi_styles[sign][0]) ax.set_title("%s" % (sign)) ax.set_xlim((0, components[-1] + 5)) ax.set_ylim((-1, 1)) ax.set_xticks(components) ax.set_ylabel("HPI((R-L)/(R+L) for # of voxels %s" % (hpi_styles[sign][2])) fh.text(0.5, 0.04, "# of components", ha="center") out_path = op.join(out_dir, 'wb_HPI.png') save_and_close(out_path, fh=fh) # Save sparsity and HPI vals for all the components for hemi in images_key: hemi_dfs[hemi].index.name = "idx" hemi_dfs[hemi].to_csv(op.join(out_dir, "%s_summary.csv" % (hemi)))