GSoC, ENH: Improve Time Frequency Analysis in Source Space
See original GitHub issueHey everyone, I’m going to work on improving Time Frequency Analysis in Source Space as my Google Summer of Code project this year! I opened this issue, so we can discuss different aspects of the project, e.g. what you would like to have implemented and what not. To get an idea of the project, you can take a look at this google doc, which is a copy of my GSoC proposal. Feel free to comment on the google doc, anyhow, it would probably be better if we keep the general discussion within the thread of this issue.
Problem:
For TFR Analysis in source space, it would be nice to be able to apply MNE’s standard repertoire of TFR functions from mne.time_frequency
on SourceEstimate
data, instead of being restricted to use the source_induced_power
and source_band_induced_power
functions.
Solution/ alternatives:
There are some possible solutions listed in the proposal.
The basic idea was to enable mne.time_frequency
functions to take VectorSourceEstimates
and VolVectorSourceEstimates
as data input and return one or more SourceTFR
classes, which contain time-frequency transformed source level data.
Anyhow, feel free to express your opinion on any solution or alternative (that’s what this issue was created for).
Issue Analytics
- State:
- Created 4 years ago
- Comments:30 (30 by maintainers)
Top GitHub Comments
If we’re going to get rid of the Vector/non-vector and time/freq class-based distinctions, we might as well get rid of the surface/volume/mixed class-based distinctions, too. We don’t have great support for mixed source spaces and trying to have a general class could help fix this problem.
I propose we come up with a new class that’s for any type of source-level data we want to work with. I’d call it SourceData because even the idea of it being an “estimate” is a misnomer (e.g. when simulating you’re actually giving ground truth). Here is a first pass at a draft spec for what a SourceData instance
sd
has and can do:sd.dims
tuple of str saying what the data dims correspond to, in order (with optionality;n_orientations
always 1 or 3.):sd.src
for the source space corresponding to the data/vertices (a stripped-down version, assrc
for surfaces with distances can be hundreds of MB)sd.subject
for the subjectsd.times
andsd.frequencies
asndarray
orNone
sd.units
for the data: e.g. ‘nAm’ (MNE), ‘F’ (dSPM), or ‘AU’ (for now; maybe we also can figure out the units for time-freq data if it’s properly normalized somehow)sd.orientations
either('normal',)
or('X', 'Y', 'Z')
For methods:
sd.get_data()
to get an ndarray containing the data for a subset of vertices/epochs/times/freqs. This, rather than always creating a.data
attribute, is useful for efficiency. In cases where we have a linear imaging kernel, a lot of stuff could be simplified e.g. iterating over epochs, doing TF transformation, apply kernel, take magnitude, etc. In other words: the default behavior of e.g.apply_inverse
is to not have a fullsd.data
stored in memory.sd.load_data()
to create and populate thesd.apply_kernel()
sd.data
array if people want the full array available and modifiable insd.data
sd.plot_3d()
– hopefully there is some convergence here with @GuillaumeFavelier’s work that this will use surface plots for the surface source spaces and some 3D volume rendering for the volume source spacessd.plot_orthoview()
– plot in 3D volumetric space like our volume plotters currently dosd.save()
to HDF5I think this could be made to work for all variants of
*SourceEstimate
we currently have, and all of their currently implemented methods.We’ll have to decide how backward compatible we want it to be. The way I would start is by looking at how far we can get by supporting “upsampling” our five existing classes to
SourceData
. Hopefully at the end of the day our five classes can just be thin wrappers that contain little to no code like:Maybe we deprecate them with a long cycle, maybe not. But I’m optimistic it’s a solvable problem.
Based on the API I outlined above I think it’s worth the necessary work to get this more compact-yet-complete interface working. It would simplify a lot of code I’ve locally written to handle the various SourceEstimate classes, as well as things internally.