question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Re-applying baseline correction after ICA

See original GitHub issue

Skimming over some Study Template analysis results with @agramfort, we found that some of our data appeared to be not baseline-corrected – some traces clearly didn’t have a zero-mean during the baseline period.

So I started digging and figured that we had indeed applied baseline correction to our data; yet after cleaning the Epochs via ICA, the baseline signals of some channels had started floating away from zero.

Now this may not come as a surprise to some of you, but I have to admit it caught me off-guard. I’d never seen this behavior before with the data I’d worked with so far, and I’ve failed to reproduce a similarly visible effect using our sample data.

However, looking through the ICA tutorial, where we clean Raw data, one can see the essence of this effect too – albeit with Raw and not Epochs (lower panel):

I’d like to propose and discuss the following changes and enhancements to deal with this behavior:

  • Clearly state in the docs that baseline correction should be re-applied to Epochs and Evoked data after applying ICA
  • viz.plot_ica_overlay() should automatically re-apply baseline correction to the cleaned signal if an Evoked was passed
    • for this, we’d need to add an Evoked.baseline attribute, which gets inherited from the parent Epochs.baseline. This has been on my agenda for a while anyway in order to improve provenance, so I’d might take a shot at this anyway.
  • We could even go so far as to auto-reapply baseline correction to Epochs and Evoked data as part of ICA.apply(), so users wouldn’t have to do this themselves. This behavior should be toggle-able using a new kwarg.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:18 (18 by maintainers)

github_iconTop GitHub Comments

2reactions
agramfortcommented, Mar 11, 2021

we converge to the same thing.

Do not baseline epochs passed to ICA.

Apply baseline only after doing ICA cleaning.

No need to enable not centering the PCA step.

1reaction
larsonercommented, Mar 10, 2021

SSP is a linear spatial operator, so if all channels have zero mean (during some interval) all channels will have zero mean after the operation (in that same interval). This is because the mean (over that interval) is also a linear operator.

To demonstrate how ICA violates this, let’s say we have two channels of data for one 3-sample epoch that that each already have zero mean over time, for example [[1, 0, -1], [0, 0, 0]]. If the empirical means estimated by ICA during fitting happened to be, say -1 and 0, ICA will:

  1. Subtract the empirical estimated means, giving [[2, 1, 0], [0, 0, 0]]
  2. Apply the ICA operator, which is just some linear spatial operator. Let’s pick one that just swaps data between channels, [[0, 1], [1, 0]] (ICA in practice will do something different like unmix-exclude-mix, but this gives a simple example to play with). So now our data after the ICA operator is [[0, 0, 0], [2, 1, 0]].
  3. Add the means back, giving [[-1, -1, -1], [2, 1, 0]].

Now our previously-zero-mean channels have means -1 and 1, which is not good. Let’s call this operation B = ICA(A). If we apply this operation to identical data, that will (trivially) have B = ICA(A) having means -1 and 1, too.

And this is where you can see that the ICA operation above is not linear. We know that B + B = ICA(A) + ICA(A) but that this means 2B = ICA(A) + ICA(A). We know that since B has means -1 and 1, 2B will have means over time of -2 and 2. For linearity to hold, we need that 2B = ICA(A) + ICA(A) = ICA(A + A) = ICA(2A), but unfortunately ICA(2A) will go from [[2, 0, -2], [0, 0, 0]] to start, through step 1 to [[3, 0, -1], [0, 0, 0]], through step 2 to [[0, 0, 0], [3, 0, -1]], through step 3 to [[-1, -1, -1], [3, 0, -1]], which has means -1 and 2/3, which do not equal -2 and 2. Hence our ICA operation is not a linear operator, which I think it is meant to be…

If we remove the mean subtraction at the beginning and mean re-addition at the end, ICA will be a linear spatial operator (just like SSP) in the end. To me this is starting to seem like the correct option.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[Eeglablist] A quick question about baseline correction after ICA
[Eeglablist] A quick question about baseline correction after ICA. David Groppe dgroppe at cogsci.ucsd.edu. Tue Jan 5 08:12:51 PST 2010.
Read more >
Baseline correction and re-referencing for ERPs - Brainstorm
I have a query regards the average re-referencing. I applied this after removing bad channels and before ICA in my pre-processing pipeline.
Read more >
Repairing artifacts with ICA — MNE 1.2.2 documentation
Note that we don't baseline correct the epochs here – we'll do this after cleaning with ICA is completed. Baseline correction before ICA...
Read more >
ICA.plot_overlay() and baseline correction #8147 - GitHub
By applying baseline correction to evoked_cln before plotting, I get the expected result: evoked_cln = ica.apply(inst.copy(), ...
Read more >
Independent component analysis reveals dynamic ictal BOLD ...
ICA applied to EEG-fMRI can detect areas of significant BOLD response to ictal events without having to predefine an HRF. By estimating the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found