def generate_level1_stats_table(zmap, mask, output_html_path, p_threshold=.001, z_threshold=None, method='fpr', cluster_th=15, null_zmax='bonferroni', null_smax=None, null_s=None, nmaxima=4, cluster_pval=.05, title=None, ): """Function to generate level 1 stats table for a contrast. Parameters ---------- zmap: image object z-map data image mask: image object or string brain mask defining ROI output_html_path: string, path where the output html should be written p_threshold: float (optional, default .001) (p-variate) frequentist threshold of the activation image z_threshold: float (optional, default None) Threshold that has been applied to Z map (input z_map) method: string (optional, default 'fpr') to be chosen as height_control in nipy.labs.statistical_mapping cluster_th: int (optional, default 15) cluster size threshold (in # voxels) null_zmax: string (optional, default 'bonferroni') parameter for cluster level statistics (?) null_s: strint (optional, default None) parameter for cluster level statistics (?) nmaxima: int (optional, default 4) number of local maxima reported per supra-threshold cluster title: string (optional) title of generated stats table """ # Delayed import of nipy for more robustness when it is not present import nipy.labs.statistical_mapping as sm # sanity if isinstance(zmap, basestring): zmap = nibabel.load(zmap) if isinstance(mask, basestring): mask = nibabel.load(mask) # Compute cluster statistics nulls = {'zmax': null_zmax, 'smax': null_smax, 's': null_s} """ if null_smax is not None: print "a" clusters, info = sm.cluster_stats(zmap, mask, height_th=threshold, nulls=nulls) clusters = [c for c in clusters if c['cluster_pvalue']<cluster_pval] else: print "b" clusters, info = sm.cluster_stats(zmap, mask, height_th=threshold, height_control=method.lower(), cluster_th=cluster_th, nulls=nulls) """ # do some sanity checks if title is None: title = "Level 1 Statistics" # clusters, info = sm.cluster_stats(zmap, mask, height_th=p_threshold, # nulls=nulls, cluster_th=cluster_th,) clusters, _ = sm.cluster_stats(zmap, mask, height_th=p_threshold, nulls=nulls, cluster_th=cluster_th,) if clusters is not None: clusters = [c for c in clusters if c['cluster_pvalue'] < cluster_pval] #if clusters == None or info == None: # print "No results were written for %s" % zmap_file_path # return if clusters == None: clusters = [] # Make HTML page page = open(output_html_path, mode="w") page.write("<center>\n") page.write("<b>%s</b>\n" % title) page.write("<table border = 1>\n") page.write("<tr><th colspan=4> Voxel significance </th>\ <th colspan=3> Coordinates in MNI referential</th>\ <th>Cluster Size</th></tr>\n") page.write("<tr><th>p FWE corr<br>(Bonferroni)</th>\ <th>p FDR corr</th><th>Z</th><th>p uncorr</th>") page.write("<th> x (mm) </th><th> y (mm) </th><th> z (mm) </th>\ <th>(voxels)</th></tr>\n") for cluster in clusters: maxima = cluster['maxima'] size = cluster['size'] for j in range(min(len(maxima), nmaxima)): temp = ["%.3f" % cluster['fwer_pvalue'][j]] temp.append("%.3f" % cluster['fdr_pvalue'][j]) temp.append("%.2f" % cluster['zscore'][j]) temp.append("%.3f" % cluster['pvalue'][j]) for it in range(3): temp.append("%.0f" % maxima[j][it]) if j == 0: # Main local maximum temp.append('%i' % size) page.write('<tr><th align="center">' + '</th>\ <th align="center">'.join(temp) + '</th></tr>') else: # Secondary local maxima page.write('<tr><td align="center">' + '</td>\ <td align="center">'.join(temp) + '</td><td></td></tr>\n') nclust = len(clusters) nvox = sum([clusters[k]['size'] for k in range(nclust)]) page.write("</table>\n") page.write("Threshold Z: %.2f (%s control at %.3f)<br/>\n" \ % (z_threshold, method, p_threshold)) page.write("Cluster level p-value threshold: %s<br/>\n" % cluster_pval) page.write("Cluster size threshold: %i voxels<br/>\n" % cluster_th) page.write("Number of voxels: %i<br>\n" % nvox) page.write("Number of clusters: %i<br>\n" % nclust) # finish up page.write("</center>\n") page.close() return clusters
group_data = example_data.get_filename( 'neurospin', 'language_babies', 'offset_002.npz') f = np.load(group_data) data, vardata, xyz = f['mat'], f['var'], f['xyz'] dX = xyz[0].max() + 1 dY = xyz[1].max() + 1 dZ = xyz[2].max() + 1 aux = np.zeros([dX, dY, dZ]) data_images = [] vardata_images = [] mask_images = [] for i in range(data.shape[0]): aux[list(xyz)] = data[i] data_images.append(Image(aux.copy(), np.eye(4))) aux[list(xyz)] = vardata[i] vardata_images.append(Image(aux.copy(), np.eye(4))) aux[list(xyz)] = 1 mask_images.append(aux) return data_images, vardata_images, mask_images data_images, vardata_images, mask_images = remake_images() zimg, mask, nulls = sm.onesample_test(data_images, None, mask_images, 'wilcoxon', permutations=1024, cluster_forming_th=0.01) clusters, info = sm.cluster_stats(zimg, mask, 0.01, nulls=nulls)
def get_activations(narps, hyp, logfile, fdr=0.05, pthresh=0.001, simulate_noise=False, cluster_kthresh=10, use_mean_fdr_thresh=False): assert fdr is not None or pthresh is not None region = hyp_regions[hyp] # load mask, create if necessary maskimg_file = get_mask_img(narps, region) maskimg = nibabel.load(maskimg_file) # load data zstat_imgs = get_zstat_images(narps, hyp) # setup masker MNI_img = os.path.join(os.environ['FSLDIR'], 'data/standard/MNI152_T1_2mm_brain_mask.nii.gz') masker = nilearn.input_data.NiftiMasker(MNI_img) # get roi mask roi_mask = masker.fit_transform(maskimg)[0, :] mean_fdr_thresh, fdr_thresh = get_mean_fdr_thresh(zstat_imgs, masker, roi_mask, simulate_noise) results = pandas.DataFrame({ '$p < %0.3f$, $k > %d$' % (pthresh, cluster_kthresh): numpy.zeros(len(zstat_imgs)) }) results['FDR'] = 0.0 for i, img in enumerate(zstat_imgs): z = masker.fit_transform(img)[0, :] if simulate_noise: z = numpy.random.randn(z.shape[0]) p = 1 - scipy.stats.norm.cdf(z) # convert Z to p # compute per-team FDR results.iloc[i, 1] = numpy.sum(p[roi_mask > 0] < fdr_thresh[i, 0]) # cluster z image nii = nibabel.load(img) c = cluster_stats(nii, maskimg, scipy.stats.norm.ppf(1 - pthresh), 'none', cluster_kthresh) if c[0] is not None: results.iloc[i, 0] = len(c[0]) # load ALE and consensus results for comparison meta_results = numpy.zeros(2) ale_img = os.path.join(narps.dirs.dirs['output'], 'ALE/hypo%d_fdr_thresholded.nii.gz' % hyp) if os.path.exists(ale_img): ale_data = masker.fit_transform(ale_img)[0, :] meta_results[0] = numpy.sum(ale_data[roi_mask > 0]) else: meta_results[0] = numpy.nan # consensus not performed for 3 and 4, so use 1/2 instead hyp_fix = {1: 1, 2: 2, 3: 1, 4: 2, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} consensus_img = os.path.join( narps.dirs.dirs['output'], 'consensus_analysis/hypo%d_1-fdr.nii.gz' % hyp_fix[hyp]) if os.path.exists(ale_img): consensus_data = masker.fit_transform(consensus_img)[0, :] meta_results[1] = numpy.sum(consensus_data[roi_mask > 0] > (1 - fdr)) else: meta_results[1] = numpy.nan message = '\nHypothesis: %s\n' % hyp if simulate_noise: message += 'SIMULATING WITH RANDOM NOISE\n' message += 'Region (%d voxels): %s\n' % (numpy.sum(roi_mask), region) message += 'ROI image: %s\n' % maskimg_file message += '\nProportion teams with nonzero activation:\n' message += (results > 0).mean(0).to_string() + '\n' message += 'Activated voxels in ALE map: %d\n' % meta_results[0] message += 'Activated voxels in consensus map: %d\n' % meta_results[1] log_to_file(logfile, message) return (results, mean_fdr_thresh, meta_results, numpy.sum(roi_mask))
def generate_level1_stats_table( zmap, mask, output_html_path, p_threshold=.001, z_threshold=None, method='fpr', cluster_th=15, null_zmax='bonferroni', null_smax=None, null_s=None, nmaxima=4, cluster_pval=.05, title=None, ): """Function to generate level 1 stats table for a contrast. Parameters ---------- zmap: image object z-map data image mask: image object or string brain mask defining ROI output_html_path: string, path where the output html should be written p_threshold: float (optional, default .001) (p-variate) frequentist threshold of the activation image z_threshold: float (optional, default None) Threshold that has been applied to Z map (input z_map) method: string (optional, default 'fpr') to be chosen as height_control in nipy.labs.statistical_mapping cluster_th: int (optional, default 15) cluster size threshold (in # voxels) null_zmax: string (optional, default 'bonferroni') parameter for cluster level statistics (?) null_s: strint (optional, default None) parameter for cluster level statistics (?) nmaxima: int (optional, default 4) number of local maxima reported per supra-threshold cluster title: string (optional) title of generated stats table """ # Delayed import of nipy for more robustness when it is not present import nipy.labs.statistical_mapping as sm # sanity if isinstance(zmap, basestring): zmap = nibabel.load(zmap) if isinstance(mask, basestring): mask = nibabel.load(mask) # Compute cluster statistics nulls = {'zmax': null_zmax, 'smax': null_smax, 's': null_s} """ if null_smax is not None: print "a" clusters, info = sm.cluster_stats(zmap, mask, height_th=threshold, nulls=nulls) clusters = [c for c in clusters if c['cluster_pvalue']<cluster_pval] else: print "b" clusters, info = sm.cluster_stats(zmap, mask, height_th=threshold, height_control=method.lower(), cluster_th=cluster_th, nulls=nulls) """ # do some sanity checks if title is None: title = "Level 1 Statistics" # clusters, info = sm.cluster_stats(zmap, mask, height_th=p_threshold, # nulls=nulls, cluster_th=cluster_th,) clusters, _ = sm.cluster_stats( zmap, mask, height_th=p_threshold, nulls=nulls, cluster_th=cluster_th, ) if clusters is not None: clusters = [c for c in clusters if c['cluster_pvalue'] < cluster_pval] #if clusters == None or info == None: # print "No results were written for %s" % zmap_file_path # return if clusters == None: clusters = [] # Make HTML page page = open(output_html_path, mode="w") page.write("<center>\n") page.write("<b>%s</b>\n" % title) page.write("<table border = 1>\n") page.write("<tr><th colspan=4> Voxel significance </th>\ <th colspan=3> Coordinates in MNI referential</th>\ <th>Cluster Size</th></tr>\n") page.write("<tr><th>p FWE corr<br>(Bonferroni)</th>\ <th>p FDR corr</th><th>Z</th><th>p uncorr</th>") page.write("<th> x (mm) </th><th> y (mm) </th><th> z (mm) </th>\ <th>(voxels)</th></tr>\n") for cluster in clusters: maxima = cluster['maxima'] size = cluster['size'] for j in range(min(len(maxima), nmaxima)): temp = ["%.3f" % cluster['fwer_pvalue'][j]] temp.append("%.3f" % cluster['fdr_pvalue'][j]) temp.append("%.2f" % cluster['zscore'][j]) temp.append("%.3f" % cluster['pvalue'][j]) for it in range(3): temp.append("%.0f" % maxima[j][it]) if j == 0: # Main local maximum temp.append('%i' % size) page.write('<tr><th align="center">' + '</th>\ <th align="center">'.join(temp) + '</th></tr>') else: # Secondary local maxima page.write('<tr><td align="center">' + '</td>\ <td align="center">'.join(temp) + '</td><td></td></tr>\n') nclust = len(clusters) nvox = sum([clusters[k]['size'] for k in range(nclust)]) page.write("</table>\n") page.write("Threshold Z: %.2f (%s control at %.3f)<br/>\n" \ % (z_threshold, method, p_threshold)) page.write("Cluster level p-value threshold: %s<br/>\n" % cluster_pval) page.write("Cluster size threshold: %i voxels<br/>\n" % cluster_th) page.write("Number of voxels: %i<br>\n" % nvox) page.write("Number of clusters: %i<br>\n" % nclust) # finish up page.write("</center>\n") page.close() return clusters