mne.stats.cluster_test#

mne.stats.cluster_test(df, formula, *, within_id=None, reference=None, stat_fun=None, tail=0, threshold=None, n_permutations=1024, adjacency='auto', max_step=1, exclude=None, step_down_p=0.0, t_power=1.0, check_disjoint=False, out_type='indices', rng=None, buffer_size=None, n_jobs=1, verbose=None)[source]#

Run a cluster permutation test from a DataFrame and a formula.

Parameters:
dfpandas.DataFrame

Dataframe containing the data, dependent and independent variables.

formulastr

Wilkinson notation formula naming the dependent variable and either a single independent variable (e.g. "data ~ condition") or a single interaction term between two or more independent variables (e.g. "data ~ a:b", tested with a repeated-measures ANOVA; see within_id). All names must match columns in df. Testing several effects (e.g. two main effects, or a main effect and an interaction) requires calling cluster_test() once per effect.

within_idNone | str

Name of column in df to use in identifying within-group contrasts.

  • If within_id is not None:

    within_id must match a column name in df, e.g. "subject_index" (a name not in df.columns will result in an error). If the independent variable has 1 level per participant, the data will be treated as already subtracted (e.g., condition A - condition B) and a paired t-test against zero will be performed (using mne.stats.ttest_1samp_no_p()). If the independent variable has 2 levels, the data will be subtracted for each participant (e.g., condition A - condition B) first. If it has more than 2 levels, a one-way repeated-measures ANOVA is performed (using mne.stats.f_mway_rm()), with permutations swapping each subject’s observations across the levels (never across subjects).

  • If within_id is None:

    Will perform a between-group test (using mne.stats.f_oneway(); This works for 2 levels or more).

  • This parameter is required if:

    formula’s right-hand side is an interaction term (e.g. "data ~ a:b"), in which case each combination of within_id and the factors must appear exactly once (a fully balanced repeated-measures design).

referencestr | None

Level of the independent variable to treat as the reference, i.e. the level that is subtracted. The test statistic is then computed on other_level - reference, so positive values mean the other level is larger. Only valid for paired two-level contrasts (a single factor with 2 levels, with within_id given); for F-tests and repeated-measures ANOVAs the statistic is sign-invariant and passing reference raises an error. If None (default), levels are taken in sorted order (or in category order if the column is a pandas.Categorical) and the second one is the reference.

stat_funcallable() | None

Function called to calculate the test statistic. Must accept 1D-array as input and return a 1D array. If None (the default), uses mne.stats.ttest_1samp_no_p() for paired tests and mne.stats.f_oneway() for unpaired tests or tests of more than 2 groups..

tailint

If tail is 1, the statistic is thresholded above threshold. If tail is -1, the statistic is thresholded below threshold. If tail is 0, the statistic is thresholded on both sides of the distribution.

thresholdfloat | dict | None

The so-called “cluster forming threshold” in the form of a test statistic (note: this is not an alpha level / “p-value”). If numeric, vertices with stat values more extreme than threshold will be used to form clusters. If None, a t- or F-threshold will be chosen automatically that corresponds to a p-value of 0.05 for the given number of observations (only valid when using stat_fun=None, i.e., a paired t-test or one-way F-test). If threshold is a dict (with keys 'start' and 'step') then threshold-free cluster enhancement (TFCE) will be used (see the TFCE example and [1]). See Notes for an example on how to compute a threshold based on a particular p-value for one-tailed or two-tailed tests.

n_permutationsint | ‘all’

The number of permutations to compute. Can be ‘all’ to perform an exact test.

adjacency“auto” | scipy.sparse.sparray | False

Defines adjacency between locations in the data, i.e. which locations may join to form a cluster.

  • "auto" (default):

    For Evoked, Epochs and BaseTFR input, sensor adjacency is inferred from the montage with mne.channels.find_ch_adjacency(), and the remaining (time and, for TFR data, frequency) dimensions get a regular lattice, connecting each location to its immediate neighbors. The data must have a single channel type. For ndarray input there is no sensor information to use, so every dimension gets a lattice.

  • a scipy.sparse.sparray:

    Assumed symmetric (only the upper triangular half is used) and square, with dimension equal to the product of the last 1, 2, or 3 data dimensions. mne.stats.combine_adjacency() is useful for building one; note that cluster_test orders the data dimensions as (n_times[, n_freqs], n_channels).

  • False:

    No adjacency: every location is treated as independent and unconnected, so each supra-threshold location forms its own cluster.

Warning

For ndarray input the lattice spans every axis, including whichever one holds your channels, so clusters can grow between channels that are merely adjacent in the array rather than on the scalp. Pass MNE objects (so "auto" can use the real sensor geometry) or build the adjacency yourself if that distinction matters.

max_stepint

Maximum distance between samples (time points). Default is 1.

excludearray_like of bool | None

Mask to apply to the data to exclude certain points from clustering (e.g., medial wall vertices). Should be the same shape as the channels/vertices dimension of the data objects. If None, no points are excluded.

step_down_pfloat

To perform a step-down-in-jumps test, pass a p-value for clusters to exclude from each successive iteration. Default is zero, perform no step-down test (since no clusters will be smaller than this value). Setting this to a reasonable value, e.g. 0.05, can increase sensitivity but costs computation time.

t_powerfloat

Power to raise the statistical values (usually t-values) by before summing (sign will be retained). Note that t_power=0 will give a count of locations in each cluster, t_power=1 will weight each location by its statistical score.

check_disjointbool

Whether to check if the adjacency matrix can be separated into disjoint sets before clustering. This may lead to faster clustering, especially if the “time” and/or “frequency” dimensions are large.

out_type‘mask’ | ‘indices’

Format used to represent each cluster in the list of clusters stored in the clusters attribute of mne.stats.ClusterResult:

  • 'mask':

    Each cluster is represented by a boolean array of the same shape as the stat_obs attribute array of mne.stats.ClusterResult, with True values indicating locations that are part of a cluster. Note that MNE-Python’s legacy API (e.g. mne.stats.permutation_cluster_test()) would return slices if the shape is 1D and adjacency is None, whereas cluster_test will always return a boolean array.

  • 'indices':

    Each cluster is represented by a tuple of 1D integer arrays, one array per dimension of the array in the stat_obs attribute of mne.stats.ClusterResult. The arrays together give the coordinates of all locations belonging to the cluster and can be used to index stat_obs. Note that for large datasets, 'indices' may use far less memory than 'mask'.

rngNone | int | instance of Generator | RandomState

The random number generator (RNG). If None (default), a new numpy.random.Generator seeded from entropy is used. Pass an int or a numpy.random.Generator for reproducible results, or a legacy RandomState to control the random-number stream or for interoperability with third-party code such as scikit-learn that does not accept generators. An integer seed uses numpy.random.default_rng() and therefore produces a different stream than the same integer passed to a legacy random_state or seed parameter.

New in v1.13.

buffer_sizeint | None

Block size to use when computing test statistics. This can significantly reduce memory usage when n_jobs > 1 and memory sharing between processes is enabled (see mne.set_cache_dir()), because the data will be shared between processes and each process only needs to allocate space for a small block of locations at a time.

n_jobsint | None

The number of jobs to run in parallel. If -1, it is set to the number of CPU cores. Requires the joblib package. None (default) is a marker for ‘unset’ that will be interpreted as n_jobs=1 (sequential execution) unless the call is performed under a joblib.parallel_config context manager that sets another value for n_jobs.

verbosebool | str | int | None

Control verbosity of the logging output. If None, use the default verbosity level. See the logging documentation and mne.verbose() for details. Should only be passed as a keyword argument.

Returns:
mne.stats.ClusterResult

Object containing the results of the cluster permutation test.

Notes

For computing a threshold based on a p-value, use the conversion from scipy.stats.rv_continuous.ppf():

pval = 0.001  # arbitrary
# for t-statistic
df = n_observations - 1  # degrees of freedom for the t-test
thresh = scipy.stats.t.ppf(1 - pval / 2, df)  # two-tailed, t distribution
# for f-statistic
dfn = n_conditions - 1  # degrees of freedom numerator
dfd = n_observations - n_conditions  # degrees of freedom denominator
thresh = scipy.stats.f.ppf(1 - pval, dfn=dfn, dfd=dfd)  # F distribution

For a one-tailed test (tail=1), don’t divide the p-value by 2. For testing the lower tail (tail=-1), don’t subtract pval from 1.

New in v1.13.

Examples using mne.stats.cluster_test#

Permutation F-test on sensor data with 1D cluster level

Permutation F-test on sensor data with 1D cluster level

Visualising statistical significance thresholds on EEG data

Visualising statistical significance thresholds on EEG data

Non-parametric 1 sample cluster statistic on single trial power

Non-parametric 1 sample cluster statistic on single trial power

Non-parametric between conditions cluster statistic on single trial power

Non-parametric between conditions cluster statistic on single trial power

Mass-univariate twoway repeated measures ANOVA on single trial power

Mass-univariate twoway repeated measures ANOVA on single trial power

Spatiotemporal permutation F-test on full sensor data

Spatiotemporal permutation F-test on full sensor data

Group-level cluster permutation testing with formula contrasts

Group-level cluster permutation testing with formula contrasts