ICA artifact correction assistance

  • MNE version 1.4.0
  • Ubuntu 20.04 running in WSL vscode Jupyter

Hello, I am experimenting with ICA artifact correction and am a bit confused about some things. First, I was wondering why my ICA components have a sign flip from my eog channels:


Next, I am wondering why my ICA overlays do not match the example on the mne site:

I suspect it has to do with the sign flip, but I am not sure.
ICA components:



Applying ICA to the raw data seems to work fine. I am just confused about why these plots do not match the mne tutorial.

Hello!

This is nothing to worry about.

There is a stochastic element in ICA that causes the signs to randomly flip between runs of ICA. The decomposition itself remains the same, though. Try re-running ICA a few times on the same machine, or on a different computer. Sooner or later you should arrive at a solution where the signs are flipped.

The implication here is that the results are not reproducible in terms of the sign, and if you want to ensure that you always get the same orientation of the signal, you should pass random_state.

It’s difficult to tell what’s going on unless you share your full preprocessing code and the data. But to me it looks like you probably didn’t high-pass filter the data, since there are clear DC shifts visible.

No, it should not be related to the sign flip.

It seems to me the data is not baseline-corrected. In our tutorial we apply baseline-correction to the EOG evoked object: Repairing artifacts with ICA — MNE 1.6.0 documentation

Lastly I’m wondering why you’re applying ICA to the raw data and not to epoched data? If you have an event-related paradigm, creating epochs and running ICA on those is usually the better approach. But of course, using ICA with continuous data is fine, too. I’m just asking because you followed our tutorial, and there we use continuous data, and I want to make sure you know that this is not the only way to do it.

Ciao,
Richard

2 Likes

Hi @richard,

The tutorial says not to baseline correct the data until after ICA. How would I baseline correct continuous raw data?

Here are the settings I used:


#Plot montage

raw_cnt.plot_sensors(show_names=True)

eog_evoked = mne.preprocessing.create_eog_epochs(raw_cnt).average()

eog_evoked.apply_baseline(baseline=(None, None))

# eog_evoked.plot_joint()

filt_raw = raw_cnt.copy().filter(l_freq=1.0, h_freq=None)

ica = mne.preprocessing.ICA(n_components=15, max_iter="auto", random_state=97)

ica.fit(filt_raw)

reconst_raw = raw_cnt.copy()


ica.apply(reconst_raw)

Plots:

ica

explained_var_ratio = ica.get_explained_variance_ratio(filt_raw)

for channel_type, ratio in explained_var_ratio.items():

print(

f"Fraction of {channel_type} variance explained by all components: " f"{ratio}"

)

ica.plot_sources(raw_cnt, show_scrollbars=False)

ica.plot_components()

# blinks

ica.plot_overlay(raw_cnt, exclude=[0], picks="eeg")

# heartbeats

#ica.plot_overlay(raw_cnt, exclude=[1], picks="mag")

ica.exclude = []

# find which ICs match the EOG pattern

eog_indices, eog_scores = ica.find_bads_eog(raw_cnt)

ica.exclude = eog_indices

# barplot of ICA component "EOG match" scores

ica.plot_scores(eog_scores)

# plot diagnostics

ica.plot_properties(raw_cnt, picks=eog_indices)

# plot ICs applied to raw_cnt data, with EOG matches highlighted

ica.plot_sources(raw_cnt, show_scrollbars=False)

# plot ICs applied to the averaged EOG epochs, with EOG matches highlighted

ica.plot_sources(eog_evoked)

I’m doing some spectral analysis so that’s why I applied ICA from the continuous data. Thank you!

Hey @richard!

Just following up on this. Thank you!

-Jacob