Platform Linux-5.15.90.2-microsoft-standard-WSL2-x86_64-with-glibc2.31
Python 3.10.10 | packaged by conda-forge | (main, Mar 24 2023, 20:08:06) [GCC 11.3.0]

Hello! I am in the process of writing a script to recreate the newtimef() function from the EEGLab toolbox in mne.

The function is designed to compute the spectral perturbation (ERSP) and inter-trial coherence (ITC) across epochs.

To do this I am using the mne.time_frequency.tfr_morlet() function. My epochs are 3 seconds long and my sampling rate is 1000 Hz.
The frequencies I am using are: np.logspace(*np.log10([1,30]), 30)
The number of cycles I am using are: np.linspace(1, 15, 30) based on this formula from EEGLab.

When I run the function I get the following error: ValueError: At least one of the wavelets (3069) is longer than the signal (3001). Consider using a longer signal or shorter wavelets.

My question is how is this 3069 value calculated? My understanding was that this value is based on the formula:

MNE-Python is pretty conservative when it comes to where to “cut” the infinite wavelet to a certain length where we say “this is close enough to zero”. The formula for this is not n_cycles/freqs, but rather 10 * n_cycles / (2 * np.pi * freqs), give or take a little depending on where the exact samples fall.

So, you could either cut epochs a little bit wider, do the tfr_morlet, and then cut the resulting TFR back to the desired length. Or, you can turn on use_fft=True, which performs the wavelet transform in Fourier space, thus sidestepping the wavelet window length issue, turning the error into a warning.

Thank you! This was really helpful @wmvanvliet! Would you mind telling what the n_cycles/freqs value is then? Also, I am still a bit confused how the 3069 samples was calculated. I assume I would just multiply my sampling rate by 10 * n_cycles / (2 * np.pi * freqs)

I don’t know where the n_cycles/freqs comes from (I’m not well versed in wavelet analysis), my guess would be something to do with the expected time resolution of the TFR(?)

I think the right way to think about “temporal window length” is that it is the temporal resolution (or conversely the amount of temporal smearing). It determines how precisely in time you’ll be able to localize an event. It is not actually reflective of the length of the morlet wavelet returned by our morlet function / used in our tfr_morlet function.

@withmywoessner if you have an idea of how we could clarify the documentation around this, please make a PR!