Preprocessing Pipeline#

This page describes a practical preprocessing order in EEGPrep. It is not a mandatory recipe for every experiment. Adapt thresholds and review steps to your data, task, and lab standards.

Start From Sample Data#

from pathlib import Path
from eegprep import pop_loadset

EEG = pop_loadset(Path("sample_data") / "eeglab_data.set")
print(EEG["data"].shape, EEG["srate"], len(EEG["event"]))

Select Data and Channels#

Use pop_select for user-facing channel, point, time, trial, and event selection:

from eegprep import pop_select

EEG, com = pop_select(EEG, channel=[1, 2, 3, 4, 5], return_com=True)

GUI path: Edit > Select data. Channel/component values in GUI dialogs are EEGLAB-facing one-based values.

Filter#

The usual FIR filtering entry point is pop_eegfiltnew:

from eegprep import pop_eegfiltnew

EEG, com = pop_eegfiltnew(
    EEG,
    locutoff=1.0,
    hicutoff=40.0,
    plotfreqz=False,
    return_com=True,
)

GUI path: Tools > Filter the data. The wrapper uses bundled FIRFilt-style Hamming-window defaults, respects continuous-data boundary events, clears stale ICA activations, and returns a replayable history command.

Use FIRFilt helpers for custom filter design:

from eegprep import pop_firws, pop_firwsord, pop_kaiserbeta

beta = pop_kaiserbeta(0.001)
order = pop_firwsord("kaiser", EEG["srate"], 2, 0.001)
EEG, com = pop_firws(
    EEG,
    fcutoff=[1, 40],
    ftype="bandpass",
    wtype="kaiser",
    warg=beta,
    forder=order,
    return_com=True,
)

Clean Continuous Data#

Use pop_clean_rawdata when you want the interactive wrapper and history string:

from eegprep import pop_clean_rawdata

EEG, com = pop_clean_rawdata(
    EEG,
    FlatlineCriterion=5,
    ChannelCriterion=0.8,
    LineNoiseCriterion=4,
    Highpass=(0.25, 0.75),
    BurstCriterion=20,
    WindowCriterion=0.25,
    return_com=True,
)

Use clean_artifacts when you need lower-level state outputs:

from eegprep import clean_artifacts

clean_eeg, highpass_state, burst_state, removed_channels = clean_artifacts(
    EEG,
    FlatlineCriterion=5,
    ChannelCriterion=0.8,
    LineNoiseCriterion=4,
    Highpass=(0.25, 0.75),
    BurstCriterion=20,
    WindowCriterion=0.25,
)

clean_artifacts returns four values. Scripts that only need the cleaned EEG should use the first value or call pop_clean_rawdata.

Sampling Rates#

ASR calibration designs its spectral-shaping filter for whatever sampling rate the dataset has, so no resampling is required beforehand. Clinical and consumer amplifier rates that are not round numbers, such as 258 Hz, work directly.

Riemannian ASR Notes#

EEGPrep supports the Riemannian ASR calibration variant through clean_asr(EEG, useriemannian="calib") and clean_artifacts(EEG, Distance="Riemannian"). Full Riemannian ASR processing is not ported, so direct full-process requests fail clearly instead of silently substituting MATLAB-only behavior.

Review Rejected Segments#

vis_artifacts(clean_eeg, original_eeg) opens an EEG browser with rejected sample intervals highlighted from clean_sample_mask. Use show=False when scripting diagnostics:

from eegprep import vis_artifacts

diagnostics = vis_artifacts(clean_eeg, EEG, show=False)
print(diagnostics["rejected_fraction"])

Resample#

Resample after early cleaning/filtering when a lower sampling rate is appropriate:

from eegprep import pop_resample

EEG, com = pop_resample(EEG, 64, return_com=True)

GUI path: Tools > Change sampling rate. Continuous data with boundary events is resampled by segment. Event latencies and the time vector are updated.

Re-Reference and Interpolate#

Average reference:

from eegprep import pop_reref

EEG, com = pop_reref(EEG, [], return_com=True)

Interpolate known bad channels after channel removal or rejection:

from eegprep import pop_interp

EEG, com = pop_interp(EEG, [0, 4, 9], return_com=True)

Use Tools > Re-reference the data and Tools > Interpolate electrodes from the GUI.

The programmatic bad_elec list for pop_interp uses Python zero-based indices when integers are supplied. GUI channel selection remains one-based and label-driven.

Run ICA and ICLabel#

Run ICA:

from eegprep import pop_runica

EEG, com = pop_runica(EEG, icatype="picard", gui=False, return_com=True)

Label and review components:

from eegprep import eeg_icalabelstat, pop_iclabel, pop_viewprops

EEG, com = pop_iclabel(EEG, "default", return_com=True)
stats = eeg_icalabelstat(EEG, threshold=0.9, verbose=False)
figures = pop_viewprops(EEG, typecomp=0, chanorcomp=[1, 2, 3])

See ICA, ICLabel, Rejection, and Visual Diagnostics before removing components.

Time-Frequency and ERP Images#

After epoching or component review, use EEGPrep’s standalone time-frequency wrappers for the common EEGLAB plotting workflows:

from eegprep import pop_newcrossf, pop_newtimef, pop_spectopo

ersp, com_timef = pop_newtimef(EEG, typeproc=1, num=1, return_com=True)
cross, com_crossf = pop_newcrossf(EEG, typeproc=1, num1=1, num2=2, return_com=True)
spectra, com_spectopo = pop_spectopo(EEG, 1, timerange=[], return_com=True)

Legacy pop_timef and pop_crossf calls route through the standalone pop_newtimef and pop_newcrossf implementations. ERP-image workflows use pop_erpimage for channel or component images:

from eegprep import pop_erpimage

image, com = pop_erpimage(EEG, typeplot=1, index=1, return_com=True)

GUI paths live under the Plot menu when a dataset is loaded. EEGPrep returns replayable Python history commands for these wrappers. Some MATLAB-only pop_erpimage event-alignment and advanced renormalization options are not standalone EEGPrep features; those requests raise explicit errors instead of silently substituting a different analysis.

Epoch and Baseline#

Use pop_epoch and pop_rmbase for ERP-style workflows:

from eegprep import pop_epoch, pop_rmbase

EEG, com_epoch = pop_epoch(EEG, ["square"], [-1, 2], return_com=True)
EEG, com_base = pop_rmbase(EEG, [-200, 0], return_com=True)

GUI paths: Tools > Extract epochs and Tools > Remove epoch baseline.

Save#

Save reviewed datasets with pop_saveset:

from pathlib import Path
from eegprep import pop_saveset

pop_saveset(EEG, Path("sample_data") / "eeglab_data_preprocessed.set")

For large datasets, review Large-Dataset Storage before deciding whether to keep data in memory, memory-map sidecar files, or retrieve offloaded datasets.

Quality Control Checklist#

  • Confirm EEG["data"].shape after each major transform.

  • Inspect events after filtering/resampling and before epoching.

  • Review rejected channels/windows visually before final removal.

  • Inspect ICLabel probabilities, scalp maps, spectra, and activity before removing components.

  • Keep LASTCOM and ALLCOM from GUI/console runs so the workflow can be replayed in scripts.