niivue / ipyniivue

A WebGL-powered Jupyter Widget for Niivue based on anywidget
BSD 2-Clause "Simplified" License
25 stars 8 forks source link

load_meshes does not add the mesh to self.meshes in MacOS and Linux #38

Closed christian-oreilly closed 5 months ago

christian-oreilly commented 1 year ago

As can be seen from https://github.com/niivue/ipyniivue/actions/runs/5906991594/job/16024117873?pr=37, Windows CI works fine but not MacOS and Linux. The problem seems to be due to that part of the notebook tractography.ipynb

image

Apparently, in these two OS, the call to nv.load_meshes fails to add the mesh to nv.meshes so the indexing of that list at [0] fails. Looking under the hood a bit, what seems to fail is nv._send_custom(['loadMeshes', [mesh_list]]) which just seems to use the send method inherited from the ipywidgets DOMWidget class to send the command to NiiVue... so could the problem be on the NiiVue/JS side? @cdrake or @AnthonyAndroulakis , do you mind having a peak at it?

christian-oreilly commented 1 year ago

Actually, I had not paid attention to the comment The following is in a separate cell because we have to wait for the typescript end of the widget to update .meshes variable in the python end. which is useful here. On my Mac, the load_meshes just seems not to return (at least not within a few minutes)...

christian-oreilly commented 1 year ago

I guess this is linked to #33 although I find it strange that it would run on Windows, and not on Mac and Linux. If it is, it points out to another deeper issue: that called functions can crash silently, leaving the kernel waiting forever for a response.

christian-oreilly commented 1 year ago

I think I have been able to further narrow down the issue. Running notebooks/examples/tractography.ipynb in a jupyter notebook, if I hit "run all cells" it crashes the same way as with CI. If I run cells one at a time, it works. The issue with "run all cells" can be fixed by changing the notebook like this:

timeout = 10
start = time()
i = 1
with ui_events() as poll:
    while True:
        poll(1)
        if len(nv.meshes):
            break
        if time() > start + timeout:
            raise TimeoutError

nv.set_mesh_property(nv.meshes[0].id, "colormap", "blue")
nv.set_clip_plane([-0.1, 270, 0])

This allows the notebook to run its events while the cell is waiting for the mesh to be loaded. I'll fix the notebook like this for now so that the CI works, but I think it would require some more fundamental changes to ipyniivue to abstract away this complexity from the end user. I am not sure I have a clear and general solution for now...

christian-oreilly commented 1 year ago

Well, it looks like this change solved one issue but did not solve the issue initially reported in this ticket: the CI still works in Windows but fails for the other OS. The code timeout (after 60s) in these OS, indicating that the meshes are never added to the list of meshes available. AFAIK, the addition of meshes is made by the callback associated with updateMeshes https://github.com/niivue/ipyniivue/blob/262d967f868b05a22518c27766a43bd905a2721a/ipyniivue/niivue.py#L417-L418 ... maybe this event never gets sent (for some reason) in these OS?

christian-oreilly commented 11 months ago

@cdrake This issue is waiting for your input.