STUDY Workflows#
EEGPrep includes standalone STUDY/session surfaces for common group-level workflows. These APIs mirror EEGLAB’s STUDY-facing names while storing cached measure data in EEGPrep-owned JSON-safe structures.
GUI Plus Console Flow#
Load two or more datasets, then use File > Create study > Using all loaded
datasets. eegprep-console will show STUDY and CURRENTSTUDY update
immediately. Continue with Study > Precompute channel measures and
Study > Plot channel measures when the selected datasets have compatible
metadata and shapes.
The same workflow in Python can reuse the sample epoched ICA dataset:
from pathlib import Path
from eegprep import pop_loadset, pop_precomp, pop_study
ALLEEG = [
pop_loadset(Path("sample_data") / "eeglab_data_epochs_ica.set"),
pop_loadset(Path("sample_data") / "eeglab_data_epochs_ica.set"),
]
for index, EEG in enumerate(ALLEEG, start=1):
EEG["subject"] = f"S{index:02d}"
EEG["condition"] = "tutorial"
STUDY, ALLEEG, com = pop_study(None, ALLEEG, name="Tutorial study", return_com=True)
STUDY, ALLEEG, com = pop_precomp(STUDY, ALLEEG, "channels", erp="on", return_com=True)
Implemented Workflows#
Create a STUDY from loaded datasets:
from eegprep import pop_study
STUDY, ALLEEG, com = pop_study(None, ALLEEG, name="My study", return_com=True)
Create a simple ERP STUDY:
from eegprep import pop_studyerp
STUDY, ALLEEG, com = pop_studyerp(ALLEEG, return_com=True)
Build and inspect design variables:
from eegprep import pop_importgroupvar, pop_listfactors, std_builddesignmat
STUDY, com = pop_importgroupvar(
STUDY,
1,
variable="age_group",
values={"S01": "young", "S02": "older"},
return_com=True,
)
factors = pop_listfactors(STUDY, constant="off")
design_matrix, labels, categorical = std_builddesignmat(
STUDY["design"][0],
[{"condition": "target", "rt": 300.0}, {"condition": "standard", "rt": 400.0}],
expanding=True,
)
Load and save EEGPrep .study files:
from eegprep import pop_loadstudy, pop_savestudy
STUDY, com = pop_savestudy(STUDY, EEG, "analysis.study", return_com=True)
STUDY, ALLEEG, com = pop_loadstudy("analysis.study", return_com=True)
Precompute and plot STUDY measures:
from eegprep import pop_chanplot, pop_precomp, std_erpplot, std_readitc
STUDY, ALLEEG, com = pop_precomp(
STUDY,
ALLEEG,
"channels",
erp="on",
spec="on",
return_com=True,
)
STUDY, com, fig = pop_chanplot(STUDY, ALLEEG, measure="erp", return_com=True)
STUDY, erpdata, erptimes, fig = std_erpplot(STUDY, ALLEEG, channels=[1])
STUDY, itcdata, itctimes, itcfreqs = std_readitc(STUDY, ALLEEG, channels=[1])
Channel measures are stored in STUDY.changrp. Component measures are stored
on the parent STUDY.cluster[0] entry so preclustering can read the same
cached arrays. Cached measure fields follow EEGLAB names such as erpdata,
specdata, erspdata, and itcdata. The selected design is recorded
in each measure group’s metadata. EEGPrep stores dataset-level averages in the
current standalone cache rather than EEGLAB sidecar measure files.
pop_chanplot reads cached channel and component measures through the same
std_readdata/std_erpplot/std_erspplot cache contract used by scripts,
so GUI and console plots slice axes and cached channel groups consistently.
Use std_checkfiles, std_checkdatasession, std_uniformfiles, and
std_uniformsetinds to audit loaded dataset consistency and cached measure
shapes before saving or plotting group-level results. std_savedat writes
explicit EEGPrep-owned JSON or MATLAB-compatible measure sidecars when a
workflow needs a durable array file outside the .study JSON.
Select datasets or trials from STUDY metadata:
from eegprep import std_getindvar, std_maketrialinfo, std_selectdataset
STUDY, trialinfo = std_maketrialinfo(STUDY, ALLEEG)
factors, factor_values, subjects, paired = std_getindvar(STUDY)
dataset_indices, trial_indices = std_selectdataset(
STUDY,
ALLEEG,
"condition",
["target"],
)
These helpers return EEGLAB-facing 1-based dataset and trial indices. Trial
metadata may be stored as row dictionaries or as EEGLAB-loaded columnar
{"factor": [values...]} dictionaries; STUDY selectors normalize both forms
before matching factor levels and numerical ranges. Use std_substudy or
std_rmdat when a workflow needs to remove datasets; EEGPrep remaps STUDY
references and invalidates cached measure arrays after membership changes.
std_findsameica groups matching ICA decompositions within each subject.
This preserves the subject boundary used by STUDY designs instead of merging
identical test fixtures across subjects.
Precluster and cluster ICA components:
from eegprep import pop_clust, pop_clustedit, pop_preclust
STUDY, ALLEEG, com = pop_preclust(
STUDY,
ALLEEG,
preproc=[{"measure": "scalp", "npca": 3, "norm": 1, "weight": 1}],
return_com=True,
)
STUDY, com = pop_clust(STUDY, ALLEEG, clus_num=4, random_state=0, return_com=True)
STUDY, com, fig = pop_clustedit(STUDY, ALLEEG, action="plot", return_com=True)
Finite outliers values in pop_clust use the EEGLAB-compatible
robust_kmeans path and record ["robust_kmeans", clus_num] in each
created cluster’s algorithm provenance. Infinite outliers keeps the plain
k-means path. In both cases command history remains pasteable in
eegprep-console.
DIPFIT Source Localization#
EEGPrep includes standalone DIPFIT-compatible spherical workflows for ICA component source localization. Configure DIPFIT metadata first, then run a coarse grid search, nonlinear refinement, and dipole plotting:
from eegprep.plugins.dipfit.pop_dipfit_settings import pop_dipfit_settings
from eegprep.plugins.dipfit.pop_dipfit_gridsearch import pop_dipfit_gridsearch
from eegprep.plugins.dipfit.pop_dipfit_nonlinear import pop_dipfit_nonlinear
from eegprep.plugins.dipfit.pop_dipplot import pop_dipplot
EEG, com = pop_dipfit_settings(EEG, model="standardBESA", return_com=True)
EEG, com = pop_dipfit_gridsearch(
EEG,
[1],
[-40, -20, 0, 20, 40],
[-40, -20, 0, 20, 40],
[20, 40, 60],
40,
return_com=True,
)
EEG, com = pop_dipfit_nonlinear(EEG, component=1, return_com=True)
figures, com = pop_dipplot(EEG, [1], summary="on", projlines="on", return_com=True)
The spherical backend fits an average-referenced leadfield, stores
posxyz, momxyz, rv, diffmap, sourcepot, and datapot in
EEG.dipfit.model, and keeps command history replayable from
eegprep-console. pop_multifit chains grid search, nonlinear fitting,
RV rejection, optional outside-head removal, and optional dipole plotting.
The deprecated EEGLAB aliases pop_dipfit_batch and pop_dipfit_manual
remain available for script compatibility.
pop_leadfield can compute spherical leadfields for explicit source points
provided as an Nx3 array, {"pos": ...} dictionary, or simple file with
source positions. MRI-derived BEM headmodel creation, AFNI atlas clipping, and
LORETA source analysis remain explicit backend limits and fail clearly rather
than producing placeholder source-localization outputs.
Session Synchronization#
The GUI and eegprep-console share STUDY and CURRENTSTUDY through
EEGPrepSession. Creating or loading a STUDY from the GUI sets
CURRENTSTUDY to 1. Retrieving a dataset from the Datasets menu returns
CURRENTSTUDY to 0 and records that transition in history.
Integration Notes#
Component ERP, spectrum, ERSP, and ITC arrays are cached on the parent
STUDY.cluster[0] entry. Preclustering reads those cached component arrays
and can also build scalp-map features directly from loaded ICA maps. MATLAB
parity checks focus on deterministic metadata and cluster structure; exact
numeric clustering labels can differ because EEGPrep uses deterministic
in-package k-means helpers rather than MATLAB’s Statistics Toolbox.
PAC, LIMO Design, And Neighbors#
EEGPrep includes a standalone PAC backend for practical channel workflows.
Use pac for epoched phase-amplitude coupling grids and pac_cont for
continuous sliding-window PAC. At the STUDY level, std_pac computes
EEGPrep-owned pacdata, pactimes, and pacfreqs caches on
STUDY.changrp. std_readpac slices those caches and std_pacplot
plots their magnitude using the same cache-reading contract as the other
STUDY measure plots.
Empirical p-value conventions are explicit. pac applies the common
(exceedances + 1) / (permutations + 1) finite-sample convention,
bootstat exposes exact permutation proportions for bootstrap helper tests,
and statistics helpers such as stat_surrogate_pvals follow EEGLAB’s
surrogate-tail convention with FDR correction available through the statistics
module. These definitions are intentionally not collapsed when they answer
different inferential questions.
The feasible in-package LIMO-compatible layer is design preparation:
std_limodesign builds categorical and continuous matrices from
pop_listfactors output and trial metadata, including interaction and split
regressor descriptions. It can write categorical_variables.txt and
continuous_variables.txt for downstream analysis code.
std_prepare_neighbors creates a distance-based FieldTrip-like neighbor
list and a LIMO-compatible channel adjacency matrix from loaded channel
locations. std_interp interpolates requested missing channels across
STUDY datasets using EEGPrep’s existing channel interpolation backend.
Limitations#
EEGPrep does not silently emulate EEGLAB’s external LIMO toolbox. pop_limo,
pop_limoresults, std_limo, std_limoresults, and
std_readfilelimo raise clear NotImplementedError messages rather than
creating placeholder LIMO results.
STUDY-level DIPFIT/FieldTrip source workflows such as std_dipplot and
std_dipoleclusters remain explicit source-backend boundaries. Use the
dedicated EEGPrep DIPFIT helpers for dataset-level source workflows and keep
STUDY source statistics behind a tested backend contract.
See the Interactive Console guide for mixed GUI plus console usage and the GUI and Help Menus guide for menu inventory behavior.