Statistics#

EEGPrep statistics helpers mirror the useful parts of EEGLAB’s functions/statistics package while using explicit NumPy contracts. Unless noted otherwise, condition arrays use their final axis for cases, subjects, or surrogate replications.

Condition Tests#

statcond(..., return_resampling_array=True) returns a SurrogateDistribution. With arraycomp="on" (the default), it contains naccu condition grids; every condition keeps its original feature and case shape. arraycomp="off" returns one grid and is compatible with EEGLAB’s incremental resampling contract. For ordinary statistical results, the off mode still computes all naccu statistics while holding one resampled grid at a time.

eegprep.statcond(data, *args, **kwargs)

Compare condition arrays using EEGLAB-style t-tests or ANOVAs.

eegprep.statcondfieldtrip(data, *[, paired, ...])

Compare conditions using the supported statcondfieldtrip contract.

eegprep.ttest_cell(a[, b, axis])

Compute paired t-statistics across the case axis.

eegprep.ttest2_cell(a[, b, variance, axis])

Compute unpaired t-statistics across the case axis.

eegprep.anova1_cell(data, *[, axis])

Compute one-way unpaired ANOVA F-statistics across condition arrays.

eegprep.anova1rm_cell(data, *[, axis])

Compute one-way repeated-measures ANOVA F-statistics.

eegprep.anova2_cell(data, *[, axis])

Compute balanced two-way unpaired ANOVA with named factor results.

eegprep.anova2rm_cell(data, *[, axis])

Compute two-way repeated-measures ANOVA F-statistics.

Two-way factor order#

statcond represents every two-way result computed from condition arrays as TwoWayEffects(rows, columns, interaction). Attribute access and iteration use that order for paired and unpaired designs, including statistics, degrees of freedom, p-values, and nonparametric outputs.

This deliberately resolves an inconsistency in EEGLAB’s MATLAB implementation. Although statcond documents rows, columns, and interaction, its unpaired branch forwards anova2_cell outputs in columns, rows, and interaction order. When translating positional unpaired MATLAB results, EEGPrep’s rows value therefore corresponds to the second MATLAB cell and columns to the first. The MATLAB-shaped copies on matlab_stat, matlab_df, matlab_pvalue, and matlab_surrogate keep that unpaired cell order. Paired two-way cells stay in row, column, interaction order.

statcond accepts the same options as keywords or as positional name/value pairs. mode selects the method when it is non-empty. verbose defaults to off. Unpaired variance defaults to Welch’s inhomogenous formula, matching EEGLAB statcond finputcheck. ttest2_cell itself still defaults to equal variance. cluster="on" replaces one-way permutation p-values with cluster-extent results. The cluster-forming threshold uses the t or F degrees of freedom of the test. EEGLAB’s statcond.m lines 470 and 490 pass the feature count to tcdf: tcdf(-abs(surrogval), size(surrogval,1)) and tcdf(-abs(ori_vals), length(ori_vals)). returnresamplingarray is the name/value form of return_resampling_array. Those cells are drawn from a MATLAB rng('default') Twister. The Python samples stream is the rng argument. structoutput="on" puts the EEGLAB struct in the single MATLAB output; the Python return value remains a StatcondResult.

FieldTrip-style inference#

statcondfieldtrip is a standalone Python backend for the scientifically active behavior in EEGLAB’s FieldTrip wrapper. It accepts condition arrays directly and does not require MATLAB, EEGLAB, or FieldTrip at runtime. Cases occupy the final axis by default; all preceding feature axes are preserved in the statistic, p-value, and mask.

Supported designs are paired or equal-variance unpaired two-condition t-tests and unpaired one-way ANOVA. Analytic inference and seeded Monte Carlo permutation inference are available. Multiple-comparison options are none, bonferroni, holm, fdr, and Monte Carlo max or cluster correction; bonferoni and holms remain accepted migration spellings.

As in FieldTrip, Bonferroni, Holm, and FDR leave the reported pointwise pvalue unchanged and apply their correction to mask. Monte Carlo probabilities use a plus-one estimate, so finite randomization runs cannot report zero probability. Max-statistic correction returns family-wise corrected probabilities and masks; two-condition tests use absolute t values for conventional two-sided inference. This fulfills the EEGLAB wrapper’s documented two-tailed output contract directly; FieldTrip’s internal correcttail='alpha' representation instead pairs a one-tail probability with a halved alpha threshold.

Paired one-way and two-way ANOVA are rejected because the maintained EEGLAB test disables those FieldTrip paths. Use statcond for the supported paired and two-way ANOVA designs without FieldTrip correction.

Cluster correction requires method="montecarlo" and an explicit neighbours adjacency matrix. The matrix is square and symmetric over every feature in C-order-flattened result space; it may be a dense NumPy array or a SciPy sparse matrix. Its diagonal is ignored. EEGPrep does not infer sensor, time, or frequency neighbours because bare condition arrays contain no axis metadata. Construct the complete adjacency graph before calling the function. For channel-only statistics, std_prepare_neighbors already returns the usable matrix as limostruct["channeighbstructmat"]. Add time/frequency connectivity explicitly when those dimensions are present.

The supported cluster policy is a parametric cluster-forming threshold and FieldTrip’s default clusterstatistic="maxsum". Set clusteralpha to derive the critical t or F value, or provide a positive clustercritval directly. Positive and negative t-value clusters are formed separately. The largest absolute cluster mass across both signs is retained for every permutation, giving one direct two-sided family-wise null distribution; F tests use their right tail. This is intentionally more explicit than FieldTrip’s internal representation using separate one-tail probabilities and a corrected alpha threshold.

Paired two-condition permutations swap labels independently within each case; unpaired permutations pool case labels and split them back into the original group sizes. Integer naccu values use a seedable Monte Carlo sample and the plus-one probability estimate. naccu="all" enumerates the complete null space for designs requiring at most 100,000 assignments and reports exact frequencies. Cluster-corrected pvalue is constant within each observed cluster and one outside clusters. cluster_labels, clusters, cluster_null, and cluster_critical_value expose the inference details. Automatic channel geometry, nonparametric cluster-forming thresholds, max-size/weighted cluster statistics, minimum-neighbour pruning, and TFCE are explicitly unsupported.

Multiple Comparisons and Surrogates#

eegprep.fdr(pvals[, q, fdr_type])

Compute Benjamini-Hochberg or Benjamini-Yekutieli FDR thresholds.

eegprep.stat_surrogate_pvals(distribution, ...)

Compute empirical p-values against a surrogate distribution.

eegprep.stat_surrogate_ci(distribution[, ...])

Compute surrogate confidence intervals along the last axis.

eegprep.surrogdistrib(data, *[, method, ...])

Build bootstrap or permutation surrogate condition grids.

Data Helpers#

eegprep.concatdata(data, *[, axis])

Concatenate condition arrays along their case axis.

eegprep.corrcoef_cell(a[, b, axis])

Compute pairwise correlations along a case axis.

eegprep.teststat([seed])

Run deterministic smoke checks for the EEGPrep statistics package.

Clustering#

kmeans_st partitions rows with a UPGMA start and single-point moves. Labels are zero-based indices of those centroid rows. Restarts use a NumPy permutation, not MATLAB randperm. kmeanscluster initializes from the first rows and keeps that numbering.

eegprep.kmeans_st(data, clusters[, ...])

Partition rows with EEGLAB's Hartigan-Wong k-means.

eegprep.kmeanscluster(data[, clusters, ...])

Cluster row-wise observations using EEGLAB's simple k-means contract.

Effective Dimensionality#

numdim evaluates zero eigenvalue entropy terms by their analytic limit, so exactly rank-deficient inputs return a finite effective dimension.

eegprep.numdim(data)

Estimate a lower bound on the number of discrete sources in the data.