Ejemplo n.º 1
0
        text = fig.suptitle(title)
        if mcc:
            text.set_weight('bold')
        plt.subplots_adjust(0, 0.05, 1, 0.9, wspace=0, hspace=0)
        mne.viz.utils.plt_show()


plot_t_p(ts[-1], ps[-1], titles[-1], mccs[-1])

###############################################################################
# "Hat" variance adjustment
# ~~~~~~~~~~~~~~~~~~~~~~~~~
# The "hat" technique regularizes the variance values used in the t-test
# calculation :footcite:`RidgwayEtAl2012` to compensate for implausibly small
# variances.
ts.append(ttest_1samp_no_p(X, sigma=sigma))
ps.append(stats.distributions.t.sf(np.abs(ts[-1]), len(X) - 1) * 2)
titles.append(r'$\mathrm{t_{hat}}$')
mccs.append(False)
plot_t_p(ts[-1], ps[-1], titles[-1], mccs[-1])

###############################################################################
# Non-parametric tests
# ^^^^^^^^^^^^^^^^^^^^
# Instead of assuming an underlying Gaussian distribution, we could instead
# use a **non-parametric resampling** method. In the case of a paired t-test
# between two conditions A and B, which is mathematically equivalent to a
# one-sample t-test between the difference in the conditions A-B, under the
# null hypothesis we have the principle of **exchangeability**. This means
# that, if the null is true, we can exchange conditions and not change
# the distribution of the test statistic.
Ejemplo n.º 2
0
def one_sample_parametric(a, n, hat=0., method='relative'):
    ts = ttest_1samp_no_p(a, sigma=hat, method=method)
    ps = stats.distributions.t.sf(np.abs(ts), n - 1) * 2
    return ts, ps
Ejemplo n.º 3
0
def _stat_fun(x, sigma=0, method="relative"):
    from mne.stats import ttest_1samp_no_p

    t_values = ttest_1samp_no_p(x, sigma=sigma, method=method)
    t_values[np.isnan(t_values)] = 0
    return t_values
Ejemplo n.º 4
0
                # magnetometer RMS
                data[si, hi] = np.sqrt(np.mean(evo_cp.data, axis=0)**2)
            evokeds.append(evoked)
        evoked_dict[cond] = evokeds
        X.append(data)
    # |deviant - standard| per hem
    contrast = np.abs(X[1] - X[0])
    contrast = np.transpose(contrast, (1, 0, 2))
    #############################################
    # One-sample t-testing with "hat" adjustment#
    #############################################
    fig, axs = plt.subplots(1, len(sensors), sharex=True, sharey=True)
    for ii, key in enumerate(sensors.keys()):
        print('     Testing...\n'
              '      |deviant - standard| in %s hem...' % key)
        ts = ttest_1samp_no_p(contrast[ii], sigma=sigma)
        ps_unc = stats.distributions.t.sf(np.abs(ts), n - 1) * 2
        n_samples, n_tests = contrast[ii].shape
        threshold_uncorrected = stats.t.ppf(1.0 - alpha, n_samples - 1)
        reject_bonferroni, pval_bonferroni = bonferroni_correction(ps_unc,
                                                                   alpha=alpha)
        threshold_bonferroni = stats.t.ppf(1.0 - alpha / n_tests,
                                           n_samples - 1)

        reject_fdr, pval_fdr = fdr_correction(ps_unc,
                                              alpha=alpha,
                                              method='indep')
        threshold_fdr = np.min(np.abs(ts)[reject_fdr])
        axs[ii].plot(times,
                     ts,
                     label='$\mathrm{|deviant - standard|_{hat}}$',
    if show:
        text = fig.suptitle(title)
        if mcc:
            text.set_weight('bold')
        plt.subplots_adjust(0, 0.05, 1, 0.9, wspace=0, hspace=0)
        mne.viz.utils.plt_show()


plot_t_p(ts[-1], ps[-1], titles[-1], mccs[-1])

###############################################################################
# "Hat" variance adjustment
# ~~~~~~~~~~~~~~~~~~~~~~~~~
# The "hat" technique regularizes the variance values used in the t-test
# calculation [1]_ to compensate for implausibly small variances.
ts.append(ttest_1samp_no_p(X, sigma=sigma))
ps.append(stats.distributions.t.sf(np.abs(ts[-1]), len(X) - 1) * 2)
titles.append('$\mathrm{t_{hat}}$')
mccs.append(False)
plot_t_p(ts[-1], ps[-1], titles[-1], mccs[-1])

###############################################################################
# Non-parametric tests
# ^^^^^^^^^^^^^^^^^^^^
# Instead of assuming an underlying Gaussian distribution, we could instead
# use a **non-parametric resampling** method. Under the null hypothesis,
# we have the principle of **exchangeability**, which means that, if the null
# is true, we should be able to exchange conditions and not change the
# distribution of the test statistic.
#
# In the case of a two-tailed 1-sample t-test (which can also be used to test
def _stat_fun(x, sigma=0, method='relative'):
    """Aux. function of stats"""
    t_values = ttest_1samp_no_p(x, sigma=sigma, method=method)
    t_values[np.isnan(t_values)] = 0
    return t_values
Ejemplo n.º 7
0
def _stat_fun(x, sigma=0, method='relative'):
    t_values = ttest_1samp_no_p(x, sigma=sigma, method=method)
    t_values[np.isnan(t_values)] = 0
    return t_values
Ejemplo n.º 8
0
def _stat_fun(x, sigma=0, method='relative'):
    from mne.stats import ttest_1samp_no_p
    import numpy as np
    t_values = ttest_1samp_no_p(x, sigma=sigma, method=method)
    t_values[np.isnan(t_values)] = 0
    return t_values
Ejemplo n.º 9
0
def permutation_cluster_ttest(data1,
                              data2,
                              paired=False,
                              n_permutations=1000,
                              threshold=None,
                              p_threshold=0.05,
                              adjacency=None,
                              tmin=None,
                              tmax=None,
                              fmin=None,
                              fmax=None,
                              trial_level=False,
                              min_adj_ch=0):
    '''Perform cluster-based permutation test with t test as statistic.

    Parameters
    ----------
    data1 : list of mne objects
        List of objects (Evokeds, TFRs) belonging to condition one.
    data2 : list of mne objects
        List of objects (Evokeds, TFRs) belonging to condition two.
    paired : bool
        Whether to perform a paired t test. Defaults to ``True``.
    n_permutations : int
        How many permutations to perform. Defaults to ``1000``.
    threshold : value
        Cluster entry threshold defined by the value of the statistic. Defaults
        to ``None`` which calculates threshold from p value (see
        ``p_threshold``)
    p_threshold : value
        Cluster entry threshold defined by the p value.
    adjacency : boolean array | sparse array
        Information about channel adjacency.
    tmin : float
        Start of the time window of interest (in seconds). Defaults to ``None``
        which takes the earliest possible time.
    tmax : float
        End of the time window of interest (in seconds). Defaults to ``None``
        which takes the latest possible time.
    fmin : float
        Start of the frequency window of interest (in seconds). Defaults to
        ``None`` which takes the lowest possible frequency.
    fmax : float
        End of the frequency window of interest (in seconds). Defaults to
        ``None`` which takes the highest possible frequency.
    min_adj_ch: int
        Minimum number of adjacent in-cluster channels to retain a point in
        the cluster.

    Returns
    -------
    clst : borsar.cluster.Clusters
        Obtained clusters.
    '''
    if data2 is not None:
        one_sample = False
        stat_fun = ttest_rel_no_p if paired else ttest_ind_no_p
    else:
        one_sample = True
        stat_fun = lambda data: ttest_1samp_no_p(data[0])

    try:
        kwarg = 'connectivity'
        from mne.source_estimate import spatial_tris_connectivity
    except:
        kwarg = 'adjacency'
        from mne.source_estimate import spatial_tris_adjacency

    inst = data1[0]
    len1 = len(data1)
    len2 = len(data2) if data2 is not None else 0

    if paired:
        assert len1 == len2

    threshold = _compute_threshold([data1, data2], threshold, p_threshold,
                                   trial_level, paired, one_sample)

    # data1 and data2 have to be Evokeds or TFRs
    supported_types = (mne.Evoked, borsar.freq.PSD,
                       mne.time_frequency.AverageTFR,
                       mne.time_frequency.EpochsTFR)
    check_list_inst(data1, inst=supported_types)
    if data2 is not None:
        check_list_inst(data2, inst=supported_types)

    # find time and frequency ranges
    # ------------------------------
    if isinstance(inst, (mne.Evoked, mne.time_frequency.AverageTFR)):
        tmin = 0 if tmin is None else inst.time_as_index(tmin)[0]
        tmax = (len(inst.times)
                if tmax is None else inst.time_as_index(tmax)[0] + 1)
        time_slice = slice(tmin, tmax)

    if isinstance(inst, (borsar.freq.PSD, mne.time_frequency.AverageTFR)):
        fmin = 0 if fmin is None else find_index(data1[0].freqs, fmin)
        fmax = (len(inst.freqs) if fmax is None else find_index(
            data1[0].freqs, fmax))
        freq_slice = slice(fmin, fmax + 1)

    # handle object-specific data
    # ---------------------------
    if isinstance(inst, mne.time_frequency.AverageTFR):
        # + fmin, fmax
        assert not trial_level
        # data are in observations x channels x frequencies x time
        data1 = np.stack(
            [tfr.data[:, freq_slice, time_slice] for tfr in data1], axis=0)
        data2 = (np.stack(
            [tfr.data[:, freq_slice, time_slice]
             for tfr in data2], axis=0) if data2 is not None else data2)
    elif isinstance(inst, mne.time_frequency.EpochsTFR):
        assert trial_level
        data1 = inst.data[..., freq_slice, time_slice]
        data2 = (data2[0].data[..., freq_slice,
                               time_slice] if data2 is not None else data2)
    elif isinstance(inst, borsar.freq.PSD):
        if not inst._has_epochs:
            assert not trial_level
            data1 = np.stack([psd.data[:, freq_slice].T for psd in data1],
                             axis=0)
            data2 = (np.stack([psd.data[:, freq_slice].T for psd in data2],
                              axis=0) if data2 is not None else data2)
        else:
            assert trial_level
            data1 = data1[0].data[..., freq_slice].transpose((0, 2, 1))
            data2 = (data2[0].data[..., freq_slice].transpose(
                (0, 2, 1)) if data2 is not None else data2)
    else:
        data1 = np.stack([erp.data[:, time_slice].T for erp in data1], axis=0)
        data2 = (np.stack([erp.data[:, time_slice].T for erp in data2], axis=0)
                 if data2 is not None else data2)

    data_3d = data1.ndim > 3
    if (isinstance(adjacency, np.ndarray) and not sparse.issparse(adjacency)
            and not data_3d):
        adjacency = sparse.coo_matrix(adjacency)

    # perform cluster-based test
    # --------------------------
    # TODO: now our cluster-based works also for 1d and 2d etc.
    if not data_3d:
        assert min_adj_ch == 0
        adj_param = {kwarg: adjacency}
        stat, clusters, cluster_p, _ = permutation_cluster_test(
            [data1, data2],
            stat_fun=stat_fun,
            threshold=threshold,
            n_permutations=n_permutations,
            out_type='mask',
            **adj_param)
        if isinstance(inst, mne.Evoked):
            dimcoords = [inst.ch_names, inst.times[time_slice]]
            dimnames = ['chan', 'time']
        elif isinstance(inst, borsar.freq.PSD):
            dimcoords = [inst.ch_names, inst.freqs[freq_slice]]
            dimnames = ['chan', 'freq']
        return Clusters(stat.T, [c.T for c in clusters],
                        cluster_p,
                        info=inst.info,
                        dimnames=dimnames,
                        dimcoords=dimcoords)

    else:
        stat, clusters, cluster_p = permutation_cluster_test_array(
            [data1, data2],
            adjacency,
            stat_fun,
            threshold=threshold,
            n_permutations=n_permutations,
            one_sample=one_sample,
            paired=paired,
            min_adj_ch=min_adj_ch)

        # pack into Clusters object
        dimcoords = [inst.ch_names, inst.freqs, inst.times[tmin:tmax]]
        return Clusters(stat,
                        clusters,
                        cluster_p,
                        info=inst.info,
                        dimnames=['chan', 'freq', 'time'],
                        dimcoords=dimcoords)