How to compute Welch PSD in Source Space after Epoch-level Autoreject

Hi MNE Experts,

I am processing a resting-state MEG dataset (275 channels) and using autoreject to clean my data after ICA. My goal is to compute Source Space Welch PSD for group-level statistics. However, I’m stuck on how to properly handle the discontinuous cleaned epochs with Welch’s sliding window.

After autoreject.transform(epochs), the bad epochs are dropped, leaving a set of clean but discontinuous 2-second segments. I want to perform a Welch PSD estimation with a 50% overlap. I see two potential approaches, but both have issues:

  • Approach A: Run Welch PSD directly on the Epochs object. If I enforce method='welch' on these isolated 2s epochs, the window can only slide inside each individual epoch. It lacks the continuous macro-level overlapping across the time series.

  • Approach B: Concatenate the cleaned Epochs into a continuous RawArray and re-epoch with a 50% overlap (duration=2s, overlap=1s). My Concern: Even though the data inside each epoch is clean, the concatenation joints (boundaries) are non-physiological. Due to epoch-level baseline corrections or channel interpolations, micro-voltage steps or phase discontinuities will exist at every splicing joint. If a Welch sliding window strides over these artificial joints, it will cause severe spectral leakage (especially in high frequencies).

What is the gold-standard workflow in MNE to achieve a proper Welch PSD estimation when dealing with post-autoreject discontinuous epochs?

Any advice or recommendations would be greatly appreciated!

Hi Junbintian1998,

I don’t think there is a gold-standard but I would avoid approach B for the reasons you mention.
Your approach A is definitely preferred.
Regarding epochs, one option would be to increase the epoch length before you run autoreject. Depending on the data you work with, a 10 second epoch might be reasonable (e.g. resting state data). The length of your epoch does determine the parameters for Welch PSD.

Specific suggestions are difficult to make without knowing the data and the artefacts that are to be expected, but I hope this general approach helped.

Cheers,

Carina

Hi Carina,

Thanks for the advice!

We are working with healthy adult data and the quality is great so far—no epochs rejected after autoreject.

I have a follow-up about autoreject’s behavior with longer epochs:

Our resting-state recording is only 3 minutes (180s) in total. If we use a 10-second epoch, my worry is that a sudden, brief artifact (like a quick muscle twitch or a SQUID jump) might cause autoreject to throw away the entire 10-second block.

Since our data is short, losing just a few blocks means losing a huge chunk of our data.

In your experience, how does autoreject handle these brief, transient artifacts in longer epochs?

Cheers,

Junbin

Hi Junbin,

Yes longer epochs can still cause the whole epoch to be marked as bad. This depends on the threshold that autoreject uses, for a detailed explanation of autoreject I recommend checking out the homepage here and the reference.

As discussed in the autoreject workflow tutorial, longer resting-state epochs are useful for frequency-domain analyses, but they can also increase the chance of losing larger data segments when artefacts occur. I suggest trying out different epoch lengths and manually inspect the flagged epochs. Hopefully this gives you a good idea of what is a a good epoch length that provides clean epochs but doesn’t remove too much clean data.

Cheers,

Carina