Skip to content

Conversation

@alexrockhill
Copy link
Contributor

@alexrockhill alexrockhill commented Jul 8, 2021

Closes #9520

Here is a very, very rough draft of what I was thinking, I didn't want to go too far in a bad direction so if you have a second to look at it @larsoner, that would be very much appreciated.

Basically, the ROIs are a very different kind of surfaces than the SUBJECTS_DIR/SUBJECT/surf surfaces and so I think need their own class but I think inheritance works nicely; they are named very differently and don't all have hemispheres.

@alexrockhill alexrockhill changed the title [ENH, WIP] Add Subcortical Surface Plotting [ENH, WIP] Suggested API changes to allow subcortical and other ROI plotting Jul 8, 2021
@alexrockhill
Copy link
Contributor Author

Ok this is missing all the brain stuff but I was a bit too tired to figure it out tonight. Looks like it works as a minimal version though. I'll add some tests tomorrow or maybe I could get a little help finishing this one because the mne.viz.Brain class is quite complicated and I'm not sure how much I really need to dive in for something this simple. Maybe we can talk about it tomorrow. I'll go ahead and start on the GUI tomorrow too.

Screen Shot 2021-07-14 at 11 05 46 PM

@larsoner
Copy link
Member

Using:

import mne
subjects_dir = mne.datasets.sample.data_path() + '/subjects'
brains = list()
brain = mne.viz.Brain(
    'fsaverage', 'both', 'pial',
    alpha=0.1, cortex='low_contrast', subjects_dir=subjects_dir)
brain.show_view(dict(azimuth=90, elevation=90))
brain.add_aseg()
brain.enable_depth_peeling()

I get:

Screenshot from 2021-07-15 14-37-20

So I added some smoothing and now I get:

Screenshot from 2021-07-15 15-08-55

I'll push, then @alexrockhill I think if you add this to tutorials/inverse/60_visualize_stc.py to show that we can now add_aseg in addition to add_annotation then I think we're close to done here!

@alexrockhill
Copy link
Contributor Author

Awesome! Looks great!!

Sure, I can do the last bit when you push your version.

@larsoner
Copy link
Member

I also feel bad for the poor neglected cerebellum so I added it to the defaults:

Screenshot from 2021-07-15 15-27-53

@larsoner
Copy link
Member

I'm done, feel free to push!

@alexrockhill
Copy link
Contributor Author

Wow you put labels on each of the default lut indices, thanks!

@larsoner
Copy link
Member

Yeah it was a quick copy-paste-trim from the FreeSurfer LUT file. vscode makes it really easy to edit N lines in an identical way :)

@alexrockhill
Copy link
Contributor Author

Hmmm, some camera issues I think

brain2

@alexrockhill alexrockhill changed the title [ENH, WIP] Suggested API changes to allow subcortical and other ROI plotting [ENH, WIP] Add mne.viz.Brain.add_aseg to plot anatomical segmentation surfaces Jul 15, 2021
@alexrockhill
Copy link
Contributor Author

alexrockhill commented Jul 15, 2021

Screen Shot 2021-07-15 at 3 53 55 PM

Hmmm the electrodes seem to be out-of-scale as well... it might be easier to mock up a quick add_sensors that doesn't support MEG but I don't want to make problems/get in the way of @GuillaumeFavelier

This is with

fig = mne.viz.plot_alignment(epochs.info.pick_channels(picks), trans,
                             'fsaverage', subjects_dir=subjects_dir,
                             surfaces=[])

brain = mne.viz.Brain('fsaverage', alpha=0.1, cortex='low_contrast',
                      subjects_dir=subjects_dir, figure=fig)
brain.add_aseg(aseg='aparc+aseg', rois=rois)

@larsoner
Copy link
Member

You need units='m' in the brain constructor

@larsoner
Copy link
Member

(plot_alignment only ever uses meters but brain defaults to millimeters for consistency with freesurfer and pysurfer)

@alexrockhill alexrockhill changed the title [ENH, WIP] Add mne.viz.Brain.add_aseg to plot anatomical segmentation surfaces [ENH, MRG] Add mne.viz.Brain.add_aseg to plot anatomical segmentation surfaces Jul 16, 2021
@larsoner
Copy link
Member

Last run CircleCI complained:

/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:13: WARNING: py:func reference target not found: mne.get_montage_rois
/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:13: WARNING: undefined label: freesurfer lookup table
/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:32: WARNING: py:func reference target not found: pyvista.BasePlotter.add_legend
changes/latest.inc:102: WARNING: py:func reference target not found: mne.viz.Brain.add_eeg_sensors

Not sure if you fixed those in the latest rebase or not...

@alexrockhill
Copy link
Contributor Author

Last run CircleCI complained:

/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:13: WARNING: py:func reference target not found: mne.get_montage_rois
/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:13: WARNING: undefined label: freesurfer lookup table
/home/circleci/project/mne/viz/_brain/_brain.py:docstring of mne.viz._brain._brain.Brain.add_aseg:32: WARNING: py:func reference target not found: pyvista.BasePlotter.add_legend
changes/latest.inc:102: WARNING: py:func reference target not found: mne.viz.Brain.add_eeg_sensors

Not sure if you fixed those in the latest rebase or not...

That's going to depend on #9545 to merge first but other than that, yes taken care of

@larsoner
Copy link
Member

@alexrockhill this needs a rebase or merge. I went to do it but I think you'll have ideas for how best to combine add_aseg with the other tutorial changes.

Also based on naming consistency I suppose this should be add_volume_labels

@larsoner
Copy link
Member

@alexrockhill I pushed a commit that cleans up the smoothing and makes the marching cubes faster for labeled volumes following the VTK example https://kitware.github.io/vtk-examples/site/Cxx/Medical/GenerateModelsFromLabels/

@larsoner
Copy link
Member

... so I think all we need here is a rebase or merge with upstream/main, and rename add_aseg to add_volume_labels then we should be good!

@larsoner larsoner changed the title [ENH, MRG] Add mne.viz.Brain.add_aseg to plot anatomical segmentation surfaces [ENH, MRG] Add mne.viz.Brain.add_volume_labels Jul 19, 2021
author Alex <aprockhill@mailbox.org> 1626322812 -0700
committer Alex <aprockhill@mailbox.org> 1626466592 -0700

add roi/subcortical plotting

wip

wip

wip

slighly working version

FIX: Fix units and render

ENH: Cerebellum

wip

add legend, fix seeg tut

add legend kwargs, update visualize stc tut

fix flake

fix doc, fix copy error in tutorial

fix func->meth

Eric suggestions
@larsoner
Copy link
Member

... just realized you asked about Brain. We should expose focalpoint in https://mne.tools/stable/generated/mne.viz.Brain.html#mne.viz.Brain.show_view

@larsoner
Copy link
Member

And it would be nice to color the electrodes differently but that's only available in #9585 not mne.viz.plot_alignment.

In this case I would favor a PR to plot_alignment first that allows channel-by-channel color choosing first, as we'll want it there, too. Then later refactoring as we've talked about.

@alexrockhill
Copy link
Contributor Author

... just realized you asked about Brain. We should expose focalpoint in https://mne.tools/stable/generated/mne.viz.Brain.html#mne.viz.Brain.show_view

Yeah I can open an issue for that too, I was able to just change the view angles for now.

@larsoner
Copy link
Member

Yeah I can open an issue for that too, I was able to just change the view angles for now.

If it's as easy as adding focalpoint=None to the signature and passing it through to set_3d_view under the hood somewhere, then it can be part of this PR

@alexrockhill
Copy link
Contributor Author

Interestingly, it ran locally for me with the insula label but that was for fsaverage and test_brain uses sample. I don't think it's an issue with the core functionality though.

Actually that's for aparc+aseg and fsaverage and the test is for aseg and sample.

@larsoner
Copy link
Member

Interestingly, it ran locally for me with the insula label but that was for fsaverage and test_brain uses sample. I don't think it's an issue with the core functionality though.

I suspect it's a problem with the example arguments/usage. Can you fix it?

@alexrockhill
Copy link
Contributor Author

Interestingly, it ran locally for me with the insula label but that was for fsaverage and test_brain uses sample. I don't think it's an issue with the core functionality though.

I suspect it's a problem with the example arguments/usage. Can you fix it?

Sure in a meeting, will fix in 30 minutes

@larsoner
Copy link
Member

Sure in a meeting, will fix in 30 minutes

Sounds good, FYI two examples appear broken now:

https://app.circleci.com/pipelines/github/mne-tools/mne-python/9151/workflows/e75f8447-9f58-40e4-b333-38bd240c79b9/jobs/31313

  File "/home/circleci/project/tutorials/inverse/60_visualize_stc.py", line 163, in <module>
    brain.add_volume_labels(aseg='aparc.a2009s+aseg', labels=labels)
  File "/home/circleci/project/mne/viz/_brain/_brain.py", line 2391, in add_volume_labels
    warn(f'Value not found for label {repr(label)} in: '
  File "/home/circleci/project/mne/utils/_logging.py", line 358, in warn
    warnings.warn_explicit(
RuntimeWarning: Value not found for label 'ctx_lh_G_occipital_sup' in: /home/circleci/mne_data/MNE-sample-data/subjects/sample/mri/aparc.a2009s+aseg.mgz
...
  File "/home/circleci/project/tutorials/clinical/20_seeg.py", line 178, in <module>
    brain.add_volume_labels(aseg='aparc+aseg', labels=labels)
  File "/home/circleci/project/mne/viz/_brain/_brain.py", line 2391, in add_volume_labels
    warn(f'Value not found for label {repr(label)} in: '
  File "/home/circleci/project/mne/utils/_logging.py", line 358, in warn
    warnings.warn_explicit(
RuntimeWarning: Value not found for label 'ctx-lh-caudalmiddlefrontal' in: /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/mri/aparc+aseg.mgz

@alexrockhill
Copy link
Contributor Author

I think some changes maybe to smoothing have broken it, it's not finding any labels not just insula. Looking into it

@larsoner
Copy link
Member

larsoner commented Jul 19, 2021

I think some changes maybe to smoothing have broken i

The failure is in the add_volume_labels step, which should have nothing to do with labels smoothing, just with the contents of aparc+aseg.mgz and the FreeSurfer LUT. Or am I missing something?

@alexrockhill
Copy link
Contributor Author

I think some changes maybe to smoothing have broken i

The failure is in the add_volume_labels step, which should have nothing to do with labels smoothing, just with the contents of aparc+aseg.mgz and the FreeSurfer LUT. Or am I missing something?

I'm going to try putting things back before your latest marching cubes change (only the first smooth), if that fixes things then we can do the discrete part in another PR.

@larsoner
Copy link
Member

I'm going to try putting things back before your latest marching cubes change (only the first smooth), if that fixes things then we can do the discrete part in another PR.

Feel free, but please preserve the warning. I suspect things might have been failing silently before (because we just silently didn't bother trying to do marching cubes before my commits) and the warning makes it clear that something is wrong somewhere (we shouldn't in an example ask to plot a volume label that does not exist in the mgz)

for label, color, (verts, triangles) in zip(labels, colors, surfs):
if len(verts) == 0: # not in aseg vals
warn(f'Value not found for label {repr(label)} in: '
f'{aseg_fname}')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the warning we need to preserve

@alexrockhill
Copy link
Contributor Author

I'm going to try putting things back before your latest marching cubes change (only the first smooth), if that fixes things then we can do the discrete part in another PR.

Feel free, but please preserve the warning. I suspect things might have been failing silently before (because we just silently didn't bother trying to do marching cubes before my commits) and the warning makes it clear that something is wrong somewhere (we shouldn't in an example ask to plot a volume label that does not exist in the mgz)

Good call, it does look like what was broken was from the marching cubes changes though. I didn't really delve into it fully but when I reverted all the surfaces rendered properly

@alexrockhill
Copy link
Contributor Author

So there was an issue with ctx-insula not being found and that was because the atlas was changed to aseg which has a subset of labels, not including the ctx ones

@larsoner
Copy link
Member

Good call, it does look like what was broken was from the marching cubes changes though. I didn't really delve into it fully but when I reverted all the surfaces rendered properly

Did you verify this by locally testing with some PATTERN=... make html_dev-pattern-memory as suggested above (or even just running python -i tutorials/clinical/... to see if there is a warning)? You should get in the habit of doing this (example testing) as well as checking pytest -- a991d32 for example almost certainly broke pytest mne/tests/test_surface.py -k march because it reverted the array-like handling but not the tests I pushed for it. Try to get in the habit of testing these things locally before each push because:

  1. It will make PR cycles shorter, and
  2. We do end up with a backlog of CI runs in general

So pushing commits that uniformly keep CIs green is better than pushing commits without checking locally that things work first. The CIs are really meant to act as a sanity / completeness check of things that have been checked locally.

So there was an issue with ctx-insula not being found and that was because the atlas was changed to aseg which has a subset of labels, not including the ctx ones

Can the discrete support be restored, or is there also an issue with the smoothing there?

@alexrockhill
Copy link
Contributor Author

Yeah sorry, got a bit hasty with the fix for the last PR being a priority.

I checked and running locally there are no warnings for the seeg tutorial with this version, all the CIs should come back green.

Can the discrete support be restored, or is there also an issue with the smoothing there?

There was an issue with the atlas in the tests but also a larger issue with the discrete method, I don't think it was working...

@larsoner
Copy link
Member

There was an issue with the atlas in the tests but also a larger issue with the discrete method, I don't think it was working...

Indeed it failed to find some ROIs, if I force it to use VTK_DOUBLE it seems to work fine! But like you said I can open a separate PR for this once this one is merged.

@larsoner
Copy link
Member

Not waiting for macOS on this one, thanks @alexrockhill !

@alexrockhill
Copy link
Contributor Author

Sounds great, looks like it's good to go

@larsoner larsoner merged commit 3a4a048 into mne-tools:main Jul 19, 2021
@alexrockhill alexrockhill deleted the subcort branch July 19, 2021 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENH] Add "roi" feature to mne.viz.Brain

2 participants