Allow viewer data to be updated in real-time (supersedes #142) - #675
Merged
Conversation
Rebases and completes GH-142: `JSMixer.addData` lets you push new data into an already running `cortex.webshow` viewer, without restarting the server: client = cortex.webshow(volume) client.addData(second=other_volume) The method was dead code -- it referenced `_convert_dataset` and `Dataset`, neither of which exists in `cortex.webgl.view`, so any call raised `NameError`, and it proxied to `window.viewers`, which the mixer page never defines. Changes: - `show()` keeps the packaged metadata as a dict instead of a JSON string, and serializes it when the mixer page is generated. That lets `addData` merge new dataviews into it, so a page reload shows everything that has been added so far. - `addData` builds a `Package` for the new dataviews, reorders vertex data against the ctm files the viewer was started with, registers the new images with the data handler, merges the metadata, and sends only the new dataviews to the browser. Adding a name that is already displayed replaces it, and the images of the replaced dataview are dropped so that repeatedly refreshing data does not pile up unused buffers in the server. Data for a subject the viewer was not started with is rejected with a clear `ValueError`, since surfaces cannot be added to a running viewer. - `mriview.Viewer.addData` (and `mriview.MultiView.addData`) now accept the raw metadata package in addition to `dataset.DataView` objects. Tests: the `xfail`-ed `test_addData_no_crash` is replaced by a `TestAddData` group covering dataview registration and switching, the metadata served on reload, the rendered image actually changing, name replacement and the pruning that goes with it, and the unknown-subject error, plus a separate test for vertex data (which exercises the reorder path).
Brings in #681, which fixes vmin/vmax being left as numpy float32 when not specified. That matters here: since show() now serializes the metadata at page-generation time rather than once at startup, a dataview with computed vmin/vmax made every subsequent GET /mixer.html fail with "Object of type float32 is not JSON serializable" -- so addData could silently leave a running viewer unable to reload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PLJk77nSbbqh7QRFzhWbmB
mvdoc
added a commit
to mvdoc/pycortex
that referenced
this pull request
Aug 21, 2026
* origin/main: (44 commits) WebGL viewer: make opacity slider and `o` toggle work for Vertex data (gallantlab#685) docs(mapper): add get_mapper docstring (gallantlab#686) ENH add types for dataset classes (BrainData, Dataview, ...) (gallantlab#669) Allow viewer data to be updated in real-time (gallantlab#675) FIX: fix minor bug in handling of vmin and vmax when not specified (replaces old cast code) (gallantlab#681) docs: correct the sulcus install instructions, which destroyed existing sulci (gallantlab#657) WebGL viewer: fix help-menu shortcut display (gallantlab#642) MNT ignore docs build outputs written into the source tree (gallantlab#680) DOC fix build warnings (gallantlab#673) webgl: bind an OS-assigned ephemeral port for the viewer server (gallantlab#676) ENH add types for Database and transforms (gallantlab#667) MNT remove obsolete Python 2 syntax, add some types (gallantlab#666) Bump JamesIves/github-pages-deploy-action from 4.8.0 to 4.9.0 (gallantlab#671) Bump actions/setup-python from 6 to 7 (gallantlab#661) docs: document in-browser sulcus drawing (pycortex-roidraw v0.4.0) (gallantlab#656) ENH Pure-python surf2surf matrix (direct nnfr construction) (gallantlab#651) Bump actions/cache from 5 to 6 (gallantlab#654) webgl: fix overlay/label async texture-bake races (complete) (gallantlab#653) docs: add in-browser ROI drawing (pycortex-roidraw) page (gallantlab#652) FIX: update BuWtRd and BuWtRd_alpha colormaps to have pure white at center, more sensible for biphasic data (gallantlab#649) ... # Conflicts: # cortex/quickflat/composite.py # cortex/utils.py # cortex/webgl/resources/js/shaderlib.js # cortex/webgl/view.py
alexhuth
pushed a commit
that referenced
this pull request
Aug 21, 2026
Rebases and completes GH-142: `JSMixer.addData` lets you push new data into an already running `cortex.webshow` viewer, without restarting the server: client = cortex.webshow(volume) client.addData(second=other_volume) The method was dead code -- it referenced `_convert_dataset` and `Dataset`, neither of which exists in `cortex.webgl.view`, so any call raised `NameError`, and it proxied to `window.viewers`, which the mixer page never defines. Changes: - `show()` keeps the packaged metadata as a dict instead of a JSON string, and serializes it when the mixer page is generated. That lets `addData` merge new dataviews into it, so a page reload shows everything that has been added so far. - `addData` builds a `Package` for the new dataviews, reorders vertex data against the ctm files the viewer was started with, registers the new images with the data handler, merges the metadata, and sends only the new dataviews to the browser. Adding a name that is already displayed replaces it, and the images of the replaced dataview are dropped so that repeatedly refreshing data does not pile up unused buffers in the server. Data for a subject the viewer was not started with is rejected with a clear `ValueError`, since surfaces cannot be added to a running viewer. - `mriview.Viewer.addData` (and `mriview.MultiView.addData`) now accept the raw metadata package in addition to `dataset.DataView` objects. Tests: the `xfail`-ed `test_addData_no_crash` is replaced by a `TestAddData` group covering dataview registration and switching, the metadata served on reload, the rendered image actually changing, name replacement and the pruning that goes with it, and the unknown-subject error, plus a separate test for vertex data (which exercises the reorder path). Co-authored-by: Claude <noreply@anthropic.com>
Contributor
|
This PR may have introduced a race condition. See this failed run for an unrelated change: https://github.com/gallantlab/pycortex/actions/runs/32525918728/job/96907786022 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #142 by @r-b-g-b, whose branch predates the history rewrite and can no longer be merged (
refusing to merge unrelated histories). The idea and the original patch are theirs; this re-applies them to currentmain, fixes what no longer fit, and adds tests.What this does
JSMixer.addDatalets you push new data into an already runningcortex.webshowviewer, without restarting the server:Why the original patch needed rework
addDataonmainwas dead code in two ways:_convert_dataset(Dataset(...)), and neither name exists incortex.webgl.view— any call raisedNameError(there was anxfailed test pinning exactly that);window.viewers.addData, butmixer.htmlonly ever defineswindow.viewer, amriview.Viewerrather than themriview.MultiViewthe original patch modified.Changes
show()keeps the packaged metadata as a dict instead of a JSON string, and serializes it when the mixer page is generated (this part is unchanged from Allow viewer data to be updated in real-time #142). That is what letsaddDatamerge new dataviews into it, so reloading the page shows everything added so far.addDatabuilds aPackagefor the new dataviews, runsPackage.reorderagainst the ctm files the viewer was started with (vertex data is uploaded as a raw vertex attribute array, so it has to match the CTM vertex order), registers the new images with the data handler, merges the metadata, and sends only the new dataviews to the browser — Allow viewer data to be updated in real-time #142 sent the whole accumulated metadata, which would re-create every brain on each call.ValueError, since surfaces are baked into the page at startup and cannot be added to a running viewer.mriview.Viewer.addData(andmriview.MultiView.addData) accept the raw metadata package in addition todataset.DataViewobjects.Tests
The
xfailedtest_addData_no_crashis replaced by aTestAddDatagroup incortex/tests/test_webgl_headless.pycovering:mixer.htmlafter the call, including that every referenced image URL still returns a PNG;ValueError.Plus
test_addData_vertex_data, which exercises thereorderpath and checks the added vertex data is served as a raw.npyblob rather than a PNG mosaic.All six fail against the pre-fix code (
NameError) and pass with it; the two pruning assertions were separately confirmed to fail without the pruning change.🤖 Generated with Claude Code
https://claude.ai/code/session_013MCFG1Uez4JMFZK65KeTeT
Generated by Claude Code