jonescompneurolab / hnn-core

Simulation and optimization of neural circuits for MEG/EEG source estimates
https://jonescompneurolab.github.io/hnn-core/
BSD 3-Clause "New" or "Revised" License
55 stars 52 forks source link

[MRG] NetworkPlot class to enable interactive visualizations and animations #649

Closed ntolley closed 5 months ago

ntolley commented 1 year ago

Here's my first pass at creating a viz class that can be used to quickly render the full 3D network, as well as membrane potentials of individual sections. This is meant to be largely generic and flexible so that it can be co-opted for other purposes. I think the most interesting applications at the moment would be:

The current strategy for the class is to do all of the heavy lifting at the initialization (namely creating the 3D object, and mapping the voltage recordings to the appropriate colors). For a quick demo, the code below can be run on my laptop on a single core in approximately 20 sec:

from hnn_core import jones_2009_model, simulate_dipole
from hnn_core.network_models import add_erp_drives_to_jones_model
from hnn_core.viz import NetworkPlot

net = jones_2009_model()
net.set_cell_positions(inplane_distance=300)
add_erp_drives_to_jones_model(net)
dpl = simulate_dipole(net, dt=0.5, tstop=170, record_vsec='all')

net_plot = NetworkPlot(net)

image

If you want to play around with visualizing the voltages, you can try the following code block:

from ipywidgets import interact, IntSlider

def update_plot(t_idx, elev, azim):
    net_plot.update_section_voltages(t_idx)
    net_plot.elev = elev
    net_plot.azim = azim
    return net_plot.fig

time_slider = IntSlider(min=0, max=len(net_plot.times), value=1, continuous_update=False)
elev_slider = IntSlider(min=-100,max=100, value=10, continuous_update=False)
azim_slider = IntSlider(min=-100,max=100, value=-100, continuous_update=False)

interact(update_plot, t_idx=time_slider, elev=elev_slider, azim=azim_slider)

image

ntolley commented 1 year ago

@jasmainak @rythorpe perhaps it'd be a good idea to make this a separate file? If we can find a solution to updating the section colors very rapidly, we can even consider adding a "play" button inside the GUI (or on the HNN website!) like the example here: https://matplotlib.org/stable/gallery/animation/unchained.html

@chenghuzi you might have some good insight on how to make the current code more "reactive"

codecov-commenter commented 1 year ago

Codecov Report

Attention: Patch coverage is 95.17544% with 11 lines in your changes are missing coverage. Please review.

Project coverage is 91.51%. Comparing base (819f4f4) to head (db60ec2). Report is 1 commits behind head on master.

:exclamation: Current head db60ec2 differs from pull request most recent head e9a94ef

Please upload reports for the commit e9a94ef to get more accurate results.

Files Patch % Lines
hnn_core/viz.py 95.13% 11 Missing :warning:

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #649 +/- ## ========================================== - Coverage 92.33% 91.51% -0.82% ========================================== Files 27 25 -2 Lines 5059 4819 -240 ========================================== - Hits 4671 4410 -261 - Misses 388 409 +21 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

jasmainak commented 1 year ago

Agnostic about saving to a different file ... see my comment about the azimuth/elevation control. Maybe it makes the class thinner?

ntolley commented 1 year ago

Dropping this here for easy testing once we get closer to merging. I think rendering movies is going to be a longish wait for larger networks, but not absurdly so (maybe like 5-10 minutes? if you downsample?)

import hnn_core
import os.path as op
from hnn_core import jones_2009_model, simulate_dipole, read_params
from hnn_core.network_models import add_erp_drives_to_jones_model
from hnn_core.viz import NetworkPlot

hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'default.json')
params = read_params(params_fname)
params.update({'N_pyr_x': 3, 'N_pyr_y': 3})
net = jones_2009_model(params)
net.set_cell_positions(inplane_distance=300)
add_erp_drives_to_jones_model(net)
dpl = simulate_dipole(net, dt=0.5, tstop=170, record_vsec='all')

net_plot = NetworkPlot(net)
net_plot.export_movie('demo.gif', dpi=200)

demo

chenghuzi commented 1 year ago

@jasmainak @rythorpe perhaps it'd be a good idea to make this a separate file? If we can find a solution to updating the section colors very rapidly, we can even consider adding a "play" button inside the GUI (or on the HNN website!) like the example here: https://matplotlib.org/stable/gallery/animation/unchained.html

@chenghuzi you might have some good insight on how to make the current code more "reactive"

Great work! Although, I'm concerned about the reactivity of our GUI. We are taking snapshots from the buffer and using imshow to render network images for now. So, it might be difficult to have real-time interaction in the new GUI with these new settings. But this will not affect the current function so there is nothing else to worry about.

ntolley commented 1 year ago

@rythorpe @jasmainak this PR is ready for review! Two weird errors have come up however. First it seems like sphinx-gallery doesn't support python versions older than 3.8 image

Does this mean our minimum python version needs to be updated?

Also the windows unit tests are failing with an error in the GUI code... image

This is the offending line in case you guys have any ideas on the possible cause: https://github.com/ntolley/hnn-core/blob/e3aa27c91ba4ed7478d2214e53fea618b793f45b/hnn_core/tests/test_viz.py#L23C5-L23C5

ntolley commented 1 year ago

Yup just confirmed, sphinx now requires python>=3.8

https://github.com/sphinx-gallery/sphinx-gallery/blob/e2903c9e43572a0a29850f7ab153ff69098f5c81/setup.py#L58C5-L58C5

rythorpe commented 1 year ago

@rythorpe @jasmainak this PR is ready for review! Two weird errors have come up however. First it seems like sphinx-gallery doesn't support python versions older than 3.8 image

Does this mean our minimum python version needs to be updated?

Also the windows unit tests are failing with an error in the GUI code... image

This is the offending line in case you guys have any ideas on the possible cause: https://github.com/ntolley/hnn-core/blob/e3aa27c91ba4ed7478d2214e53fea618b793f45b/hnn_core/tests/test_viz.py#L23C5-L23C5

Ugh, I'm guessing the most recent version of matplotlib has diverged for windows vs. linux. Something to do with the agg backend....

ntolley commented 1 year ago

Ok updating the python version used for CircleCI worked, however it seems something in the MNE code is breaking the somato example now: image

jasmainak commented 1 year ago

it seems something in the MNE code is breaking the somato example now:

looks like nibabel is now being used in MNE for reading the surface files ... I reported this upstream:

https://github.com/mne-tools/mne-python/pull/11565/files#r1337642633

hopefully it'll get fixed soon but probably still won't be reflected in the current release. We may want to add nibabel as an added install in the CI with a note to remove it when MNE does it automatically

jasmainak commented 9 months ago

@rythorpe @gtdang could you guys review and merge this PR if it's good by you? I am finding it difficult to find time and don't want to block progress ... this could be a good excuse for a release.

rythorpe commented 7 months ago

Just in case this slipped your attention @ntolley, this PR is sooooo close ;-)

rythorpe commented 5 months ago

@ntolley do you know if plot_cell_morphology sets the length of each cell section before plotting it? Or are the section endpoints already updated with the appropriate length? Apologies if we already hashed this out, I just can't remember and was wondering about this the other day....

ntolley commented 5 months ago

@rythorpe they are updated automatically! #433 fixed this early on, but then Rajat's project made a new and improved version where he implemented the Neuron functions for calculating end points directly in our python code (necessary for saving this infromation in a JSON/dict format)

ntolley commented 5 months ago

@jasmainak this is ready for a final round of reviews when you have the chance!

I think there are some tasks that might be delegated to followup PR's (e.g. a better jupyter notebook tutorial?), but in terms of basic functionality and readability I think this is in a good place

jasmainak commented 5 months ago

@ntolley this is tremendous!!! 🥳 when can I have the privilege of merging it? I tried it and it works really nice. @rythorpe did you want to look? It's good to go on my end.

One feature request: perhaps we can have a small text in the corner showing the timestamp ... I was a bit confused whether the plot was still updating (or is it instantaneous?) when I moved it around.

jasmainak commented 5 months ago

@gtdang do you still have remaining objections? Merging seems blocked because of your comments

jasmainak commented 5 months ago

Don't forget to update whats_new.rst !

rythorpe commented 5 months ago

Aside from @jasmainak's spelling error and my incredibly nitpicky punctuation suggestion above, this looks great @ntolley !

rythorpe commented 5 months ago

I've enabled auto-merge! Thanks @ntolley for this incredible feature - I'm very excited to put it to good use :smile: