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

Possible to restrict beamformer output to labels? #8509

Open bloyl opened 3 years ago

bloyl commented 3 years ago

Is there a reason the lcmv beamformer apply methods (apply_lcmv_epochs, apply_lcmv_raw, apply_lcmv_cov) don't support restricting to Label?

It seems like once the filter weights are made restricting to source locations inside a label shouldn't affect the results.

CC @britta-wstnr

larsoner commented 3 years ago

Personally I would just use stc.in_label afterward. Will this not work for your use case?

bloyl commented 3 years ago

The problem is memory usage for long data segments (mostly apply_lcmv_raw).

If you restrict first, you only allocate memory for the vertices you are going to fit.

larsoner commented 3 years ago

Sounds reasonable to me. +1 to add this, ideally by reusing / refactoring code in minimum_norm to handle it. That way if someday we want to support volume-atlas-labels we can do it in one place.

bloyl commented 3 years ago

I'll want this to work with volume-atlas-labels :(

Are there plans to flesh that out some? It seems like only extract_time_course supports volume_atlas_labels currently. Maybe it would make sense to focus there first?

larsoner commented 3 years ago

At least extract_label_time_course and VolSourceEstimate.in_label work with volumetric atlas int/atlas combinations. The underlying machinery so far runs through _volume_labels, so in theory it shouldn't be too bad to make it work for apply_inverse, and then eventually apply_lcmv.

One tricky part is mri_resolution -- in extract_label_time_course by default mri_resolution=True so the source estimate is effectively upsampled to the original MRI resolution, then the volume label is extracted. In vol_stc.in_label, mri_resolution=False, so it operates in the pos-spacing volumetric grid of the source space. This means it's possible if the label is small and the pos spacing is too large you could end up with no vertices selected. By contrast, this never happens with mri_resolution=True because you will always end up with some value as a result of the interpolation from the nearby grid points.

Eventually we could probably make it so that you could pass mri_resolution=True and it would include all vertices that would go into this interpolation, but it's a little bit weird because there are no weights associated with them.

Not sure the best way to go, but it is something to think about as you consider using label during extraction. Maybe in that case it should include all vertices necessary to extract the volume activation in the high-resolution space, but to get it properly weighted/interpolated you should use apply_inverse(..., label='whatever') followed by extract_label_time_course(stc, 'whatever', src=src), and it will apply the appropriate trilinear weights to upsample then extract using the label mask.

britta-wstnr commented 3 years ago

@larsoner Does this mean that I could end up with having the same grid point belong to different labels based on the interpolation that's been done?

At least from the beamformer perspective, there should not be any problem in applying or even calculating the filter for a subset of grid points only, since the weights are calculated for each grid point independently (as long as forward model and covariance matrix do not change, that is).

larsoner commented 3 years ago

Does this mean that I could end up with having the same grid point belong to different labels based on the interpolation that's been done?

Yep: