Repairing artificats with ICA for siena scalp EEG Epilepsy database not changing after apply

  • MNE version:1.0.3
  • operating system: Ubuntu 20.04

I have followed tutorial (Repairing artifacts with ICA ā€” MNE 1.3.0 documentation)

Iā€™m able to find EMG and ECG artifacts correctly for dataset (Siena Scalp EEG Database v1.0.0), From visualization it shows working correctly

Iā€™m working with patient number 0 and dataset number PN00-1.

Code and data can be found here. (Artifact Detection using ICA MNE Python Epilepsy | Kaggle)

When I apply the ICA components, I see no effect on raw plot.

Any help would be appreciated.

Thanks in Advance
Abhishek

Hello, did you check with plot_overlay() that removal of your selected components would actually lead to a visible change in the signal? Have you tried selecting more components for removal just as a sanity check?

Best wishes,

Richard

Hi @richard ,
Thanks for the revertā€¦ There was plot_overlay already doneā€¦ In Kaggle please can you check it.

I have increase number of components to 25 but no success.

What i belive is I have made some mistake before / after applying ICA.

Thanks
Abhishek

Looking at the topographies, Iā€™d say the ICA decomposition didnā€™t really work:

I donā€™t have time to look in more detail though, sorry. But something is going wrong here.

Richard

Hello,

Here is a piece of code to get you started:

from mne.io import read_raw
from mne.preprocessing import ICA


fname = "PN00-1.edf"
raw = read_raw(fname, preload=True)

# remove flat channels
raw.drop_channels(["SPO2", "MK", "HR"])
# fix auxiliary channels names/types
raw.rename_channels({"EKG EKG": "ECG1", "2": "ECG2", "1": "EOG"})
raw.set_channel_types({"ECG1": "ecg", "ECG2": "ecg", "EOG": "eog"})
# fix EEG channels names
raw.rename_channels(
    {ch: ch.split(" ")[1] for ch in raw.ch_names if "EEG" in ch}
)
# fix EEG channels for the template montage
# set a template montage
raw.rename_channels(
    {"Fc1": "FC1", "Fc5": "FC5", "Cp1": "CP1", 
     "Cp5": "CP5", "Fc2": "FC2", "Fc6": "FC6", 
     "Cp2": "CP2", "Cp6": "CP6"}
)
raw.set_montage("standard_1020")

# ICA
ica = ICA(n_components=None, method="picard")
raw = raw.filter(l_freq=1., h_freq=40.)

# (optional) fixing the highpass and lowpass values in raw.info that are 
# incorrect from loading, it's bothering me
with raw.info._unlock():
    raw.info["highpass"] = 1.
    raw.info["lowpass"] = 40.
    
ica.fit(raw, picks="eeg")

Note that I donā€™t know how this dataset is filtered, read_raw loads (1.6 - 30) Hz, but thatā€™s definitely false judging by the PSD and by filtering at 1 Hz for the ICA.
You also have some sharp large amplitude events, which I would tend to annotate as ā€˜bads_segmentsā€™. Please have a look at this tutorial for annotations. For instance:

I did not annotate them as ā€˜bad_segmentsā€™ when I ran the ICA below, because of ā€˜Epilepsyā€™ keyword in the title. Maybe those correspond to some epileptic activity, although I doubt it, and it looks to me like the epileptic activity is around the ā€˜middleā€™ of the recording here:

But I donā€™t have any experience with epileptic dataset, so please take this information with a grain of salt.
Anyway, with this filtering and with an ICA fitted on the EEG channels, I do get some coherent (although not that great) ICs:

You can probably improve the IC fit by annotating as ā€˜bad_segmentā€™ the noisy segments, and by fitting independently the ā€˜normalā€™ and epileptic activities.

Mathieu

2 Likes

Hi @mscheltienne , Thanks for investing your time in going through and help, revert and providing solution,
I tried itā€¦ However, it has not given any changes before and after applying ICA.
If you can check with my original question, Iā€™m not able to see that ECG / EOG components in the data is getting reduced but instead both graph before and after looks exactly identical.

If you can help me with how to check the effect of removing the artifact with raw data itā€™d be great. I have seen other dataset tutorial where thereā€™s significant differece in output, Hence getting confused.

Thanks,
Abhishek

A quick second look at your Kaggle code shows:

Applying ICA to Raw instance
    Transforming to ICA space (25 components)
    Zeroing out 0 ICA components
    Projecting back using 25 PCA components
Applying ICA to Raw instance
    Transforming to ICA space (25 components)
    Zeroing out 0 ICA components
    Projecting back using 33 PCA components

As mentioned, 0 ICA components are zeroed. This means that the list ica.exclude is empty, i.e. that you did not select any component to be rejected. Using the topographic maps from my reply, we could remove the ICA 0 and 1. You can mark them for exclusion either by clicking on their name on the plot_components or plot_sources interactive figures, or by providing their ID in ica.exclude:

ica.exclude = [0, 1]

Then, when you will apply the ICA with ica.apply, the components marked for exclusion will be removed.

1 Like