Epochs: Autoreject cleaning
Autoreject was run to produce cleaner epochs before fitting ICA. 17 epochs were rejected because more than {'eeg': 2} channels were bad (cross-validated n_interpolate limit; excluding globally bad and non-data channels, shown in white). Note that none of the blue segments were actually interpolated before submitting the data to ICA. This is following the recommended approach for ICA described in the the Autoreject documentation.
Number of events 143
Events stimulus/car/normal: 69
stimulus/face/normal: 74
Time range -0.203 – 0.797 s
Baseline off
Epoch # event_name response/correct response/error stimulus/car/normal stimulus/car/scrambled stimulus/face/normal stimulus/face/scrambled
0 stimulus/face/normal 0.414 0.000
1 stimulus/car/normal 0.586 0.000
2 stimulus/face/normal 0.445 0.000
3 stimulus/face/normal 0.398 0.000
4 stimulus/face/normal 0.422 0.000
5 stimulus/car/normal 0.594 0.000
6 stimulus/car/normal 0.453 0.000
7 stimulus/face/normal 0.508 0.000
8 stimulus/car/normal 0.609 0.000
9 stimulus/car/normal 0.477 0.000
10 stimulus/car/normal 0.453 0.000
11 stimulus/car/normal 0.531 0.000
12 stimulus/face/normal 0.602 0.000
13 stimulus/car/normal 0.477 0.000
14 stimulus/face/normal 0.453 0.000
15 stimulus/face/normal 0.414 0.000
16 stimulus/face/normal 0.492 0.000
17 stimulus/car/normal 0.578 0.000
18 stimulus/face/normal 0.719 0.000
19 stimulus/face/normal 0.414 0.000
20 stimulus/face/normal 0.352 0.000
21 stimulus/car/normal 0.391 0.000
22 stimulus/face/normal 0.414 0.000
23 stimulus/car/normal 0.758 0.000
24 stimulus/face/normal 0.414 0.000
25 stimulus/face/normal 0.469 0.000
26 stimulus/car/normal 0.422 0.000
27 stimulus/car/normal 0.430 0.000
28 stimulus/face/normal 0.562 0.000
29 stimulus/car/normal 0.422 0.000
31 stimulus/face/normal 0.383 0.000
33 stimulus/face/normal 0.430 0.000
35 stimulus/car/normal 0.461 0.000
36 stimulus/car/normal 0.430 0.000
37 stimulus/face/normal 0.539 0.000
38 stimulus/car/normal 0.445 0.000
39 stimulus/car/normal 0.586 0.000
40 stimulus/car/normal 0.508 0.000
41 stimulus/face/normal 0.383 0.000
42 stimulus/car/normal 0.469 0.000
44 stimulus/car/normal 0.484 0.000
45 stimulus/face/normal 0.523 0.000
46 stimulus/face/normal 0.555 0.000
47 stimulus/car/normal 0.539 0.000
48 stimulus/car/normal 0.508 0.000
49 stimulus/face/normal 0.453 0.000
50 stimulus/car/normal 0.422 0.000
52 stimulus/car/normal 0.500 0.000
53 stimulus/car/normal 0.508 0.000
54 stimulus/car/normal 0.000
56 stimulus/car/normal 0.391 0.000
57 stimulus/car/normal 0.375 0.000
58 stimulus/face/normal 0.438 0.000
59 stimulus/face/normal 0.359 0.000
60 stimulus/face/normal 0.477 0.000
61 stimulus/car/normal 0.500 0.000
63 stimulus/car/normal 0.344 0.000
64 stimulus/face/normal 0.461 0.000
65 stimulus/car/normal 0.461 0.000
66 stimulus/face/normal 0.539 0.000
67 stimulus/car/normal 0.383 0.000
69 stimulus/face/normal 0.508 0.000
70 stimulus/car/normal 0.414 0.000
71 stimulus/car/normal 0.523 0.000
72 stimulus/face/normal 0.641 0.000
73 stimulus/face/normal 0.281 0.000
74 stimulus/face/normal 0.289 0.000
75 stimulus/face/normal 0.328 0.000
76 stimulus/car/normal 0.570 0.000
78 stimulus/face/normal 0.391 0.000
79 stimulus/car/normal 0.383 0.000
80 stimulus/car/normal 0.359 0.000
81 stimulus/face/normal 0.516 0.000
82 stimulus/face/normal 0.352 0.000
83 stimulus/car/normal 0.438 0.000
84 stimulus/face/normal 0.344 0.000
85 stimulus/face/normal 0.359 0.000
86 stimulus/car/normal 0.641 0.000
87 stimulus/car/normal 0.484 0.000
88 stimulus/face/normal 0.383 0.000
89 stimulus/face/normal 0.383 0.000
90 stimulus/car/normal 0.398 0.000
92 stimulus/car/normal 0.531 0.000
93 stimulus/face/normal 0.492 0.000
94 stimulus/face/normal 0.445 0.000
95 stimulus/face/normal 0.461 0.000
96 stimulus/face/normal 0.500 0.000
97 stimulus/face/normal 0.344 0.000
98 stimulus/face/normal 0.375 0.000
99 stimulus/face/normal 0.383 0.000
100 stimulus/face/normal 0.422 0.000
102 stimulus/car/normal 0.367 0.000
103 stimulus/car/normal 0.352 0.000
104 stimulus/car/normal 0.414 0.000
105 stimulus/face/normal 0.445 0.000
106 stimulus/face/normal 0.352 0.000
107 stimulus/face/normal 0.484 0.000
108 stimulus/car/normal 0.492 0.000
109 stimulus/car/normal 0.523 0.000
110 stimulus/face/normal 0.375 0.000
111 stimulus/car/normal 0.367 0.000
112 stimulus/face/normal 0.414 0.000
113 stimulus/face/normal 0.328 0.000
114 stimulus/car/normal 0.453 0.000
115 stimulus/car/normal 0.398 0.000
116 stimulus/car/normal 0.430 0.000
117 stimulus/car/normal 0.391 0.000
118 stimulus/car/normal 0.359 0.000
119 stimulus/face/normal 0.430 0.000
120 stimulus/face/normal 0.359 0.000
121 stimulus/car/normal 0.398 0.000
122 stimulus/face/normal 0.367 0.000
123 stimulus/car/normal 0.438 0.000
124 stimulus/face/normal 0.422 0.000
126 stimulus/face/normal 0.430 0.000
127 stimulus/face/normal 0.438 0.000
128 stimulus/face/normal 0.438 0.000
129 stimulus/face/normal 0.445 0.000
130 stimulus/face/normal 0.398 0.000
131 stimulus/car/normal 0.344 0.000
132 stimulus/face/normal 0.508 0.000
133 stimulus/face/normal 0.383 0.000
134 stimulus/car/normal 0.609 0.000
136 stimulus/car/normal 0.461 0.000
137 stimulus/car/normal 0.617 0.000
138 stimulus/face/normal 0.398 0.000
139 stimulus/car/normal 0.422 0.000
140 stimulus/car/normal 0.453 0.000
142 stimulus/car/normal 0.422 0.000
143 stimulus/face/normal 0.492 0.000
144 stimulus/face/normal 0.500 0.000
145 stimulus/face/normal 0.445 0.000
146 stimulus/car/normal 0.586 0.000
149 stimulus/face/normal 0.492 0.000
150 stimulus/car/normal 0.484 0.000
151 stimulus/car/normal 0.430 0.000
152 stimulus/car/normal 0.445 0.000
153 stimulus/face/normal 0.641 0.000
154 stimulus/face/normal 0.461 0.000
155 stimulus/car/normal 0.383 0.000
156 stimulus/face/normal 0.461 0.000
157 stimulus/face/normal 0.367 0.000
159 stimulus/car/normal 0.406 0.000

143 rows × 8 columns

Drop log
PSD
PSD calculated from 143 epochs (143.0 s).
Method picard
Fit parameters fastica_it=5
max_iter=1000
Fit 110 iterations on epochs (9295 samples)
ICA components 29
Available PCA components 30
Channel types eeg
ICA components marked for exclusion ICA001
ICA002
ICA014
ICA020
ICA028
  """ERP CORE.

This example demonstrate 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-1053-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.7.0.dev156+g415e7f68e (devel, latest release is 1.6.1)
├☑ numpy             1.26.4 (OpenBLAS 0.3.23.dev with 2 threads)
├☑ scipy             1.12.0
└☑ matplotlib        3.8.3 (backend=agg)

Numerical (optional)
├☑ sklearn           1.4.1.post1
├☑ numba             0.59.1
├☑ nibabel           5.2.1
├☑ pandas            2.2.1
└☐ unavailable       nilearn, dipy, openmeeg, cupy

Visualization (optional)
├☑ pyvista           0.43.4 (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.0
├☑ vtk               9.3.0
├☑ qtpy              2.4.1 (PyQt6=6.6.0)
└☐ unavailable       ipympl, pyqtgraph, mne-qt-browser, ipywidgets, trame_client, trame_server, trame_vtk, trame_vuetify

Ecosystem (optional)
├☑ mne-bids          0.15.0.dev43+g17d20c132
├☑ mne-bids-pipeline 1.8.0
└☐ unavailable       mne-nirs, mne-features, mne-connectivity, mne-icalabel, neo