Is there a way to obtain the time points from time_frequency.stft?

Proposed documentation ehancement

I wanted to use mne.time_frequency.stft — MNE 0.22.0 documentation
to compute the spectrogram of a Raw object.

However, it takes a sliding window and applies it to the data to compute the FT. Is there a quick and easy way within mne-python to obtain the time points?

If so, is it worth adding to the documentation for this function? If not, is it worth adding?

I don’t think we’ve implemented a quick way to get the time points. Seems useful though; are you up for making a PR to add it? For an API I’d expect something like a return_times parameter that defaults to False.

I can most definitely make a PR for this!

In order to “return_times”, though one would probably need to feed the function sfreq and return_times. In order to make this entire thing backwards-compatible, maybe these would be optional arguments?

In conjunction with that, would the mne-devs be opposed to making a time_frequency.tfr_stft function that allows input of a Raw object? Probably then need to rename this function to time_frequency.stft_array?

Related to some discussion in Adding overlap keyword to make_fixed_length_epochs · Issue #8773 · mne-tools/mne-python · GitHub

ah right, I forgot this is operating on arrays (hence no inst.info['sfreq'] available). I see now you’ve got a WIP PR already at #8781 for operating on Raws… thinking more deeply about this, here are my thoughts:

  1. operating on Raw seems useful, as long as there are big obvious caveats in the docstring about how huge the resulting object might be. For that function/method, return_times seems natural.

  2. When operating on arrays, return_times seems actually kind of unnatural; the rest of the function params are specified in samples (not seconds) so it would make sense that if it returned “times” it returned them as sample numbers. Except, I think the “times” are guaranteed to end up as midpoints between samples, right? (because the window is always an even # of samples in width). So to return integer sample numbers you’d have to decide if you want the lower or upper sample from the middle of the window. This is all doable, but feels inelegant, which makes me wonder if we’re missing some more straightforward way of getting what you want… how onerous is it to compute those times yourself from wsize and tstep?

I’d be curious to hear what other devs have to say about this. Incidentally, if we do end up adding stft_raw and renaming stft to stft_array, it would be a great opportunity to improve API consistency a little (i.e., maybe tstep → step or step_size, because prefixing with “t” to me implies time in seconds and elsewhere we’re standardizing on tmin/tmax for seconds and start/stop for samples; and possibly wsize → window_length).

[quote=“drammock, post:4, topic:2682, full:true”]

  1. operating on Raw seems useful, as long as there are big obvious caveats in the docstring about how huge the resulting object might be. For that function/method, return_times seems natural.

→ yay! Yeah for someone who doesn’t really work w/ Epochs, having to go thru Epochs to get the tfr(non-array) funcs is a bit tedious. I generally also only work w/ the average/median power within certain frequency bands too.

  1. how onerous is it to compute those times yourself from wsize and tstep?

→ it’s a bit tedious tbh esp if I have to repeat this operation on multiple projects. Ideally, there is a light-weight function within MNE that just does it for you and is linked to in all the tfr_array examples that “compress” the data in time.

A few additional thoughts if I ever manage to get tfr_<X> to work on Raw objects :

  1. Should they return AverageTFR, or perhaps a RawTFR similar to EpochsTFR? This would help facilitate in-line operations like “averaging power in a frequency band” to get the “gamma power” spectrogram of a dataset (channels X time).
  2. Should all tfr_<X> functions be made to return a TFR object?