def _thiscontrast(i, node=node, cluster_threshold=cluster_threshold, mode=mode, title=title, axis=axis, row_l=row_l, start=start, end=end, step=step): output_dir = osp.join(path, node._id) img = glob(osp.join(output_dir, 'spm*_00%02d.nii' % i))[0] contrast_type = osp.split(img)[-1][3] print([img, contrast_type]) contrast_name = node.inputs.contrasts[i - 1][0] thresholded_map1, threshold1 = map_threshold( img, threshold=0.001, cluster_threshold=cluster_threshold) if mode == 'uncorrected': threshold1 = 3.106880 if contrast_type == 'T' else 4.69 pval_thresh = 0.001 elif mode == 'FWE': threshold1 = 4.5429 if contrast_type == 'T' else 8.1101 pval_thresh = 0.05 pngfile = plot_stat_map(img, threshold=threshold1, row_l=row_l, axis=axis, start=start, end=end, step=step, title='(%s) %s - %s>%.02f - p<%s (%s)' % (title, contrast_name, contrast_type, threshold1, pval_thresh, mode)) return pngfile
def one_sample_test(imgs, glm, threshold=3.1, height_control='none'): """ Do a one sample t-test of the contrast images in dataframe Parameters ---------- imgs: list of strings, input images glm: nistats.SecondLevelModel instance the model used for analysis (with preset mask) verbose: bool, optional, verbosity mode Returns ------- z: array of shape (mask.sum()), the z-transformed contrast values within the mask """ n_samples = len(imgs) dmtx = pd.DataFrame(np.ones(n_samples), columns=['intercept']) glm.fit(imgs, design_matrix=dmtx) rfx_img = glm.compute_contrast([1], output_type='z_score') _, threshold_ = map_threshold(rfx_img, threshold=threshold, height_control=height_control) rfx = glm.masker_.transform(rfx_img) rfx = rfx * (np.abs(rfx) > threshold) return rfx_img, threshold_, rfx
def conjunction_img(imgs, masker, contrast, percentile=50, threshold=3.1, height_control='none'): """ generate conjunction statsitics of the contrat images in dataframe Parameters ---------- df: pandas dataframe, holding information on the database indexed by task, contrast, subject contrasts: list of strings, The contrasts to be tested masker: niftimasker instance, to define the spatial context of the analysis precentile: float, Percentile used for the conjunction analysis """ from conjunction import _conjunction_inference_from_z_values contrast_mask = (df.contrast.values == contrast) Z = masker.transform(imgs).T pos_conj = _conjunction_inference_from_z_values(Z, percentile * .01) neg_conj = _conjunction_inference_from_z_values(-Z, percentile * .01) conj = pos_conj conj[conj < 0] = 0 conj[neg_conj > 0] = -neg_conj[neg_conj > 0] conj_img = masker.inverse_transform(conj) _, threshold_ = map_threshold(conj_img, threshold=threshold, height_control=height_control) conj = conj * (np.abs(conj) > threshold) return conj_img, threshold_, conj
def one_sample_ttest(filenames, name): design_matrix = pd.DataFrame([1] * len(filenames), columns=['intercept']) second_level_model = SecondLevelModel().fit(filenames, design_matrix=design_matrix) z_map = second_level_model.compute_contrast(output_type='z_score') nib.save(zmap, name + '.nii') thmap, threshold1 = map_threshold(z_map, level=.001, height_control='fpr', cluster_threshold=10) display = plot_glass_brain(thmap, display_mode='lzry', threshold=0, colorbar=True) display.savefig(name + '.png') display.close()
def print_images1(files, masker, mask_array, curr_work_folder, coords): """Convert NIfTI files to images""" for file in files: pdata = nib.load(os.path.join(curr_work_folder, file)).get_data() pvals = pdata[mask_array > 0] z_map = masker.inverse_transform(z_score(np.power(10, -np.abs(pvals)))) threshold1 = fdr_threshold(np.power(10, -np.abs(pvals)), 0.05) thresholded_map2, threshold2 = map_threshold(z_map, threshold=.05, height_control='fdr') print(file, threshold1, threshold2) # According to internet plotting.plot_stat_map(thresholded_map2, threshold=threshold2, cut_coords=coords, title='Thresholded z map, expected fdr = .05', output_file=os.path.join( curr_work_folder, os.path.splitext(file)[0] + '_01')) # Flop plotting.plot_stat_map(os.path.join(working_folder, file), threshold=threshold1, cut_coords=coords, title='Thresholded z map, expected fdr = .05', output_file=os.path.join( curr_work_folder, os.path.splitext(file)[0] + '_02')) # Does this make sense plotting.plot_stat_map(thresholded_map2, threshold=threshold1, cut_coords=coords, title='Thresholded z map, expected fdr = .05', output_file=os.path.join( curr_work_folder, os.path.splitext(file)[0] + '_03')) # plotting.plot_stat_map(os.path.join(working_folder, file), threshold=threshold2, cut_coords=coords, title='Thresholded z map, expected fdr = .05', output_file=os.path.join( curr_work_folder, os.path.splitext(file)[0] + '_04'))
def test_map_threshold(): shape = (9, 10, 11) p = np.prod(shape) data = norm.isf(np.linspace(1. / p, 1. - 1. / p, p)).reshape(shape) threshold = .001 data[2:4, 5:7, 6:8] = 5. stat_img = nib.Nifti1Image(data, np.eye(4)) mask_img = nib.Nifti1Image(np.ones(shape), np.eye(4)) # test 1 th_map, _ = map_threshold( stat_img, mask_img, threshold, height_control='fpr', cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 2: excessive cluster forming threshold th_map, _ = map_threshold( stat_img, mask_img, 100, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_true(np.sum(vals > 0) == 0) # test 3:excessive size threshold th_map, z_th = map_threshold( stat_img, mask_img, threshold, height_control='fpr', cluster_threshold=10) vals = th_map.get_data() assert_true(np.sum(vals > 0) == 0) assert_equal(z_th, norm.isf(.001)) # test 4: fdr threshold + bonferroni for control in ['fdr', 'bonferroni']: th_map, _ = map_threshold( stat_img, mask_img, .05, height_control=control, cluster_threshold=5) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 5: direct threshold th_map, _ = map_threshold( stat_img, mask_img, 4.0, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 6: without mask th_map, _ = map_threshold( stat_img, None, 4.0, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8)
def glassbrain_allcontrasts(path, title, mode='uncorrected', cluster_threshold=50): ''' For each SPM contrast from a Nipype workflow (`path` points to the base directory), generates a glass brain figure with the corresponding thresholded map. `mode` can be either 'uncorrected' (p<0.001, T>3.1, F>4.69) or 'FWE' (p<0.05, T>4.54, F>8.11). `title` is the title displayed on the plot.''' nodes = [ pickle.load(gzip.open(osp.join(path, e, '_node.pklz'), 'rb')) for e in ['modeldesign', 'estimatemodel', 'estimatecontrasts'] ] _, _, node = nodes spm_mat_file = osp.join(node.output_dir(), 'SPM.mat') for i in range(1, len(node.inputs.contrasts) + 1): output_dir = osp.join(path, node._id) img = glob(osp.join(output_dir, 'spm*_00%02d.nii' % i))[0] contrast_type = osp.split(img)[-1][3] print([img, contrast_type]) contrast_name = node.inputs.contrasts[i - 1][0] thresholded_map1, threshold1 = map_threshold( img, threshold=0.001, cluster_threshold=cluster_threshold) if mode == 'uncorrected': threshold1 = 3.106880 if contrast_type == 'T' else 4.69 pval_thresh = 0.001 elif mode == 'FWE': threshold1 = 4.5429 if contrast_type == 'T' else 8.1101 pval_thresh = 0.05 plotting.plot_glass_brain(thresholded_map1, colorbar=True, black_bg=True, display_mode='ortho', threshold=threshold1, title='(%s) %s - %s>%.02f - p<%s (%s)' % (title, contrast_name, contrast_type, threshold1, pval_thresh, mode))
def _thiscontrast(i, node=node, cluster_threshold=cluster_threshold, mode=mode, title=title, axis=axis, row_l=row_l, start=start, end=end, step=step): output_dir = osp.join(path, node._id) img = glob(osp.join(output_dir, 'spm*_00%02d.nii'%i))[0] contrast_type = osp.split(img)[-1][3] print img, contrast_type contrast_name = node.inputs.contrasts[i-1][0] thresholded_map1, threshold1 = map_threshold(img, threshold=0.001, cluster_threshold=cluster_threshold) if mode == 'uncorrected': threshold1 = 3.106880 if contrast_type == 'T' else 4.69 pval_thresh = 0.001 elif mode == 'FWE': threshold1 = 4.5429 if contrast_type == 'T' else 8.1101 pval_thresh = 0.05 pngfile = plot_stat_map(img, threshold=threshold1, row_l=row_l, axis=axis, start=start, end=end, step=step, title= '(%s) %s - %s>%.02f - p<%s (%s)' %(title, contrast_name, contrast_type, threshold1, pval_thresh, mode)) return pngfile
def glassbrain_allcontrasts(path, title, mode='uncorrected', cluster_threshold=50): ''' For each SPM contrast from a Nipype workflow (`path` points to the base directory), generates a glass brain figure with the corresponding thresholded map. `mode` can be either 'uncorrected' (p<0.001, T>3.1, F>4.69) or 'FWE' (p<0.05, T>4.54, F>8.11). `title` is the title displayed on the plot.''' nodes = [pickle.load(gzip.open(osp.join(path, e, '_node.pklz'), 'rb')) for e in ['modeldesign', 'estimatemodel','estimatecontrasts']] _, _, node = nodes spm_mat_file = osp.join(node.output_dir(), 'SPM.mat') for i in range(1, len(node.inputs.contrasts)+1): output_dir = osp.join(path, node._id) img = glob(osp.join(output_dir, 'spm*_00%02d.nii'%i))[0] contrast_type = osp.split(img)[-1][3] print img, contrast_type contrast_name = node.inputs.contrasts[i-1][0] thresholded_map1, threshold1 = map_threshold(img, threshold=0.001, cluster_threshold=cluster_threshold) if mode == 'uncorrected': threshold1 = 3.106880 if contrast_type == 'T' else 4.69 pval_thresh = 0.001 elif mode == 'FWE': threshold1 = 4.5429 if contrast_type == 'T' else 8.1101 pval_thresh = 0.05 plotting.plot_glass_brain(thresholded_map1, colorbar=True, black_bg=True, display_mode='ortho', threshold=threshold1, title='(%s) %s - %s>%.02f - p<%s (%s)' %(title, contrast_name, contrast_type, threshold1, pval_thresh, mode))
def create_one_sample_t_test(name, maps, output_dir, smoothing_fwhm=None, vmax=None, design_matrix=None, p_val=0.001, fdr=0.01, loc=0, scale=1, fwhm=6): """ Do a one sample t-test over the maps. """ print('##### ', name, ' #####') model = SecondLevelModel(smoothing_fwhm=smoothing_fwhm, n_jobs=-1) design_matrix = design_matrix if ( design_matrix is not None) else pd.DataFrame([1] * len(maps), columns=['intercept']) model = model.fit(maps, design_matrix=design_matrix) z_map = model.compute_contrast(output_type='z_score') p_val = p_val z_th = norm.isf(p_val, loc=loc, scale=scale) # 3.09 # apply fdr to zmap thresholded_zmap, th = map_threshold(stat_img=z_map, alpha=fdr, height_control='fdr', cluster_threshold=0, two_sided=False) print(z_th, th) # effect size-map eff_map = model.compute_contrast(output_type='effect_size') thr = np.abs(thresholded_zmap.get_data()) return z_map, eff_map, new_img_like(eff_map, (thr > z_th)), (thr > z_th)
# ## Store them... subject_map.to_filename( os.path.join(cache, 'subject_effect' + '_' + suffix + '.nii.gz')) contrast_map.to_filename( os.path.join(cache, 'condition_effect' + '_' + suffix + '.nii.gz')) acq_map.to_filename( os.path.join(cache, 'acq_effect' + '_' + suffix + '.nii.gz')) # ## ...or load them # subject_map = os.path.join(cache, # 'subject_effect' + '_' + suffix + '.nii.gz') # contrast_map = os.path.join(cache, # 'contrast_effect' + '_' + suffix + '.nii.gz') # acq_map = os.path.join(cache, 'acq_effect' + '_' + suffix + '.nii.gz') # ## Plots _, threshold_ = map_threshold(subject_map, alpha=.05, height_control='fdr') sub_effect = plotting.plot_stat_map(subject_map, cut_coords=[10, -50, 10], threshold=threshold_, vmax=37, title='Subject effect', draw_cross=False) sub_effect.savefig(os.path.join(cache, 'subject_effect' + '_' + suffix + '.png'), dpi=1200) # _, threshold_ = map_threshold(contrast_map, alpha=.05, height_control='fdr') cond_effect = plotting.plot_stat_map(contrast_map, cut_coords=[10, -50, 10],
def test_map_threshold(): shape = (9, 10, 11) p = np.prod(shape) data = norm.isf(np.linspace(1. / p, 1. - 1. / p, p)).reshape(shape) threshold = .001 data[2:4, 5:7, 6:8] = 5. stat_img = nib.Nifti1Image(data, np.eye(4)) mask_img = nib.Nifti1Image(np.ones(shape), np.eye(4)) # test 1 th_map, _ = map_threshold(stat_img, mask_img, threshold, height_control='fpr', cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 2: excessive cluster forming threshold th_map, _ = map_threshold(stat_img, mask_img, 100, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_true(np.sum(vals > 0) == 0) # test 3:excessive size threshold th_map, z_th = map_threshold(stat_img, mask_img, threshold, height_control='fpr', cluster_threshold=10) vals = th_map.get_data() assert_true(np.sum(vals > 0) == 0) assert_equal(z_th, norm.isf(.001)) # test 4: fdr threshold + bonferroni for control in ['fdr', 'bonferroni']: th_map, _ = map_threshold(stat_img, mask_img, .05, height_control=control, cluster_threshold=5) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 5: direct threshold th_map, _ = map_threshold(stat_img, mask_img, 4.0, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8) # test 6: without mask th_map, _ = map_threshold(stat_img, None, 4.0, height_control=None, cluster_threshold=0) vals = th_map.get_data() assert_equal(np.sum(vals > 0), 8)
t_values_masked = [] heat_values_masked = [] for method in ['fmriprep', 'fsl', 'spm', 'fmriflows_none', 'fmriflows_5']: # List of contrasts cons = sorted(glob('res_04_zmaps/zmap_%s_sub-*_%s.nii.gz' % (con, method))) # List of subjects subjects = [[s for s in c.split('_') if 'sub' in s][0] for c in cons] n_subj = len(subjects) # Create subject overview figure tmaps = [] for cidx, tmap in enumerate(cons): _, threshold = map_threshold( tmap, level=p_thresh, height_control=height_control) tmap = math_img('img * (img>=%.8f)' % threshold, img=tmap) tmaps.append(tmap) print(threshold) plot_glass_brain( tmap, colorbar=False, threshold=threshold, plot_abs=False, symmetric_cbar=False, title=subjects[cidx], display_mode='z', axes=axes[int(cidx / 4), int(cidx % 4)]) #tmap.to_filename(res_path + '/thr_%s_%s_h-%s_p-%.3f.nii.gz' % ( # method, subjects[cidx], height_control, p_thresh)) fig.suptitle( '%s: %s (%s - %s)' % (method, con, height_control, p_thresh), fontsize=40) fig.savefig(res_path + '/overview_subjects_%s_%s.svg' % (con, method)) fig.tight_layout()
fmri_masked = nifti_masker.fit_transform(cmap_filenames) # perform a one-sample test on these values from scipy.stats import ttest_1samp _, p_values = ttest_1samp(fmri_masked, 0) # z-transform of p-values from nistats.utils import z_score z_map = nifti_masker.inverse_transform(z_score(p_values)) # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold(z_map, nifti_masker.mask_img_, threshold=.001, height_control='fpr', cluster_threshold=10) # Now use FDR <.05, no cluster-level threshold thresholded_map2, threshold2 = map_threshold(z_map, None, threshold=.05, height_control='fdr') # Visualization from nilearn import plotting display = plotting.plot_stat_map(z_map, title='Raw z map') plotting.plot_stat_map( thresholded_map1, cut_coords=display.cut_coords,
########################################################################### # Fit of the second-level model from nistats.second_level_model import SecondLevelModel model = SecondLevelModel(smoothing_fwhm=5.0) model.fit(contrast_map_filenames, design_matrix=design_matrix) ########################################################################## # To estimate the contrast is very simple. We can just provide the column # name of the design matrix. z_map = model.compute_contrast('fluency', output_type='z_score') ########################################################################### # We compute the fdr-corrected p = 0.05 threshold for these data from nistats.thresholding import map_threshold _, threshold = map_threshold(z_map, alpha=.05, height_control='fdr') ########################################################################### # Let us plot the second level contrast at the computed thresholds from nilearn import plotting plotting.plot_stat_map( z_map, threshold=threshold, colorbar=True, title='Group-level association between motor activity \n' 'and reading fluency (fdr=0.05)') plotting.show() ########################################################################## # Computing the (corrected) p-values with parametric test to compare with
weights = [ [1, 0, 0, 0, 0], [1,-1, 0, 0, 0], [1, 0,-1, 0, 0], [1, 0, 0,-1, 0], [1, 0, 0, 0,-1], [-1, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1,-1, 0, 0], [0, 1, 0,-1, 0], [0, 1, 0, 0,-1], [-1, 0, 1, 0, 0], [0,-1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1,-1, 0], [0, 0, 1, 0,-1], [-1, 0, 0, 1, 0], [0,-1, 0, 1, 0], [0, 0,-1, 1, 0], [0, 0, 0, 1, 0], [0, 0, 0, 1,-1], [-1, 0, 0, 0, 1], [0,-1, 0, 0, 1], [0, 0,-1, 0, 1], [0, 0, 0,-1, 1], [0, 0, 0, 0, 1]] for i, w in enumerate(weights): # Estimate contrast z_map = second_level_model.compute_contrast( second_level_contrast=w, second_level_stat_type='t', output_type='z_score') #z_map.to_filename(res_path + '/tsnr/tsnr_%04d.nii.gz' % (i + 1)) img, threshold = map_threshold( z_map, level=p_thresh, height_control=height_control, cluster_threshold=cluster_threshold) img.to_filename(res_path + '/tsnr/tsnr_%04d_thr.nii.gz' % (i + 1)) plot_stat_map( img, cut_coords=[-20, 10], draw_cross=False, annotate=False, bg_img=template, dim=0.5, vmax=35, display_mode='xz', black_bg=True, colorbar=False, threshold=threshold,
plot_stat_map(z_map, bg_img=mean_img, threshold=3.0, display_mode='z', cut_coords=3, black_bg=True, title='Active minus Rest (Z>3)') plt.show() ############################################################################### # Statistical significance testing. One should worry about the # statistical validity of the procedure: here we used an arbitrary # threshold of 3.0 but the threshold should provide some guarantees on # the risk of false detections (aka type-1 errors in statistics). One # first suggestion is to control the false positive rate (fpr) at a # certain level, e.g. 0.001: this means that there is.1% chance of # declaring active an inactive voxel. from nistats.thresholding import map_threshold _, threshold = map_threshold(z_map, level=.001, height_control='fpr') print('Uncorrected p<0.001 threshold: %.3f' % threshold) plot_stat_map(z_map, bg_img=mean_img, threshold=threshold, display_mode='z', cut_coords=3, black_bg=True, title='Active minus Rest (p<0.001)') plt.show() ############################################################################### # The problem is that with this you expect 0.001 * n_voxels to show up # while they're not active --- tens to hundreds of voxels. A more # conservative solution is to control the family wise error rate, # i.e. the probability of making only one false detection, say at # 5%. For that we use the so-called Bonferroni correction _, threshold = map_threshold(z_map, level=.05, height_control='bonferroni') print('Bonferroni-corrected, p<0.05 threshold: %.3f' % threshold)
from nistats.second_level_model import SecondLevelModel second_level_model = SecondLevelModel(smoothing_fwhm=2.0, mask=mask_img) second_level_model.fit(gray_matter_map_filenames, design_matrix=design_matrix) ########################################################################## # Estimate the contrast is very simple. We can just provide the column # name of the design matrix. z_map = second_level_model.compute_contrast(second_level_contrast=[1, 0, 0], output_type='z_score') ########################################################################### # We threshold the second level contrast at uncorrected p < 0.001 and plot it. # First compute the threshold. from nistats.thresholding import map_threshold _, threshold = map_threshold(z_map, level=.05, height_control='fdr') print('The FDR=.05-corrected threshold is: %.3g' % threshold) ########################################################################### # The plot it from nilearn import plotting display = plotting.plot_stat_map( z_map, threshold=threshold, colorbar=True, display_mode='z', cut_coords=[-4, 26], title='age effect on grey matter density (FDR = .05)') plotting.show() ###########################################################################
# plot_contrast_matrix(pd.DataFrame(contrasts), design_matrix) # plt.savefig(os.path.join(write_dir, 'contrasts.png')) ######################################################################### # contrast estimation for index, (contrast_id, contrast_val) in enumerate(contrasts.items()): print(' Contrast % 2i out of %i: %s' % (index + 1, len(contrasts), contrast_id)) z_map = first_level_model.compute_contrast(contrast_val, output_type='z_score') effect_map = first_level_model.compute_contrast( contrast_val, output_type='effect_size') # Create snapshots of the contrasts _, threshold = map_threshold(z_map, level=.05, height_control='fdr') out_file = os.path.join(write_dir, '%s_z_map.png' % contrast_id) display = plotting.plot_stat_map(z_map, display_mode='z', threshold=threshold, title=contrast_id, output_file=out_file) # write image to disk z_map.to_filename( os.path.join(write_dir, '%s_z_map.nii.gz' % contrast_id)) effect_map.to_filename( os.path.join(write_dir, '%s_effects.nii.gz' % contrast_id)) plt.close('all') import pandas as pd n_subjects = len(subjects)
# Specify and estimate the model from nistats.second_level_model import SecondLevelModel second_level_model = SecondLevelModel().fit(cmap_filenames, design_matrix=design_matrix) ######################################################################### # Compute the only possible contrast: the one-sample test. Since there # is only one possible contrast, we don't need to specify it in detail z_map = second_level_model.compute_contrast(output_type='z_score') ######################################################################### # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold(z_map, alpha=.001, height_control='fpr', cluster_threshold=10) ######################################################################### # Now use FDR <.05, (False Discovery Rate) no cluster-level threshold thresholded_map2, threshold2 = map_threshold(z_map, alpha=.05, height_control='fdr') print('The FDR=.05 threshold is %.3g' % threshold2) ######################################################################### # Now use FWER <.05, (Familywise Error Rate) no cluster-level # threshold. As the data have not been intensively smoothed, we can # use a simple Bonferroni correction thresholded_map3, threshold3 = map_threshold(z_map, alpha=.05,
######################################################################### # Specify and estimate the model from nistats.second_level_model import SecondLevelModel second_level_model = SecondLevelModel().fit( cmap_filenames, design_matrix=design_matrix) ######################################################################### # Compute the only possible contrast: the one-sample test. Since there # is only one possible contrast, we don't need to specify it in detail z_map = second_level_model.compute_contrast(output_type='z_score') ######################################################################### # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold( z_map, alpha=.001, height_control='fpr', cluster_threshold=10) ######################################################################### # Now use FDR <.05, (False Discovery Rate) no cluster-level threshold thresholded_map2, threshold2 = map_threshold( z_map, alpha=.05, height_control='fdr') print('The FDR=.05 threshold is %.3g' % threshold2) ######################################################################### # Now use FWER <.05, (Familywise Error Rate) no cluster-level # threshold. As the data have not been intensively smoothed, we can # use a simple Bonferroni correction thresholded_map3, threshold3 = map_threshold( z_map, alpha=.05, height_control='bonferroni') print('The p<.05 Bonferroni-corrected threshold is %.3g' % threshold3)
verbose=100, n_jobs=1, minimize_memory=True) for con in ['left_hand-right_hand' ]: #['incongruent-congruent', 'incorrect-correct']: if con == 'incorrect-correct': models = [] for model in fl_models: if 'incorrect' in model.design_matrices_[0]: models.append(model) else: models = fl_models slm.fit(models) print("Computing %s contrast ..." % con) zmap = slm.compute_contrast(second_level_contrast=None, first_level_contrast=con, second_level_stat_type='t', output_type='z_score') zmap_thr = map_threshold(stat_img=zmap, mask_img=None, level=0.05, height_control='fdr', cluster_threshold=0)[0] zmap.to_filename(op.join(sl_dir, 'zmap_%s.nii.gz' % con)) zmap_thr.to_filename(op.join(sl_dir, 'zmap_thr_%s.nii.gz' % con))
cmap_filenames = localizer_dataset.cmaps fmri_masked = nifti_masker.fit_transform(cmap_filenames) # perform a one-sample test on these values from scipy.stats import ttest_1samp _, p_values = ttest_1samp(fmri_masked, 0) # z-transform of p-values from nistats.utils import z_score z_map = nifti_masker.inverse_transform(z_score(p_values)) # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold( z_map, nifti_masker.mask_img_, threshold=.001, height_control='fpr', cluster_threshold=10) # Now use FDR <.05, no cluster-level threshold thresholded_map2, threshold2 = map_threshold( z_map, None, threshold=.05, height_control='fdr') # Visualization from nilearn import plotting display = plotting.plot_stat_map(z_map, title='Raw z map') plotting.plot_stat_map( thresholded_map1, cut_coords=display.cut_coords, threshold=threshold1, title='Thresholded z map, fpr <.001, clusters > 10 voxels') plotting.plot_stat_map(thresholded_map2, cut_coords=display.cut_coords, title='Thresholded z map, expected fdr = .05',
# ---------------------------------- # perform a one-sample test on these values from scipy.stats import ttest_1samp _, p_values = ttest_1samp(fmri_masked, 0) ######################################################################### # z-transform of p-values from nistats.utils import z_score z_map = nifti_masker.inverse_transform(z_score(p_values)) ######################################################################### # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold(z_map, threshold=.001, height_control='fpr', cluster_threshold=10) ######################################################################### # Now use FDR <.05, no cluster-level threshold thresholded_map2, threshold2 = map_threshold(z_map, threshold=.05, height_control='fdr') ######################################################################### # Visualize the results from nilearn import plotting display = plotting.plot_stat_map(z_map, title='Raw z map') plotting.plot_stat_map( thresholded_map1, cut_coords=display.cut_coords,
memory='nilearn_cache', memory_level=1) # cache options cmap_filenames = localizer_dataset.cmaps fmri_masked = nifti_masker.fit_transform(cmap_filenames) # perform a one-sample test on these values from scipy.stats import ttest_1samp _, p_values = ttest_1samp(fmri_masked, 0) # z-transform of p-values from nistats.utils import z_score z_map = nifti_masker.inverse_transform(z_score(p_values)) # Threshold the resulting map: # false positive rate < .001, cluster size > 10 voxels from nistats.thresholding import map_threshold thresholded_map1, threshold1 = map_threshold( z_map, threshold=.001, height_control='fpr', cluster_threshold=10) # Now use FDR <.05, no cluster-level threshold thresholded_map2, threshold2 = map_threshold( z_map, threshold=.05, height_control='fdr') # Visualization from nilearn import plotting display = plotting.plot_stat_map(z_map, title='Raw z map') plotting.plot_stat_map( thresholded_map1, cut_coords=display.cut_coords, threshold=threshold1, title='Thresholded z map, fpr <.001, clusters > 10 voxels') plotting.plot_stat_map(thresholded_map2, cut_coords=display.cut_coords, title='Thresholded z map, expected fdr = .05', threshold=threshold2)
from nistats.second_level_model import SecondLevelModel second_level_model = SecondLevelModel(smoothing_fwhm=2.0, mask_img=mask_img) second_level_model.fit(gray_matter_map_filenames, design_matrix=design_matrix) ########################################################################## # Estimate the contrast is very simple. We can just provide the column # name of the design matrix. z_map = second_level_model.compute_contrast(second_level_contrast=[1, 0, 0], output_type='z_score') ########################################################################### # We threshold the second level contrast at uncorrected p < 0.001 and plot it. # First compute the threshold. from nistats.thresholding import map_threshold _, threshold = map_threshold( z_map, alpha=.05, height_control='fdr') print('The FDR=.05-corrected threshold is: %.3g' % threshold) ########################################################################### # Then plot it from nilearn import plotting display = plotting.plot_stat_map( z_map, threshold=threshold, colorbar=True, display_mode='z', cut_coords=[-4, 26], title='age effect on grey matter density (FDR = .05)') plotting.show() ########################################################################### # Can also study the effect of sex: compute the stat, compute the # threshold, plot the map
def model_fitting(source_img, prepped_img, subject_info, aroma, task, args, mask_file, run_number): # Get the necessary parameters outputdir = args.outputdir fwhm = args.fwhm cthresh = args.cthresh alpha = args.alpha # Make a task directory in the output folder if run_number > 0: taskdir = os.path.join(outputdir, task + "_run-0" + str(run_number + 1)) else: taskdir = os.path.join(outputdir, task) if not os.path.exists(taskdir): os.mkdir(taskdir) os.mkdir(os.path.join(taskdir, 'stats')) os.mkdir(os.path.join(taskdir, 'figs')) processed_image = preprocess(aroma, fwhm, prepped_img, mask_file, taskdir, task) task_vs_baseline = [ task + " vs baseline", 'T', [task, 'baseline'], [1, -1] ] # set up contrasts contrasts = [task_vs_baseline] """ Model fitting workflow Inputs:: inputspec.session_info : info generated by modelgen.SpecifyModel inputspec.interscan_interval : interscan interval inputspec.contrasts : list of contrasts inputspec.film_threshold : image threshold for FILM estimation inputspec.model_serial_correlations inputspec.bases Outputs:: outputspec.copes outputspec.varcopes outputspec.dof_file outputspec.zfiles outputspec.parameter_estimates """ modelfit = pe.Workflow(name='modelfit', base_dir=taskdir) modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") # generate design info inputspec = pe.Node(util.IdentityInterface(fields=[ 'session_info', 'interscan_interval', 'contrasts', 'film_threshold', 'functional_data', 'bases', 'model_serial_correlations' ]), name='inputspec') level1design = pe.Node(interface=fsl.Level1Design(), name="level1design") modelgen = pe.MapNode(interface=fsl.FEATModel(), name='modelgen', iterfield=['fsf_file', 'ev_files']) modelestimate = pe.MapNode( interface=fsl.FILMGLS(smooth_autocorr=True, mask_size=5), name='modelestimate', iterfield=['design_file', 'in_file', 'tcon_file']) merge_contrasts = pe.MapNode(interface=util.Merge(2), name='merge_contrasts', iterfield=['in1']) outputspec = pe.Node(util.IdentityInterface(fields=[ 'copes', 'varcopes', 'dof_file', 'zfiles', 'parameter_estimates' ]), name='outputspec') modelfit.connect([ (modelspec, inputspec, [('session_info', 'session_info')]), (inputspec, level1design, [('interscan_interval', 'interscan_interval'), ('session_info', 'session_info'), ('contrasts', 'contrasts'), ('bases', 'bases'), ('model_serial_correlations', 'model_serial_correlations')]), (inputspec, modelestimate, [('film_threshold', 'threshold'), ('functional_data', 'in_file')]), (level1design, modelgen, [('fsf_files', 'fsf_file'), ('ev_files', 'ev_files')]), (modelgen, modelestimate, [('design_file', 'design_file')]), (merge_contrasts, outputspec, [('out', 'zfiles')]), (modelestimate, outputspec, [('param_estimates', 'parameter_estimates'), ('dof_file', 'dof_file')]), ]) modelfit.connect([ (modelgen, modelestimate, [('con_file', 'tcon_file'), ('fcon_file', 'fcon_file')]), (modelestimate, merge_contrasts, [('zstats', 'in1'), ('zfstats', 'in2')]), (modelestimate, outputspec, [('copes', 'copes'), ('varcopes', 'varcopes')]), ]) # Define inputs to workflow modelspec.inputs.functional_runs = processed_image inputspec.inputs.functional_data = processed_image modelspec.inputs.subject_info = subject_info modelspec.inputs.input_units = 'secs' modelspec.inputs.time_repetition = source_img.entities['RepetitionTime'] modelspec.inputs.high_pass_filter_cutoff = 90 inputspec.inputs.model_serial_correlations = True inputspec.inputs.film_threshold = 10.0 inputspec.inputs.interscan_interval = source_img.entities['RepetitionTime'] inputspec.inputs.bases = { 'gamma': { 'gammasigma': 3, 'gammadelay': 6, 'derivs': True } } inputspec.inputs.contrasts = contrasts # Run the model-fitting pipeline. Main outputs are a feat directory (w/ functional img) and a design.mat file res = modelfit.run() # outputs output_txt = open(os.path.join(taskdir, task + '_outputs.txt'), 'w') print_outputs(output_txt, res) # The third node, FILM's, first element (i.e. only element) of its 'zstats' output z_img = list(res.nodes)[2].result.outputs.zstats[0] # Use False Discovery Rate theory to correct for multiple comparisons fdr_thresh_img, fdr_threshold = thresholding.map_threshold( stat_img=z_img, mask_img=mask_file, alpha=alpha, height_control='fdr', cluster_threshold=cthresh) print("Thresholding at FDR corrected threshold of " + str(fdr_threshold)) fdr_thresh_img_path = os.path.join(taskdir, task + '_fdr_thresholded_z.nii.gz') nibabel.save(fdr_thresh_img, fdr_thresh_img_path) # Do a cluster analysis using the FDR corrected threshold on the original z_img print("Performing cluster analysis.") cl = fsl.Cluster(in_file=z_img, threshold=fdr_threshold) cluster_file = os.path.join(taskdir, 'stats', task + "_cluster_stats.txt") cluster_analysis(cluster_file, cl) # Resample the result image with AFNI resample_fdr_thresh_img_path = os.path.join( taskdir, task + '_fdr_thresholded_z_resample.nii.gz') print("Resampling thresholded image to MNI space") resample = afni.Resample(master=template, out_file=resample_fdr_thresh_img_path, in_file=fdr_thresh_img_path) resample.run() os.remove(fdr_thresh_img_path) print("Image to be returned: " + resample_fdr_thresh_img_path) return resample_fdr_thresh_img_path
def run_sig_tests(data_fnames, mask=None): cmap = "Wistia" second_level_model = SecondLevelModel(smoothing_fwhm=5.0, mask=mask) if isinstance(data_fnames, dict): test_type = 'z' data_fnames_num = sorted(data_fnames['number']) data_fnames_fri = sorted(data_fnames['friend']) fname_atts = get_all_bids_atts(data_fnames_num[0]) fname_atts['task'] = 'diff' fname_atts['test'] = 'pairedt' # create paired t-test design matrix pair_mat = np.zeros( (2 * len(data_fnames_num), len(data_fnames_num) + 1), dtype=int) labs = [] for i in range(len(data_fnames_num)): l = 's' + str(i) labs = labs + [l] a = [0] * len(data_fnames_num) a[i] = 1 pair_mat[:, i] = a + a pair_mat[:, len(data_fnames_num)] = [1] * len( data_fnames_num) + [-1] * len(data_fnames_fri) design_matrix = pd.DataFrame(pair_mat, columns=labs + ['diff']) if fname_atts['pred'] == 'deg': data_fnames = data_fnames_num + data_fnames_fri cmap = "winter" elif fname_atts['pred'] == 'dist': data_fnames = data_fnames_fri + data_fnames_num cmap = "cool" print(data_fnames) con_name = 'diff' else: fname_atts = get_all_bids_atts(data_fnames[0]) # if fname_atts['val'] == 'R2': # test_type = 'ks' # fname_atts['test'] = 'ksfit' # else: test_type = 'z' fname_atts['test'] = 'singlesamplet' design_matrix = pd.DataFrame([1] * len(data_fnames), columns=['intercept']) con_name = 'intercept' # setup file names del fname_atts['sub'] fname_atts['correction'] = "none" # show data files and design matrix print("Running significance testing on: ") print(data_fnames) if test_type == 'z': print("Using design matrix: ") print(design_matrix) out_stat = "z" # save z map second_level_model = second_level_model.fit( data_fnames, design_matrix=design_matrix) z_map = second_level_model.compute_contrast(con_name, output_type='z_score') out_map = z_map # save p map p_val = second_level_model.compute_contrast(con_name, output_type='p_value') refnii = p_val elif test_type == 'ks': out_stat = "D" d_map, p_map, all_data = run_R2_sig_tests(data_fnames, mask_nii=mask) refnii = nib.load(data_fnames[0]) out_map = nib.Nifti1Image(d_map, refnii.affine, refnii.header) p_val = nib.Nifti1Image(p_map, refnii.affine, refnii.header) # save R2 mean if fname_atts['val'] == 'R2': all_data = load_all(data_fnames) mean_data = np.mean(all_data, axis=3) fname_atts['val2'] = 'mean' out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) save_nii(mean_data, refnii, out_fname) # save stat map fname_atts['val2'] = out_stat out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(out_map, out_fname) print(out_fname + ' saved.') # save p map fname_atts['val2'] = "p" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(p_val, out_fname) print(out_fname + ' saved.') # FDR correction if mask is None: test_indices = np.argwhere(np.ones( refnii.get_data().flatten().shape)).flatten() else: test_indices = np.argwhere(mask.get_data().flatten()).flatten() p_arr = p_val.get_data().flatten() p_arr2 = np.take(p_arr, test_indices) sigs2, fdr_val2, a2, b2 = multipletests(p_arr2, alpha=.05, method='fdr_bh', is_sorted=False, returnsorted=False) pfdr2 = deepcopy(1 - fdr_val2) pfdr_arr = np.zeros(p_arr.shape) np.put(pfdr_arr, test_indices, pfdr2) pfdr_3d2 = pfdr_arr.reshape(p_val.shape) pfdr_map = nib.Nifti1Image(pfdr_3d2, refnii.affine, refnii.header) fname_atts['val2'] = "p" fname_atts['correction'] = "fdr" fname_atts['dir'] = "rev" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(pfdr_map, out_fname) print(out_fname + ' saved.') # plot maps thresholded_map2, threshold2 = map_threshold( out_map, level=.05, height_control='fdr') #, two_sided=False) display = plot_stat_map(out_map, title='raw stat') print('The FDR=.05 threshold is %.3g' % threshold2) if not math.isinf(threshold2): # thresholded_map2, threshold2 = map_threshold( # out_map, level=.001, height_control=None)#, two_sided=False) # fname_atts['val2'] = out_stat # fname_atts['thresh'] = "p01" # fname_atts['plot'] = "statmap" # fname_atts['correction'] = "none" # out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) # display = plot_stat_map(thresholded_map2, title='z map, p < 0.001', threshold = threshold2) # display.savefig(out_fname) # else: fname_atts['val2'] = out_stat fname_atts['thresh'] = "p05" fname_atts['plot'] = "statmap" fname_atts['correction'] = "fdr" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) display = plot_stat_map(thresholded_map2, cut_coords=display.cut_coords, title='Thresholded ' + out_stat + ' map, expected fdr = .05, ' + out_stat + ' = ' + str(threshold2), threshold=threshold2) display.savefig(out_fname) fname_atts['plot'] = "glassbrain" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) display = plot_glass_brain(thresholded_map2, cut_coords=display.cut_coords, title='Thresholded ' + out_stat + ' map, expected fdr = .05, z = ' + str(threshold2), threshold=threshold2) display.savefig(out_fname)
def run_sig_tests(data_fnames, mask=None): cmap = "Wistia" second_level_model = SecondLevelModel(smoothing_fwhm=5.0, mask=mask) if isinstance(data_fnames, dict): data_fnames_num = sorted(data_fnames['number']) data_fnames_fri = sorted(data_fnames['friend']) fname_atts = get_all_bids_atts(data_fnames_num[0]) fname_atts['task'] = 'diff' fname_atts['test'] = 'pairedt' # create paired t-test design matrix pair_mat = np.zeros( (2 * len(data_fnames_num), len(data_fnames_num) + 1), dtype=int) labs = [] for i in range(len(data_fnames_num)): l = 's' + str(i) labs = labs + [l] a = [0] * len(data_fnames_num) a[i] = 1 pair_mat[:, i] = a + a pair_mat[:, len(data_fnames_num)] = [1] * len( data_fnames_num) + [-1] * len(data_fnames_fri) design_matrix = pd.DataFrame(pair_mat, columns=labs + ['diff']) if fname_atts['pred'] == 'deg': data_fnames = data_fnames_num + data_fnames_fri cmap = "winter" elif fname_atts['pred'] == 'dist': data_fnames = data_fnames_fri + data_fnames_num cmap = "cool" print(data_fnames) con_name = 'diff' else: fname_atts = get_all_bids_atts(data_fnames[0]) fname_atts['test'] = 'singlesamplet' design_matrix = pd.DataFrame([1] * len(data_fnames), columns=['intercept']) con_name = 'intercept' # show data files and design matrix print("Running significance testing on: ") print(data_fnames) print("Using design matrix: ") print(design_matrix) # setup file names del fname_atts['sub'] fname_atts['val2'] = "z" fname_atts['correction'] = "none" if 'extra' in fname_atts.keys(): fname_atts.move_to_end('extra') # save z map second_level_model = second_level_model.fit(data_fnames, design_matrix=design_matrix) z_map = second_level_model.compute_contrast(con_name, output_type='z_score') out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(z_map, out_fname) print(out_fname + ' saved.') threshold = 2.88 #3.1 # correponds to p < .001, uncorrected display = plotting.plot_glass_brain(z_map, threshold=threshold, colorbar=True, plot_abs=False, output_file=out_fname, cmap=cmap, title='z map') # save p map p_val = second_level_model.compute_contrast(con_name, output_type='p_value') fname_atts['val2'] = "p" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(p_val, out_fname) print(out_fname + ' saved.') # correct for multiple comparisons # Correcting the p-values for multiple testing and taking negative logarithm n_voxels = np.sum(second_level_model.masker_.mask_img_.get_data()) neg_log_pval = math_img("-np.log10(np.minimum(1, img * {}))".format( str(n_voxels)), img=p_val) fname_atts['val2'] = "p" fname_atts['correction'] = "parametric" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(neg_log_pval, out_fname) print(out_fname + ' saved.') # FDR correction p_arr = p_val.get_data().flatten() sigs, fdr_val, a, b = multipletests(p_arr, alpha=.05, method='fdr_bh', is_sorted=False, returnsorted=False) pfdr = deepcopy(1 - fdr_val) pfdr[fdr_val == 0.] = 0. pfdr = pfdr.reshape(p_val.shape) pfdr_map = nib.Nifti1Image(pfdr, p_val.affine, p_val.header) fname_atts['val2'] = "p" fname_atts['correction'] = "fdr" fname_atts['dir'] = "rev" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) nib.save(pfdr_map, out_fname) print(out_fname + ' saved.') #save_nii(data = fdr_val.reshape(p_val.shape), refnii=p_val, filename=out_fname) threshold = .95 display = plotting.plot_glass_brain(pfdr_map, threshold=threshold, colorbar=True, plot_abs=False, output_file=out_fname, cmap=cmap, title='p map FDR-corrected, p < 0.05') # threshold plots if fname_atts['pred'] in ['deg', 'dist']: thresholded_map1, threshold1 = map_threshold(z_map, level=.001, height_control='fpr', cluster_threshold=10) thresholded_map2, threshold2 = map_threshold(z_map, level=.05, height_control='fdr') print('The FDR=.05 threshold is %.3g' % threshold2) fname_atts['val2'] = "z" fname_atts['thresh'] = "p05" fname_atts['plot'] = "statmap" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) display = plot_stat_map(z_map, title='Raw z map, expected fdr = .05') display = plot_stat_map( thresholded_map2, cut_coords=display.cut_coords, title='Thresholded z map, expected fdr = .05, z = ' + str(threshold2), threshold=threshold2) display.savefig(out_fname) fname_atts['plot'] = "glassbrain" out_fname = os.path.join(out_dir, make_bids_str(fname_atts)) display = plot_glass_brain( thresholded_map2, cut_coords=display.cut_coords, title='Thresholded z map, expected fdr = .05, z = ' + str(threshold2), threshold=threshold2) display.savefig(out_fname)
cut_coords=3, black_bg=True, title='Active minus Rest (Z>3)') plt.show() ############################################################################### # Statistical significance testing. One should worry about the # statistical validity of the procedure: here we used an arbitrary # threshold of 3.0 but the threshold should provide some guarantees on # the risk of false detections (aka type-1 errors in statistics). # One suggestion is to control the false positive rate (fpr, denoted by # alpha) at a certain level, e.g. 0.001: this means that there is 0.1% chance # of declaring an inactive voxel, active. from nistats.thresholding import map_threshold _, threshold = map_threshold(z_map, alpha=.001, height_control='fpr') print('Uncorrected p<0.001 threshold: %.3f' % threshold) plot_stat_map(z_map, bg_img=mean_img, threshold=threshold, display_mode='z', cut_coords=3, black_bg=True, title='Active minus Rest (p<0.001)') plt.show() ############################################################################### # The problem is that with this you expect 0.001 * n_voxels to show up # while they're not active --- tens to hundreds of voxels. A more # conservative solution is to control the family wise error rate, # i.e. the probability of making only one false detection, say at
# %% 3. Threshold and binarize the maps at a reasonable level # Save probabilistic maps and images out h, thr = 'fdr', 0.05 # thresholding parameters prob_maps = '/Users/ilkay.isik/MPI-Documents/hack_19/data/prob_maps2' if not os.path.exists(prob_maps): os.makedirs(prob_maps) for c, loc in enumerate(pfob_norm): zmaps = [load(zmap) for zmap in loc] thr_images, thresholds = [], [] for i in range(nr_sub): thr_img, threshold = map_threshold(zmaps[i], level=thr, height_control=h) thr_images.append(thr_img) thresholds.append(threshold) data = [zmap.get_data() for zmap in thr_images] bin_data = [] for i in range(nr_sub): bin_data.append(np.where(data[i] > thresholds[i], 1, 0)) # sum the images sum_img = np.sum(bin_data, axis=0) # save out out = Nifti1Image(sum_img, header=zmaps[0].header, affine=zmaps[0].affine) save(out, prob_maps + '/' + names[c] + "sum.nii.gz")
def _make_stat_maps_contrast_clusters(stat_img, contrasts_plots, threshold, alpha, cluster_threshold, height_control, min_distance, bg_img, display_mode, plot_type): """ Populates a smaller HTML sub-template with the proper values, make a list containing one or more of such components & returns the list to be inserted into the HTML Report Template. Each component contains the HTML code for a contrast & its corresponding statistical maps & cluster table; Parameters ---------- stat_img : Niimg-like object or None statistical image (presumably in z scale) whenever height_control is 'fpr' or None, stat_img=None is acceptable. If it is 'fdr' or 'bonferroni', an error is raised if stat_img is None. contrasts_plots: Dict[str, str] Contains the contrast names & the HTML code of the contrast's SVG plot. threshold: float desired threshold in z-scale. This is used only if height_control is None alpha: float number controlling the thresholding (either a p-value or q-value). Its actual meaning depends on the height_control parameter. This function translates alpha to a z-scale threshold. cluster_threshold : float cluster size threshold. In the returned thresholded map, sets of connected voxels (`clusters`) with size smaller than this number will be removed. height_control: string false positive control meaning of cluster forming threshold: 'fpr' or 'fdr' or 'bonferroni' or None min_distance: `float` For display purposes only. Minimum distance between subpeaks in mm. Default is 8 mm. bg_img : Niimg-like object Only used when plot_type is 'slice'. See http://nilearn.github.io/manipulating_images/input_output.html The background image for stat maps to be plotted on upon. If nothing is specified, the MNI152 template will be used. To turn off background image, just pass "bg_img=False". display_mode: string Choose the direction of the cuts: 'x' - sagittal, 'y' - coronal, 'z' - axial, 'l' - sagittal left hemisphere only, 'r' - sagittal right hemisphere only, 'ortho' - three cuts are performed in orthogonal directions. Possible values are: 'ortho', 'x', 'y', 'z', 'xz', 'yx', 'yz', 'l', 'r', 'lr', 'lzr', 'lyr', 'lzry', 'lyrz'. plot_type: string ['slice', 'glass'] The type of plot to be drawn. Returns ------- all_components: List[String] Each element is a set of HTML code for contrast name, contrast plot, statistical map, cluster table. """ all_components = [] components_template_path = os.path.join( HTML_TEMPLATE_ROOT_PATH, 'stat_maps_contrast_clusters_template.html') with open(components_template_path) as html_template_obj: components_template_text = html_template_obj.read() for contrast_name, stat_map_img in stat_img.items(): component_text_ = string.Template(components_template_text) thresholded_stat_map, threshold = map_threshold( stat_img=stat_map_img, threshold=threshold, alpha=alpha, cluster_threshold=cluster_threshold, height_control=height_control, ) table_details = _clustering_params_to_dataframe( threshold, cluster_threshold, min_distance, height_control, alpha, ) stat_map_svg = _stat_map_to_svg( stat_img=thresholded_stat_map, bg_img=bg_img, display_mode=display_mode, plot_type=plot_type, table_details=table_details, ) cluster_table = get_clusters_table( stat_map_img, stat_threshold=threshold, cluster_threshold=cluster_threshold, min_distance=min_distance, ) cluster_table_html = _dataframe_to_html( cluster_table, precision=2, index=False, classes='cluster-table', ) table_details_html = _dataframe_to_html( table_details, precision=2, header=False, classes='cluster-details-table', ) components_values = { 'contrast_name': escape(contrast_name), 'contrast_plot': contrasts_plots[contrast_name], 'stat_map_img': stat_map_svg, 'cluster_table_details': table_details_html, 'cluster_table': cluster_table_html, } component_text_ = component_text_.safe_substitute(**components_values) all_components.append(component_text_) return all_components
def test_all_resolution_inference(): shape = (9, 10, 11) p = np.prod(shape) data = norm.isf(np.linspace(1. / p, 1. - 1. / p, p)).reshape(shape) alpha = .001 data[2:4, 5:7, 6:8] = 5. stat_img = nib.Nifti1Image(data, np.eye(4)) mask_img = nib.Nifti1Image(np.ones(shape), np.eye(4)) # test 1: standard case th_map = cluster_level_inference(stat_img, threshold=3, alpha=.05) vals = th_map.get_data() assert np.sum(vals > 0) == 8 # test 2: high threshold th_map = cluster_level_inference(stat_img, threshold=6, alpha=.05) vals = th_map.get_data() assert np.sum(vals > 0) == 0 # test 3: list of thresholds th_map = cluster_level_inference(stat_img, threshold=[3, 6], alpha=.05) vals = th_map.get_data() assert np.sum(vals > 0) == 8 # test 4: one single voxel data[3, 6, 7] = 10 stat_img_ = nib.Nifti1Image(data, np.eye(4)) th_map = cluster_level_inference(stat_img_, threshold=7, alpha=.05) vals = th_map.get_data() assert np.sum(vals > 0) == 1 # test 5: aberrant alpha with pytest.raises(ValueError): cluster_level_inference(stat_img, threshold=3, alpha=2) with pytest.raises(ValueError): cluster_level_inference(stat_img, threshold=3, alpha=-1) # test 6 with mask_img th_map = cluster_level_inference(stat_img, mask_img=mask_img, threshold=3, alpha=.05) vals = th_map.get_data() assert np.sum(vals > 0) == 8 # test 7 verbose mode th_map = cluster_level_inference(stat_img, threshold=3, alpha=.05, verbose=True) # test 9: one-sided test th_map, z_th = map_threshold(stat_img, mask_img, alpha, height_control='fpr', cluster_threshold=10, two_sided=False) assert_equal(z_th, norm.isf(.001)) # test 10: two-side fdr threshold + bonferroni data[0:2, 0:2, 6:8] = -5. stat_img = nib.Nifti1Image(data, np.eye(4)) for control in ['fdr', 'bonferroni']: th_map, _ = map_threshold(stat_img, mask_img, alpha=.05, height_control=control, cluster_threshold=5) vals = get_data(th_map) assert_equal(np.sum(vals > 0), 8) assert_equal(np.sum(vals < 0), 8) th_map, _ = map_threshold(stat_img, mask_img, alpha=.05, height_control=control, cluster_threshold=5, two_sided=False) vals = get_data(th_map) assert_equal(np.sum(vals > 0), 8) assert_equal(np.sum(vals < 0), 0)
def plot_contrasts(df, task_contrast, masker, write_dir, cut=0, display_mode='x', name=''): """ Parameters ---------- df: pandas dataframe, holding information on the database indexed by task, contrast, subject task_contrasts: list of tuples, Pairs of (task, contrasts) to be displayed masker: nilearn.NiftiMasker instance, used to mask out images write_dir: string, where to write the result """ from nilearn.plotting import cm fig = plt.figure(figsize=(16, 4), facecolor='k') plt.axis('off') n_maps = len(task_contrast) cmap = plt.get_cmap(plt.cm.gist_rainbow) color_list = cmap(np.linspace(0, 1, n_maps + 1)) break_length = 165. / n_maps grid = 5 * np.ones((10, 10)) grid[0] = 1 for i in range(n_maps): delta = 1. / n_maps pos = [delta * i, 0.01, delta, .1] ax = fig.add_axes(pos, facecolor='k') ax.axis('off') inset = fig.add_axes([delta * i, 0.01, .01, .05]) inset.imshow(grid, cmap=cm.alpha_cmap(color_list[i])) inset.axis('off') x_text = .08 y_text = .95 ax.text(x_text, y_text, break_string(BETTER_NAMES[task_contrast[i][1]], break_length), va='top', ha='left', fontsize=11, color='w', transform=ax.transAxes) for i, subject in enumerate(SUBJECTS): # anat = df[df.contrast == 't1_bet'][df.subject == subject].path.values[-1] anat = df[df.contrast == 'highres_gm'][df.subject == subject].path.values[-1] print(anat) axes = plt.axes( [.01 + .167 * np.mod(i, 6), .12 + .44 * (i / 6), .165, .44]) th_imgs = [] for task, contrast in task_contrast: imgs = df[df.task == task][df.contrast == contrast]\ [df.subject == subject][df.acquisition == 'ffx'].path.values if len(imgs > 0): img = imgs[-1] threshold = np.percentile(masker.transform(img), 99) th_img, _ = map_threshold(img, threshold=threshold, height_control='height', cluster_threshold=5) th_imgs.append(th_img) plotting.plot_prob_atlas( th_imgs, bg_img=anat, axes=axes, display_mode=display_mode, cut_coords=[cut], black_bg=True, annotate=False, dim=0, # title=subject, colorbar=False, view_type='filled_contours', linewidths=2.) axes.axis('off') fig.savefig(os.path.join(write_dir, 'snapshot_%s.pdf' % name), facecolor='k', dpi=300)
def test_map_threshold(): shape = (9, 10, 11) p = np.prod(shape) data = norm.isf(np.linspace(1. / p, 1. - 1. / p, p)).reshape(shape) alpha = .001 data[2:4, 5:7, 6:8] = 5. stat_img = nib.Nifti1Image(data, np.eye(4)) mask_img = nib.Nifti1Image(np.ones(shape), np.eye(4)) # test 1 th_map, _ = map_threshold(stat_img, mask_img, alpha, height_control='fpr', cluster_threshold=0) vals = get_data(th_map) assert np.sum(vals > 0) == 8 # test 2: excessive cluster forming threshold th_map, _ = map_threshold(stat_img, mask_img, threshold=100, height_control=None, cluster_threshold=0) vals = get_data(th_map) assert np.sum(vals > 0) == 0 # test 3: excessive size threshold th_map, z_th = map_threshold(stat_img, mask_img, alpha, height_control='fpr', cluster_threshold=10) vals = get_data(th_map) assert np.sum(vals > 0) == 0 assert z_th == norm.isf(.0005) # test 4: fdr threshold + bonferroni for control in ['fdr', 'bonferroni']: th_map, _ = map_threshold(stat_img, mask_img, alpha=.05, height_control=control, cluster_threshold=5) vals = get_data(th_map) assert np.sum(vals > 0) == 8 # test 5: direct threshold th_map, _ = map_threshold(stat_img, mask_img, threshold=4.0, height_control=None, cluster_threshold=0) vals = get_data(th_map) assert np.sum(vals > 0) == 8 # test 6: without mask th_map, _ = map_threshold(stat_img, None, threshold=4.0, height_control=None, cluster_threshold=0) vals = get_data(th_map) assert np.sum(vals > 0) == 8 # test 7 without a map th_map, threshold = map_threshold(None, None, threshold=3.0, height_control=None, cluster_threshold=0) assert threshold == 3.0 assert th_map == None # noqa:E711 th_map, threshold = map_threshold(None, None, alpha=0.05, height_control='fpr', cluster_threshold=0) assert (threshold > 1.64) assert th_map == None # noqa:E711 with pytest.raises(ValueError): map_threshold(None, None, alpha=0.05, height_control='fdr') with pytest.raises(ValueError): map_threshold(None, None, alpha=0.05, height_control='bonferroni') # test 8 wrong procedure with pytest.raises(ValueError): map_threshold(None, None, alpha=0.05, height_control='plop')
from nistats.second_level_model import SecondLevelModel second_level_model = SecondLevelModel(smoothing_fwhm=2.0, mask=mask_img) second_level_model.fit(gray_matter_map_filenames, design_matrix=design_matrix) ########################################################################## # Estimate the contrast is very simple. We can just provide the column # name of the design matrix. z_map = second_level_model.compute_contrast(second_level_contrast=[1, 0, 0], output_type='z_score') ########################################################################### # We threshold the second level contrast at uncorrected p < 0.001 and plot it. # First compute the threshold. from nistats.thresholding import map_threshold _, threshold = map_threshold( z_map, level=.05, height_control='fdr') print('The FDR=.05-corrected threshold is: %.3g' % threshold) ########################################################################### # The plot it from nilearn import plotting display = plotting.plot_stat_map( z_map, threshold=threshold, colorbar=True, display_mode='z', cut_coords=[-4, 26], title='age effect on grey matter density (FDR = .05)') plotting.show() ########################################################################### # Can also study the effect of sex: compute the stat, compute the # threshold, plot the map
vmin=-1, vmax=1) fig.savefig(op.join(output_dir, 'design_corr.png')) plt.close() for con in ['incongruent-congruent', 'incorrect-correct']: if con == 'incorrect-correct' and 'incorrect' not in design_matrix.columns: print("No incorrect trials for sub-%s!" % m.subject_label) continue out_dict = m.compute_contrast(con, output_type='all') zmap_img, pe_img, var_img = out_dict['z_score'], out_dict[ 'effect_size'], out_dict['effect_variance'] zmap_img_thr = map_threshold(zmap_img, mask_img=m.mask, level=0.05, height_control='fpr')[0] #test = map_threshold(math_img('pe / np.sqrt(var)', pe=pe_img, var=var_img), mask_img=m.mask, level=0.05, height_control='fpr')[0] for name, img in zip(['zvals_thr', 'betas', 'vars'], [zmap_img_thr, pe_img, var_img]): img.to_filename( op.join(output_dir, 'contrast-%s_%s.nii.gz' % (con, name))) fig, ax = plt.subplots(figsize=(10, 5)) plot_stat_map(img, output_file=op.join( output_dir, 'contrast-%s_%s.png' % (con, name)), display_mode='ortho', colorbar=True,