- MNE version: e.g. 1.0.3
- operating system: Windows 10
Hi there,
I’m trying to correct EOG artifacts using ICA and I’m having a problem. The data that I’m using is these PhysioNet Polysomnography files that can be accessed using this function:
mne.datasets.sleep_physionet.age.fetch_data
I have two EEG channels and one horizontal EOG channel and also some other channels that I don’t need like temperature recordings. I’m trying to use the EOG channel to remove the artifacts from the two EEG channels but it seems that the independent components that are made are almost identical to the original EEG channels which means that the EOG data is probably not used for some reason. I would like to get help.
This is my code:
import os
import numpy as np
import mne
import matplotlib.pyplot as plt
from mne.preprocessing import (ICA, create_eog_epochs, create_ecg_epochs, corrmap)
import sklearn
import pandas
The next block of code works perfectly. It crops the data, ignores some channels and sets annotations. My problem is in the last block.
paths = fetch_data(subjects=[4], recording=[1]) # getting the data path
patient=0 # number of the patient
raw_train = mne.io.read_raw_edf(paths[patient][0], stim_channel='Event marker', misc=['Temp rectal'])
raw_train.pick_channels(['EEG Fpz-Cz', 'EEG Pz-Oz','EOG horizontal']) # ignoring the other channels
annot_train = mne.read_annotations(paths[patient][1])
raw_train.set_annotations(annot_train, emit_warning=False)
annotation_desc_2_event_id = {'Sleep stage W': 1,
'Sleep stage 1': 2,
'Sleep stage 2': 3,
'Sleep stage 3': 4,
'Sleep stage 4': 4,
'Sleep stage R': 5} # annotations dictionary
annot_train.crop(annot_train[1]['onset'] - 60*3, annot_train[-2]['onset'] + 30) # cropping the data
raw_train.set_annotations(annot_train, emit_warning=False)
events_train, _ = mne.events_from_annotations(
raw_train, event_id=annotation_desc_2_event_id, chunk_duration=30.)
Here I tried to run some code that I copied from this tutorial:
https://mne.tools/stable/auto_tutorials/preprocessing/40_artifact_correction_ica.html
raw_train.set_channel_types({'EOG horizontal': 'eog'}) # needed for create_eog_epochs() to find en EOG channel because it wasn't originally named "eog"
eog_evoked = create_eog_epochs(raw_train).average()
eog_evoked.apply_baseline(baseline=(None, -0.2))
raw_train.load_data()
filt_raw = raw_train.copy().filter(l_freq=1., h_freq=None) # just a filter. Nothing special
ica = ICA(n_components=2, max_iter='auto', random_state=97) # choosing the maximum number of components which is 2
ica.fit(filt_raw) # running the ICA decomposition on the data
ica.exclude = [0] # choosing an independent component to exclude
reconst_raw = raw_train.copy() # copying so it doesn't change the original data
ica.apply(reconst_raw) # applying the ICA on the data
raw_train.plot(start=0, duration=20,
show_scrollbars=False,scalings=dict(eeg=0.1*1e-3))
reconst_raw.plot(start=0, duration=20,
show_scrollbars=False,scalings=dict(eeg=0.1*1e-3))
del reconst_raw # deleting the copy
ica
That’s what you get from the last line:
Method | fastica |
---|---|
Fit | 8 iterations on raw data (7710000 samples) |
ICA components | 2 |
Explained variance | 100.0 % |
Available PCA components | 2 |
Channel types | eeg |
ICA components marked for exclusion | ICA000 |
I don’t get any errors. The problem is that the independent components that I get are almost identical to the original EEG channels which means that the EOG channel wasn’t used for the ICA, right? Am I missing something?
You can see here the original data:
And here are the independent components: