mne-tools / mne-python

MNE: Magnetoencephalography (MEG) and Electroencephalography (EEG) in Python
https://mne.tools
BSD 3-Clause "New" or "Revised" License
2.69k stars 1.31k forks source link

Volume source space: apply_inverse without altering spectra? #6109

Closed jhouck closed 4 years ago

jhouck commented 5 years ago

In volume source space, using apply_inverse with pick_ori='normal' doesn't really seem like a great option (per @larsoner this is probably +Z). But using pick_ori=None will take the norm across the 3 orientations, which changes the spectra (see e.g. https://gist.github.com/jhouck/8e20484fad3a8e1a1d08addc96204aff). Using pick_ori='vector' preserves the spectra and also provides 3x as much data, which should then probably be combined somehow.

What would be the best way to combine the information from the 3 orientations that is returned by 'vector'? Would it make sense to borrow from the label_funcs in source_estimate (e.g., mean, mean_flip, max, pca_flip) for this?

larsoner commented 5 years ago

It depends a bit on what you are going to do with the spectra. If it's just to get a PSD, getting the power spectra of the three orientations and then just taking the sum, average, or RMS across orientations might not be so terrible.

If you want to do some connectivity measure, then it's going to be more complicated. I talked briefly with @SherazKhan about how it should be possible to use an SVD approach (and/or multivariate correlation) to compute one envelope correlation value between vertices, each of which is in free orientation. I think in principle it should work but am not sure if anyone has tried it. (I might try it soon.) For other connectivity measures I don't know what you would do.

Would it make sense to borrow from the label_funcs in source_estimate (e.g., mean, mean_flip, max, pca_flip) for this?

We wouldn't want to use the actual label flip function, since that has to do with the relations between the orientations of different vertex normals, rather than between the three canonical orientations of a given vertex. But we can think about how the math would translate, which is probably what you were thinking anyway.

So one option would be to project your data for each vertex onto the predominant direction (orientation). (This might end up being equivalent to what the pick_ori='max_power' in beamformer is designed to do.) The problem is that, while a beamformer can do this using the data_cov and thus it is static once you create the beamformer filters, for MNE inverses this becomes data-input dependent. For example, when iterating over epochs, the effective orientation chosen can change epoch to epoch. One way around this would be to choose the orientation for each vertex once using all epochs -- then it's still data dependent but at least no longer time-varying. But it might also not matter too much, since pca_flip also has this issue.

I guess at the very least, VectorSourceEstimate has a normal method in it, we could add something like a pca_direction method that does the equivalent of the pca_flip method for label flips. @agramfort @SherazKhan does this make sense to you?

jhouck commented 5 years ago

OK, ok, you've talked me into using the beamformer. ;)

Yes, the interest was connectivity; the PSD was an error check. I had planned to do envelope correlation, with a group ICA along the way. There are some additional steps if you want to take complex data from the inversion through the intermediate steps into envelope_correlation, but nothing too onerous. At the moment the process runs fine, other than all of the input data being wrong.

larsoner commented 4 years ago

Closing since I don't think there is much else to do for this one