napari-spatialdata icon indicating copy to clipboard operation
napari-spatialdata copied to clipboard

Issues reproducing annotation notebooks

Open clwgg opened this issue 2 years ago • 2 comments

I've been trying to reproduce the two annotation notebooks from the spatialdata tutorials, and am running into different issues with both of them:

I tried reproducing this one as described and shown in the gif, but when I add a new points layer and press SHIFT+E nothing happens. When I afterwards inspect the SpatialData object, it appears unchanged. Any guidance on how to further debug this would be appreciated.

When I instead annotate a shapes layer as shown in the second notebook and press SHIFT+E, I get an error with a long traceback, the last four entries of which are:

File ~/src/napari-3.10/venv/lib/python3.10/site-packages/napari/utils/key_bindings.py:545, in KeymapHandler.on_key_press(self=<napari.utils.key_bindings.KeymapHandler object>, event=<KeyEvent blocked=False handled=False key=<Key '...c0> source=None sources=[] text=E type=key_press>)
    535 if (
    536     event.native is not None
    537     and event.native.isAutoRepeat()
   (...)
    541     # unless the combo being held down is one of the autorepeatables or
    542     # one of the navigation keys (helps with scrolling).
    543     return
--> 545 self.press_key(combo)
        combo = 'Shift-E'
        self = <napari.utils.key_bindings.KeymapHandler object at 0x2a324d300>

File ~/src/napari-3.10/venv/lib/python3.10/site-packages/napari/utils/key_bindings.py:470, in KeymapHandler.press_key(self=<napari.utils.key_bindings.KeymapHandler object>, key_combo='Shift-E')
    461 if not callable(func):
    462     raise TypeError(
    463         trans._(
    464             "expected {func} to be callable",
   (...)
    467         )
    468     )
--> 470 generator_or_callback = func()
        func = <bound method QtAdataViewWidget.export of Viewer(camera=Camera(center=(0.0, 10785.0, 9752.0), zoom=0.046125222806246056, angles=(0.0, 0.0, 90.0), perspective=0.0, mouse_pan=False, mouse_zoom=True), cursor=Cursor(position=(20519.370711726915, 18857.64737205759), scaled=True, size=1, style=<CursorStyle.CROSS: 'cross'>), dims=Dims(ndim=2, ndisplay=2, last_used=0, range=((0.0, 21571.0, 1.0), (0.0, 19505.0, 1.0)), current_step=(10785, 9752), order=(0, 1), axis_labels=('0', '1')), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[<Image layer 'CytAssist_FFPE_Human_Breast_Cancer_full_image' at 0x3129f5060>, <Shapes layer 'Shapes' at 0x311fe9210>], help='use <6> for pan/zoom, use <2> for transform, use <R> for add rectangles, use <L> for add lines, use <T> for add path, use <P> for add polygons, use <Shift-P> for add polygons lasso, use <4> for select vertices, use <5> for select shapes, use <2> for insert vertex, use <1> for remove vertex', status={'layer_base': 'Shapes', 'source_type': '', 'plugin': '', 'coordinates': ' [20519 18858]: [, ]'}, tooltip=Tooltip(visible=False, text=''), theme='dark', title='napari', mouse_over_canvas=True, mouse_move_callbacks=[], mouse_drag_callbacks=[], mouse_double_click_callbacks=[], mouse_wheel_callbacks=[<function dims_scroll at 0x2a13311b0>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, keymap={'Shift-L': <bound method SpatialDataViewer._inherit_metadata of <napari_spatialdata._viewer.SpatialDataViewer object at 0x2c7e44a30>>, 'Shift-E': <bound method QtAdataViewWidget.export of <napari_spatialdata._view.QtAdataViewWidget object at 0x2c7b86c20>>})>
    472 if inspect.isgeneratorfunction(func):
    473     try:

File ~/src/napari-3.10/venv/lib/python3.10/site-packages/napari_spatialdata/_view.py:292, in QtAdataViewWidget.export(self=<napari_spatialdata._view.QtAdataViewWidget object>, _=Viewer(camera=Camera(center=(0.0, 10785.0, 9752...._view.QtAdataViewWidget object at 0x2c7b86c20>>}))
    289 key = f"{layer.name}_{self.model.layer.name}"  # type:ignore[union-attr]
    291 logger.info(f"Adding `adata.obs[{key!r}]`\n       `adata.uns[{key!r}]['mesh']`.")
--> 292 self._save_shapes(layer, key=key)
        layer = <Shapes layer 'Shapes' at 0x311fe9210>
        key = 'Shapes_Shapes'
        self = <napari_spatialdata._view.QtAdataViewWidget object at 0x2c7b86c20>
    293 self._update_obs_items(key)

File ~/src/napari-3.10/venv/lib/python3.10/site-packages/napari_spatialdata/_view.py:300, in QtAdataViewWidget._save_shapes(self=<napari_spatialdata._view.QtAdataViewWidget object>, layer=<Shapes layer 'Shapes'>, key='Shapes_Shapes')
    297 triangles = shape_list._mesh.vertices[shape_list._mesh.displayed_triangles]
    299 # TODO(giovp): check if view and save accordingly
--> 300 points_mask: NDArrayA = _points_inside_triangles(self.model.coordinates[:, 1:], triangles)
        triangles = <class 'numpy.ndarray'> (894, 3, 2) float64
        NDArrayA = numpy.ndarray[typing.Any, numpy.dtype[typing.Any]]
        _points_inside_triangles = CPUDispatcher(<function _points_inside_triangles at 0x2a23de290>)
        self = <napari_spatialdata._view.QtAdataViewWidget object at 0x2c7b86c20>
    302 if self._model._adata is not None:
    303     logger.info("Saving layer shapes.")

TypeError: 'NoneType' object is not subscriptable

I've tried both examples on various different python versions (3.9, 3.10, 3.11) and with different versions of the spatialdata and napari-spatialdata packages, including the latest pypi releases and github HEADs, and haven't been able to get it to work.

I'd greatly appreciate any help.

clwgg avatar Oct 13 '23 01:10 clwgg

We are aware of the issue and this is the result of an old implementation which most likely within a week will be changed. I am opening a PR today. I'll keep you posted. We are ultimately looking to combine this with partial writes to disk.

melonora avatar Oct 13 '23 10:10 melonora

I opened #168 as a draft. It does have a dependency on a PR currently being worked on in SpatialData.

melonora avatar Oct 15 '23 18:10 melonora