Hello,
I was trying to assess how the adaptative z-scoring of ica.find_bads_eog
and ica.find_bads_ecg
was performing, and I now face a behavior that I can not explain.
I start by loading one of my -raw.fif
file and I apply filters/rereferencing. The file include 64 EEG channels + 1 EOG channel and 1 ECG channel.
I fit an ICA with this raw
instance.
I look for the components correlating with the EOG and ECG channel (ica.find_bads_exg
methods) and I exclude them.
I copy the raw
instance and apply the ICA to it.
I look for the components correlating with the EOG and ECG channel of the copied instance.
I was expecting to find exactly the same, as the EOG and ECG channels are not modified by ica.apply
. Am I wrong in assuming the methods ica.find_bads_eog
and ica.find_bads_ecg
are correlating with the EOG and ECG channel?
Reproducible example:
import mne
import numpy as np
# Load
fname = 'sample-raw.fif'
raw = mne.io.read_raw_fif(fname, preload=True)
mne.rename_channels(raw.info, {"AUX7": "EOG", "AUX8": "ECG"})
raw.set_channel_types(mapping={"ECG": "ecg", "EOG": "eog"})
mapping = {
"FP1": "Fp1",
"FPZ": "Fpz",
"FP2": "Fp2",
"FZ": "Fz",
"CZ": "Cz",
"PZ": "Pz",
"POZ": "POz",
"FCZ": "FCz",
"OZ": "Oz",
"FPz": "Fpz",
}
for key, value in mapping.items():
try:
mne.rename_channels(raw.info, {key: value})
except Exception:
pass
# Filter and montage
raw.filter(l_freq=1., h_freq=40., picks=['eog', 'ecg'], phase="zero-double",
pad="edge")
raw.notch_filter(np.arange(50, 151, 50), picks=['eog', 'ecg']) # Yes, not necessary
raw.add_reference_channels(ref_channels='CPz')
raw.set_montage('standard_1020')
raw.set_eeg_reference(
ref_channels="average", ch_type="eeg", projection=True)
raw.filter(l_freq=1., h_freq=40., picks='eeg', phase="zero-double",
pad="edge")
# ICA
ica = mne.preprocessing.ICA(method='picard', max_iter='auto', random_state=101)
ica.fit(raw, picks='eeg', reject_by_annotation=False) # No annotations
# Correlation
eog_idx_raw, eog_scores_raw = ica.find_bads_eog(raw)
ecg_idx_raw, ecg_scores_raw = ica.find_bads_ecg(raw)
ica.exclude = eog_idx_raw + ecg_idx_raw
# Apply ICA
raw_ica_applied = raw.copy()
ica.apply(raw_ica_applied)
# Correlation with applied ICA
ica.exclude = list()
eog_idx_raw_ica_applied, eog_scores_raw_ica_applied = ica.find_bads_eog(raw_ica_applied)
ecg_idx_raw_ica_applied, ecg_scores_raw_ica_applied = ica.find_bads_ecg(raw_ica_applied)
File to run: (available 24h, ask for re-upload).
https://file.re/2021/10/13/sample-raw/
Running 0.23.0. Output:
eog_idx_raw
Out[15]: [0]
ecg_idx_raw
Out[16]: [26, 19]
eog_idx_raw_ica_applied
Out[17]: [0, 26, 19]
ecg_idx_raw_ica_applied
Out[18]: []
Mathieu