EEG processing workflow and ICA application

Hi folks,

First, I would like to thank all the community for participating in the forum. I have a couple of questions regarding EEG processing.

Question #1: preprocessing resting state EEG
My starting point is matrix (channels x samples) holding a resting state EEG recording (16 eeg channels). I want to preprocess this recording using bad channel rejection, filtering, epoching and blink artifact removal. Is the following pipeline correct or could I improve it?

  1. Create raw object from my EEG data matrix.
  2. Set raw.info['bads'] based on annotations taken during the experiment.
  3. Apply high-pass filter and notch filter to raw to remove slow drifts and powerline artifact.
  4. Create epochs object based on filtered raw object and events of interest.
  5. Fit ICA to epochs object.
  6. Identify blink artifact component using ica.find_bads_eog(epochs, ch_name = 'Fp1') and exclude that component. Note: I do not have an eog channel so I find the blink artifact component using highest correlation with my Fp1 channel.
  7. Apply ICA to epochs object to reconstruct the epochs without the blink artifact component.

Question #2: apply ICA to an Event Related Potentials recording.
Let us consider for this assumption we have an epochs object (data dimension: trials x channels x samples) holding the epochs for all the events we are interested in. Let us also say that we are interested in the evoked response, epochs.average().

If we want to apply ICA to remove blink artifacts, should we fit ICA to the epochs object, then apply the fitted ICA to this very epochs object and finally estimate the evoked response as epochs.average()? or should we first estimate the evoked response, fit ICA to the evoked object and the apply it to that very evoked object? I consider the first approach more appropriate, but I am not sure at all.

I apologize for not providing a minimal working example, but these are kind of theoretical issues I found while designing my pipeline.

Thanks in advance.

Hello @eduardo and welcome to the forum!

Applying a notch filter is not necessary and I personally am not very fond of them anyways … if you don’t need the “high” frequencies, you can simply apply a low-pass with a cut-off frequency well below the power-line frequency. But this is not necessary for ICA. Only the high-pass filter (e.g., 1 Hz lower bound) is important to remove slow drifts.

But which events? :slight_smile: You have resting-state data, right?
You can chop the continuous data into equidistant chucks using make_fixed_length_epochs()

This sounds good in general. If the data you want to analyze requires a lower filtering cutoff for the high-pass, the recommended approach is to actually create two sets the data, one filtered with a 1-Hz-or-so high-pass for fitting ICA, and another one with a lower cutoff (e.g., 0.1 Hz), to which you will apply the ICA artifact removal.

That’s how I would do it, simply to have those cleaned epochs around in case I decide to do something else with them (source localization, machine learning) later on.

You cannot fit ICA to an evoked object in MNE (only epochs and raw data); however you can apply ICA cleaning to evoked data.

1 Like

Thank you very much for your answer, @richard.

With regard to the events, I forgot to mention I manually created an events matrix to split the resting state EEG into equal chunks, but I will use make_fixed_length_epochs() instead for better MNE compatibility.

As per the rest of your suggestions, you pretty much cleared things up. I will consider getting rid of the notch filter and I will fit ICA to my epochs object. Then, my plan is to perform feature extraction on the cleaned epochs and use the features to build a classifier.

Thanks again for your assistance.

1 Like