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
Esempio n. 2
0
    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)
Esempio n. 3
0
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))
Esempio n. 4
0
    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)
Esempio n. 5
0
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