N170
trial_type subject session response stimulus
015 N170 320 320
016 N170 248 320
017 N170 322 320
018 N170 322 320
019 N170 322 320

5 rows × 4 columns

General
Filename(s) sub-015_ses-N170_task-N170_ave.fif
MNE object type Evoked
Measurement date Unknown
Participant sub-015
Experimenter Unknown
Acquisition
Aggregation average of 5 epochs
Condition Grand average: stimulus/face/normal
Time range -0.203 – 0.797 s
Baseline -0.203 – 0.000 s
Sampling frequency 128.00 Hz
Time points 129
Channels
EEG
Head & sensor digitization 33 points
Filters
Highpass 0.10 Hz
Lowpass 64.00 Hz
Time course (EEG)
Global field power
General
Filename(s) sub-015_ses-N170_task-N170_ave.fif
MNE object type Evoked
Measurement date Unknown
Participant sub-015
Experimenter Unknown
Acquisition
Aggregation average of 5 epochs
Condition Grand average: stimulus/car/normal
Time range -0.203 – 0.797 s
Baseline -0.203 – 0.000 s
Sampling frequency 128.00 Hz
Time points 129
Channels
EEG
Head & sensor digitization 33 points
Filters
Highpass 0.10 Hz
Lowpass 64.00 Hz
Time course (EEG)
Global field power
General
Filename(s) sub-015_ses-N170_task-N170_ave.fif
MNE object type Evoked
Measurement date Unknown
Participant sub-015
Experimenter Unknown
Acquisition
Aggregation average of 5 epochs
Condition Grand average: stimulus/face/normal - stimulus/car/normal
Time range -0.203 – 0.797 s
Baseline -0.203 – 0.000 s
Sampling frequency 128.00 Hz
Time points 129
Channels
EEG
Head & sensor digitization 33 points
Filters
Highpass 0.10 Hz
Lowpass 64.00 Hz
Time course (EEG)
Global field power
Full-epochs decoding
Based on N=5 subjects. Each dot represents the mean cross-validation score for a single subject. The dashed line is expected chance performance.
Decoding over time: stimulus/face/normal vs. stimulus/car/normal
Based on N=5 subjects. Standard error and confidence interval of the mean were bootstrapped with 5000 resamples. CI must not be used for statistical inference here, as it is not corrected for multiple testing. Time periods with decoding performance significantly above chance, if any, were derived with a one-tailed cluster-based permutation test (31 permutations) and are highlighted in yellow.
t-values across time: stimulus/face/normal vs. stimulus/car/normal
Observed t-values. Time points with t-values > 2.132 were used to form clusters.
Time generalization: stimulus/face/normal vs. stimulus/car/normal
Time generalization (generalization across time, GAT): each classifier is trained on each time point, and tested on all other time points. The results were averaged across N=5 subjects.
  """ERP CORE.

This example demonstrates how to process 5 participants from the
[ERP CORE](https://erpinfo.org/erp-core) dataset. It shows how to obtain 7 ERP
components from a total of 6 experimental tasks:

- N170 (face perception)
- MMN (passive auditory oddball)
- N2pc (visual search)
- N400 (word pair judgment)
- P3b (active visual oddball)
- LRP and ERN (flankers task)

## Dataset information

- **Authors:** Emily S. Kappenman, Jaclyn L. Farrens, Wendy Zhang,
                       Andrew X. Stewart, and Steven J. Luck
- **License:** CC-BY-4.0
- **URL:** [https://erpinfo.org/erp-core](https://erpinfo.org/erp-core)
- **Citation:** Kappenman, E., Farrens, J., Zhang, W., Stewart, A. X.,
                & Luck, S. J. (2021). ERP CORE: An open resource for human
                event-related potential research. *NeuroImage* 225: 117465.
                [https://doi.org/10.1016/j.neuroimage.2020.117465](https://doi.org/10.1016/j.neuroimage.2020.117465)
"""

import argparse
import sys

import mne

bids_root = "~/mne_data/ERP_CORE"
deriv_root = "~/mne_data/derivatives/mne-bids-pipeline/ERP_CORE"

# Find the --task option
args = [arg for arg in sys.argv if arg.startswith("--task") or not arg.startswith("-")]
parser = argparse.ArgumentParser()
parser.add_argument("ignored", nargs="*")
parser.add_argument(
    "--task", choices=("N400", "ERN", "LRP", "MMN", "N2pc", "N170", "P3"), required=True
)
task = parser.parse_args(args).task
sessions = [task]

subjects = ["015", "016", "017", "018", "019"]

ch_types = ["eeg"]
interactive = False

raw_resample_sfreq = 128
# Suppress "Data file name in EEG.data (sub-019_task-ERN_eeg.fdt) is incorrect..."
read_raw_bids_verbose = "error"

eeg_template_montage = mne.channels.make_standard_montage("standard_1005")
eeg_bipolar_channels = {
    "HEOG": ("HEOG_left", "HEOG_right"),
    "VEOG": ("VEOG_lower", "FP2"),
}
drop_channels = ["HEOG_left", "HEOG_right", "VEOG_lower"]
eog_channels = ["HEOG", "VEOG"]

l_freq = 0.1
h_freq = None
notch_freq = 60

decode = True
decoding_time_generalization = True
decoding_time_generalization_decim = 2

find_breaks = True
min_break_duration = 10
t_break_annot_start_after_previous_event = 3.0
t_break_annot_stop_before_next_event = 1.5

if task == "N400":  # test autoreject local without ICA
    spatial_filter = None
    reject = "autoreject_local"
    autoreject_n_interpolate = [2, 4]
elif task == "N170":  # test autoreject local before ICA
    spatial_filter = "ica"
    ica_reject = "autoreject_local"
    reject = "autoreject_global"
    autoreject_n_interpolate = [2, 4]
else:
    spatial_filter = "ica"
    ica_reject = dict(eeg=350e-6, eog=500e-6)
    reject = "autoreject_global"

# These settings are only used for the cases where spatial_filter="ica"
ica_max_iterations = 1000
ica_eog_threshold = 2
ica_decim = 2  # speed up ICA fitting

run_source_estimation = False
on_rename_missing_events = "ignore"

parallel_backend = "dask"
dask_worker_memory_limit = "2.5G"
n_jobs = 4

if task == "N400":
    dask_open_dashboard = True

    rename_events = {
        "response/201": "response/correct",
        "response/202": "response/error",
        "stimulus/111": "stimulus/prime/related",
        "stimulus/112": "stimulus/prime/related",
        "stimulus/121": "stimulus/prime/unrelated",
        "stimulus/122": "stimulus/prime/unrelated",
        "stimulus/211": "stimulus/target/related",
        "stimulus/212": "stimulus/target/related",
        "stimulus/221": "stimulus/target/unrelated",
        "stimulus/222": "stimulus/target/unrelated",
    }

    eeg_reference = ["P9", "P10"]
    epochs_tmin = -0.2
    epochs_tmax = 0.8
    epochs_metadata_tmin = 0
    epochs_metadata_tmax = 1.5
    epochs_metadata_keep_first = ["stimulus/target", "response"]
    baseline = (None, 0)

    conditions = {
        "related": '`first_stimulus/target` == "related" and '
        'first_response == "correct"',
        "unrelated": '`first_stimulus/target` == "unrelated" and '
        'first_response == "correct"',
    }
    contrasts = [("unrelated", "related")]
    cluster_forming_t_threshold = 1.5  # Only for testing!
    cluster_permutation_p_threshold = 0.2  # Only for testing!
elif task == "ERN":
    rename_events = {
        "stimulus/11": "compatible/left",
        "stimulus/12": "compatible/right",
        "stimulus/21": "incompatible/left",
        "stimulus/22": "incompatible/right",
        "response/111": "response/correct",
        "response/112": "response/incorrect",
        "response/121": "response/correct",
        "response/122": "response/incorrect",
        "response/211": "response/incorrect",
        "response/212": "response/correct",
        "response/221": "response/incorrect",
        "response/222": "response/correct",
    }

    eeg_reference = ["P9", "P10"]
    epochs_tmin = -0.6
    epochs_tmax = 0.4
    baseline = (-0.4, -0.2)
    conditions = ["response/correct", "response/incorrect"]
    contrasts = [("response/incorrect", "response/correct")]
    cluster_forming_t_threshold = 5  # Only for testing!
    cluster_permutation_p_threshold = 0.2  # Only for testing!
    decoding_csp = True
    decoding_csp_freqs = {
        "theta": [4, 7],
        "alpha": [8, 12],
        "beta": [13, 20, 30],
        "gamma": [50, 63],
    }
    decoding_csp_times = [-0.2, 0.0, 0.2, 0.4]
elif task == "LRP":
    rename_events = {
        "stimulus/11": "compatible/left",
        "stimulus/12": "compatible/right",
        "stimulus/21": "incompatible/left",
        "stimulus/22": "incompatible/right",
        "response/111": "response/left/correct",
        "response/112": "response/left/incorrect",
        "response/121": "response/left/correct",
        "response/122": "response/left/incorrect",
        "response/211": "response/right/incorrect",
        "response/212": "response/right/correct",
        "response/221": "response/right/incorrect",
        "response/222": "response/right/correct",
    }

    eeg_reference = ["P9", "P10"]
    epochs_tmin = -0.8
    epochs_tmax = 0.2
    baseline = (None, -0.6)
    conditions = ["response/left", "response/right"]
    contrasts = [("response/right", "response/left")]  # contralateral vs ipsi
elif task == "MMN":
    rename_events = {
        "stimulus/70": "stimulus/deviant",
        "stimulus/80": "stimulus/standard",
    }

    eeg_reference = ["P9", "P10"]
    epochs_tmin = -0.2
    epochs_tmax = 0.8
    baseline = (None, 0)
    conditions = ["stimulus/standard", "stimulus/deviant"]
    contrasts = [("stimulus/deviant", "stimulus/standard")]
elif task == "N2pc":
    rename_events = {
        "response/201": "response/correct",
        "response/202": "response/error",
        "stimulus/111": "stimulus/blue/left",
        "stimulus/112": "stimulus/blue/left",
        "stimulus/121": "stimulus/blue/right",
        "stimulus/122": "stimulus/blue/right",
        "stimulus/211": "stimulus/pink/left",
        "stimulus/212": "stimulus/pink/left",
        "stimulus/221": "stimulus/pink/right",
        "stimulus/222": "stimulus/pink/right",
    }

    eeg_reference = ["P9", "P10"]
    # Analyze all EEG channels -- we only specify the channels here for the purpose of
    # demonstration
    analyze_channels = [
        "FP1",
        "F3",
        "F7",
        "FC3",
        "C3",
        "C5",
        "P3",
        "P7",
        "P9",
        "PO7",
        "PO3",
        "O1",
        "Oz",
        "Pz",
        "CPz",
        "FP2",
        "Fz",
        "F4",
        "F8",
        "FC4",
        "FCz",
        "Cz",
        "C4",
        "C6",
        "P4",
        "P8",
        "P10",
        "PO8",
        "PO4",
        "O2",
    ]

    epochs_tmin = -0.2
    epochs_tmax = 0.8
    baseline = (None, 0)
    conditions = ["stimulus/right", "stimulus/left"]
    contrasts = [("stimulus/right", "stimulus/left")]  # Contralteral vs ipsi
elif task == "N170":
    rename_events = {
        "response/201": "response/correct",
        "response/202": "response/error",
    }

    eeg_reference = "average"
    # Analyze all EEG channels -- we only specify the channels here for the purpose of
    # demonstration
    analyze_channels = [
        "FP1",
        "F3",
        "F7",
        "FC3",
        "C3",
        "C5",
        "P3",
        "P7",
        "P9",
        "PO7",
        "PO3",
        "O1",
        "Oz",
        "Pz",
        "CPz",
        "FP2",
        "Fz",
        "F4",
        "F8",
        "FC4",
        "FCz",
        "Cz",
        "C4",
        "C6",
        "P4",
        "P8",
        "P10",
        "PO8",
        "PO4",
        "O2",
    ]

    ica_n_components = 30 - 1
    for i in range(1, 180 + 1):
        orig_name = f"stimulus/{i}"

        if 1 <= i <= 40:
            new_name = "stimulus/face/normal"
        elif 41 <= i <= 80:
            new_name = "stimulus/car/normal"
        elif 101 <= i <= 140:
            new_name = "stimulus/face/scrambled"
        elif 141 <= i <= 180:
            new_name = "stimulus/car/scrambled"
        else:
            continue

        rename_events[orig_name] = new_name

    epochs_tmin = -0.2
    epochs_tmax = 0.8
    baseline = (None, 0)
    conditions = ["stimulus/face/normal", "stimulus/car/normal"]
    contrasts = [("stimulus/face/normal", "stimulus/car/normal")]
elif task == "P3":
    rename_events = {
        "response/201": "response/correct",
        "response/202": "response/incorrect",
        "stimulus/11": "stimulus/target/11",
        "stimulus/22": "stimulus/target/22",
        "stimulus/33": "stimulus/target/33",
        "stimulus/44": "stimulus/target/44",
        "stimulus/55": "stimulus/target/55",
        "stimulus/21": "stimulus/non-target/21",
        "stimulus/31": "stimulus/non-target/31",
        "stimulus/41": "stimulus/non-target/41",
        "stimulus/51": "stimulus/non-target/51",
        "stimulus/12": "stimulus/non-target/12",
        "stimulus/32": "stimulus/non-target/32",
        "stimulus/42": "stimulus/non-target/42",
        "stimulus/52": "stimulus/non-target/52",
        "stimulus/13": "stimulus/non-target/13",
        "stimulus/23": "stimulus/non-target/23",
        "stimulus/43": "stimulus/non-target/43",
        "stimulus/53": "stimulus/non-target/53",
        "stimulus/14": "stimulus/non-target/14",
        "stimulus/24": "stimulus/non-target/24",
        "stimulus/34": "stimulus/non-target/34",
        "stimulus/54": "stimulus/non-target/54",
        "stimulus/15": "stimulus/non-target/15",
        "stimulus/25": "stimulus/non-target/25",
        "stimulus/35": "stimulus/non-target/35",
        "stimulus/45": "stimulus/non-target/45",
    }

    eeg_reference = ["P9", "P10"]
    epochs_tmin = -0.2
    epochs_tmax = 0.8
    baseline = (None, 0)
    conditions = ["stimulus/target", "stimulus/non-target"]
    contrasts = [("stimulus/target", "stimulus/non-target")]
    cluster_forming_t_threshold = 0.8  # Only for testing!
    cluster_permutation_p_threshold = 0.2  # Only for testing!
else:
    raise RuntimeError(f"Task {task} not currently supported")

  Platform             Linux-5.15.0-1057-aws-x86_64-with-glibc2.35
Python               3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
Executable           /home/circleci/python_env/bin/python3.10
CPU                  x86_64 (36 cores)
Memory               68.6 GB

Core
├☑ mne               1.8.0.dev79+gcaba81b9f (devel, latest release is 1.7.1)
├☑ numpy             2.0.0 (OpenBLAS 0.3.27 with 2 threads)
├☑ scipy             1.13.1
└☑ matplotlib        3.9.0 (backend=agg)

Numerical (optional)
├☑ sklearn           1.5.0
├☑ numba             0.60.0
├☑ nibabel           5.2.1
├☑ pandas            2.2.2
├☑ h5io              0.2.3
├☑ h5py              3.11.0
└☐ unavailable       nilearn, dipy, openmeeg, cupy

Visualization (optional)
├☑ pyvista           0.43.10 (OpenGL 4.5 (Core Profile) Mesa 23.2.1-1ubuntu3.1~22.04.2 via llvmpipe (LLVM 15.0.7, 256 bits))
├☑ pyvistaqt         0.11.1
├☑ vtk               9.3.0
├☑ qtpy              2.4.1 (PyQt6=6.7.1)
└☐ unavailable       ipympl, pyqtgraph, mne-qt-browser, ipywidgets, trame_client, trame_server, trame_vtk, trame_vuetify

Ecosystem (optional)
├☑ mne-bids          0.16.0.dev3+g0e3cbc66a
├☑ mne-bids-pipeline 1.9.0
├☑ eeglabio          0.0.2-4
├☑ edfio             0.4.2
├☑ pybv              0.7.5
└☐ unavailable       mne-nirs, mne-features, mne-connectivity, mne-icalabel, neo, mffpy