Frequency step in psd_multitaper vs psd_welch

The frequency step in psd_welch is 1.953125 while in psd_multitaper it is 0.00164441 - 3 orders of magnitude difference:

import mne
psds,freqs = mne.time_frequency.psd_multitaper(edf)
np.diff(freqs)
==> array([0.00164441, 0.00164441, 0.00164441, 0.00164441, 0.00164441, ...])
psds,freqs = mne.time_frequency.psd_welch(edf)
np.diff(freqs)
==> array([1.953125, 1.953125, 1.953125, 1.953125, 1.953125, 1.953125, ...])

Why? How do I control it?

mne.__version__ == '1.0.3'
Python 3.10.4 on Linux.

PS. See also SO.

I assume that your edf variable is continuous data.

It’s the size of the FFT window that drives your frequency resolution.

If you want to increase the frequency resolution with welch increase the n_fft parameter
(taking ideally a power of 2)

HTH
A

1 Like

Thank you!

What about decreasing resolution of psd_multitaper?
I really don’t need more than 0.3!

I think for multitaper the only thing that affects freq bin spacing is number of samples and sampling frequency. See here:

so, I think no public API exists for doing a more sparse sampling of frequencies.

Thank you for the bad news ;-(

The code you are referencing is for psd_array_multitaper and it accepts sfreq that determines the sampling. However, I am interested in psd_multitaper, which gets sfreq from _check_psd_data which examines inst.info['sfreq'].

My EDF instance has inst.info['sfreq'] == 2000.0 and …

RuntimeError: sfreq cannot be set directly. Please use method inst.resample() instead.

I don’t see where this method is documented, but help seems to suggest

inst.resample(sfreq=???)

what do I pass there to reduce sampling?

psd_multitaper calls psd_array_multitaper internally.

inst.resample() in the error message means raw.resample() or epochs.resample() or evoked.resample() (inst means “instance”, i.e., an instance of one of those classes).

My edf.info["sfreq"] is 2000 and mne.time_frequency.psd_multitaper(edf) produces 1151033 frequencies with step 0.00086879 and range [0;1000].

After edf.resample(sfreq=100), I get 57552 frequencies with the same step(!) and smaller range [0;50].

This is certainly not what I want!