MNE resample different values in downsampling

MNE (1.1.1)
Windows 10

Dear all,
I’ve a problem with using of Mne when I downsample a signal of 500Hz to 100Hz. My control workflow is: 1) I created several raw file objects from the same 500 Hz eeg signal using for each time different incremental length ( e.g. 5 min, 5min+30s, … ) , 2) then I used raw.resample attribute on these raw files to downsample at 100 Hz and later I extracted sample data with raw.get_data. At last 3) I plotted the extracted data overlapped to compare them. I expect that all signals are superimposable for the same number of samples but it’s not so… the extracted data are too much different among themselves.

Is it a normal functional behavior of mne resample? Is it possible that this different values at the same sample for different length of raw files is due to the effect of the lp filter type included in mne code?

kind regards,

Matteo Padalino

If you take two raw files both having sampling rate of 500Hz, and one of the raw files has duration 300 seconds (5 minutes) and the other raw file has duration 330 seconds, then if you plot them they will not line up at the end (the second one will be 30 seconds longer). If you then resample them both to 100 Hz, they will still not line up at the end. This is because raw.resample(sfreq=100) does not mean “make the whole thing 100 samples long” — it means “make it have 100 samples per second”. Does that help?

Hi Dan, thank for your answer! I know that all signal will not line up at the end in this way, in fact I did this overlapping between signals because I want to analyze the performance/accuracy of the sleepstaging prediction for several length of the same signal in Yasa that uses Mne. So, for a stable prediction I expect that every overlapped part of each signal are similar, but it’s not so. I think that this behaviour is owed to a big artifact at 50 Hz and to the work of the lp filter before downsampling inside .resample(), but I asked in this forum to receive a confirm of my thesis.
Have nice day!

ah, OK, so you’re concerned because the initial part of all of them does not perfectly overlap. I think it is probably because raw.resample() automatically uses an anti-aliasing filter and applies some padding. If you pass npad=0 when resampling they will be much closer (but still not 100% perfect overlap)

import matplotlib.pyplot as plt
import mne
import numpy as np

rng = np.random.default_rng()
signal = rng.normal(size=(1, 10000))  # 20 seconds @ 500 Hz
info = mne.create_info(sfreq=500, ch_names=['ch1'], ch_types=['eeg'])
raw = mne.io.RawArray(data=signal, info=info)

with plt.ion():
    fig, ax = plt.subplots()
    # go in reverse order, i.e., shortest signal comes last, for clearer plot
    for tmax in (8, 7, 6, 5):
        _raw = raw.copy().crop(tmax=tmax).resample(sfreq=100, npad=0)
        ax.plot(_raw.get_data()[0], alpha=tmax/8)
    fig.tight_layout()

Try doing this locally and using the zoom tool of the matplotlib window to zoom in on just the first 50 samples or so. You’ll see the overlap is pretty good; then do it again with the npad=0 and you’ll see it gets worse.

Figure_1