napari-nD-annotator icon indicating copy to clipboard operation
napari-nD-annotator copied to clipboard

Bug with napari>=0.5

Open m-albert opened this issue 1 year ago • 6 comments

Hey, I've just tried out napari-nd-annotator and find it super cool and useful! Thanks a lot!

Wanted to report this here quickly: In napari>=0.5, layers no longer have a layer._slice_indices attribute and this raises errors when using napari-nd-annotator (discovered while interpolating slices).

Independently of a fix, it might already be super useful to pin napari to <0.5.0 in the dependencies.

Thanks again for this great package :)

m-albert avatar Jul 24 '24 17:07 m-albert

Hey @m-albert, thanks for the info! Glad you like the plugin 🙂. I didn't yet get to test the plugin on newer napari versions, although I wouldn't want to create a new release for limiting the napari version. I'll try to fix it asap, although I cannot promise it will come in the upcoming weeks...

bauerdavid avatar Jul 26 '24 09:07 bauerdavid

Luckily only a small change was needed to make it work for the newer napari versions. I will make a new release soon, until then you can build from code (already committed to main), if you need it right away.

bauerdavid avatar Aug 03 '24 08:08 bauerdavid

Hey @bauerdavid, thanks a lot for fixing this :) So far I had been using your tool with napari < 0.5 but this will be super useful for integration with the newer versions. Thanks again!

m-albert avatar Aug 05 '24 13:08 m-albert

Hello,

Similarly to layers, it seems that AttributeError: 'BoundingBoxLayer' object has no attribute '_slice_indices'

System info: napari: 0.5.4 Platform: Windows-10-10.0.19045-SP0 Python: 3.10.15 | packaged by conda-forge | (main, Oct 16 2024, 01:15:49) [MSC v.1941 64 bit (AMD64)] Qt: 5.15.2 PyQt5: 5.15.11 NumPy: 1.26.4 SciPy: 1.14.1 Dask: 2024.10.0 VisPy: 0.14.3 magicgui: 0.9.1 superqt: 0.6.7 in-n-out: 0.2.1 app-model: 0.3.0 psygnal: 0.11.1 npe2: 0.7.7 pydantic: 2.9.2

with the very last version of nd-annotator pulled from the github.

Thanks!

TAspert avatar Oct 17 '24 15:10 TAspert

@TAspert could you copy the whole trace? My guess is that you should also update the napari-bbox package.

bauerdavid avatar Oct 18 '24 10:10 bauerdavid

After a clean install of napari napari: 0.5.4 Platform: Windows-10-10.0.19045-SP0 Python: 3.10.15 | packaged by conda-forge | (main, Oct 16 2024, 01:15:49) [MSC v.1941 64 bit (AMD64)] Qt: 5.15.8 PyQt5: 5.15.9 NumPy: 2.0.2 SciPy: 1.14.1 Dask: 2024.10.0 VisPy: 0.14.3 magicgui: 0.8.3 superqt: 0.6.7 in-n-out: 0.2.1 app-model: 0.3.0 psygnal: 0.11.1 npe2: 0.7.7 pydantic: 2.0.3

followed by: pip install git+https://github.com/bauerdavid/napari-nd-annotator.git and pip install git+https://github.com/bauerdavid/napari-bbox.git

When launching napari:

Traceback (most recent call last):
  File "C:\Users\Administrateur\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\_utils\persistence\persistent_widget_state.py", line 37, in __init__
    with open(self._config_path, "w") as new_file, open(default_settings_path, "r") as def_file:
FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/Administrateur/AppData/Local/napari/napari\\nd_annotator_config.yaml'
C:\Users\Administrateur\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\_utils\persistence\persistent_widget_state.py:77: UserWarning: id 'method_dropdown' not found in config file!
C:\Users\Administrateur\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\_utils\persistence\persistent_widget_state.py:77: UserWarning: id 'n_points' not found in config file!
C:\Users\Administrateur\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\_utils\persistence\persistent_widget_state.py:77: UserWarning: id 'rpsv_iterations_spinbox' not found in config file!
Traceback (most recent call last):
  File "C:\Users\Administrateur\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\_utils\persistence\persistent_widget_state.py", line 37, in __init__
    with open(self._config_path, "w") as new_file, open(default_settings_path, "r") as def_file:
FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/Administrateur/AppData/Local/napari/napari\\nd_annotator_config.yaml'

Then, when trying to create a BoundingBox:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~\anaconda3\envs\napari-env6\lib\site-packages\vispy\app\backends\_qt.py:506, in QtBaseCanvasBackend.mouseReleaseEvent(self=<vispy.app.backends._qt.CanvasBackendDesktop object>, ev=<PyQt5.QtGui.QMouseEvent object>)
    504 if self._vispy_canvas is None:
    505     return
--> 506 self._vispy_mouse_release(
        self = <vispy.app.backends._qt.CanvasBackendDesktop object at 0x000001D5AF109C60>
        ev = <PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0>
        BUTTONMAP = {0: 0, 1: 1, 2: 2, 4: 3, 8: 4, 16: 5}
    507     native=ev,
    508     pos=_get_event_xy(ev),
    509     button=BUTTONMAP[ev.button()],
    510     modifiers=self._modifiers(ev),
    511 )

File ~\anaconda3\envs\napari-env6\lib\site-packages\vispy\app\base.py:224, in BaseCanvasBackend._vispy_mouse_release(self=<vispy.app.backends._qt.CanvasBackendDesktop object>, **kwargs={'button': 1, 'buttons': [1], 'last_event': <MouseEvent blocked=False button=1 buttons=[1] d...urces=[] time=1729263629.2477193 type=mouse_move>, 'last_mouse_press': None, 'modifiers': (), 'native': <PyQt5.QtGui.QMouseEvent object>, 'pos': (1107, 908), 'press_event': <MouseEvent blocked=False button=1 buttons=[1] d...rces=[] time=1729263628.0712779 type=mouse_press>})
    220 def _vispy_mouse_release(self, **kwargs):
    221     # default method for delivering mouse release events to the canvas
    222     kwargs.update(self._vispy_mouse_data)
--> 224     ev = self._vispy_canvas.events.mouse_release(**kwargs)
        self._vispy_canvas.events.mouse_release = <vispy.util.event.EventEmitter object at 0x000001D5AF10E650>
        kwargs = {'native': <PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0>, 'pos': (1107, 908), 'button': 1, 'modifiers': (), 'buttons': [1], 'press_event': <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=False last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[20 32] press_event=None source=None sources=[] time=1729263628.0712779 type=mouse_press>, 'last_event': <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.2477193 type=mouse_move>, 'last_mouse_press': None}
        self = <vispy.app.backends._qt.CanvasBackendDesktop object at 0x000001D5AF109C60>
        self._vispy_canvas.events = <vispy.util.event.EmitterGroup object at 0x000001D5AF10E560>
        self._vispy_canvas = <NapariSceneCanvas (PyQt5) at 0x1d5af10c580>
    225     if (self._vispy_mouse_data['press_event']
    226             and self._vispy_mouse_data['press_event'].button == ev.button):
    227         self._vispy_mouse_data['press_event'] = None

File ~\anaconda3\envs\napari-env6\lib\site-packages\vispy\util\event.py:453, in EventEmitter.__call__(self=<vispy.util.event.EventEmitter object>, *args=(), **kwargs={'button': 1, 'buttons': [1], 'last_event': <MouseEvent blocked=False button=1 buttons=[1] d...urces=[] time=1729263629.2477193 type=mouse_move>, 'last_mouse_press': None, 'modifiers': (), 'native': <PyQt5.QtGui.QMouseEvent object>, 'pos': (1107, 908), 'press_event': <MouseEvent blocked=False button=1 buttons=[1] d...rces=[] time=1729263628.0712779 type=mouse_press>})
    450 if self._emitting > 1:
    451     raise RuntimeError('EventEmitter loop detected!')
--> 453 self._invoke_callback(cb, event)
        event = <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.423459 type=mouse_release>
        self = <vispy.util.event.EventEmitter object at 0x000001D5AF10E650>
        cb = <bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object at 0x000001D5AF10C3D0>>
    454 if event.blocked:
    455     break

File ~\anaconda3\envs\napari-env6\lib\site-packages\vispy\util\event.py:471, in EventEmitter._invoke_callback(self=<vispy.util.event.EventEmitter object>, cb=<bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object>>, event=<MouseEvent blocked=False button=1 buttons=[1] d...ces=[] time=1729263629.423459 type=mouse_release>)
    469     cb(event)
    470 except Exception:
--> 471     _handle_exception(self.ignore_callback_errors,
        self = <vispy.util.event.EventEmitter object at 0x000001D5AF10E650>
        cb = <bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object at 0x000001D5AF10C3D0>>
        event = <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.423459 type=mouse_release>
        (cb, event) = (<bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object at 0x000001D5AF10C3D0>>, <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.423459 type=mouse_release>)
    472                       self.print_callback_errors,
    473                       self, cb_event=(cb, event))

File ~\anaconda3\envs\napari-env6\lib\site-packages\vispy\util\event.py:469, in EventEmitter._invoke_callback(self=<vispy.util.event.EventEmitter object>, cb=<bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object>>, event=<MouseEvent blocked=False button=1 buttons=[1] d...ces=[] time=1729263629.423459 type=mouse_release>)
    467 def _invoke_callback(self, cb, event):
    468     try:
--> 469         cb(event)
        cb = <bound method VispyCanvas._on_mouse_release of <napari._vispy.canvas.VispyCanvas object at 0x000001D5AF10C3D0>>
        event = <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.423459 type=mouse_release>
    470     except Exception:
    471         _handle_exception(self.ignore_callback_errors,
    472                           self.print_callback_errors,
    473                           self, cb_event=(cb, event))

File ~\anaconda3\envs\napari-env6\lib\site-packages\napari\_vispy\canvas.py:484, in VispyCanvas._on_mouse_release(self=<napari._vispy.canvas.VispyCanvas object>, event=<MouseEvent blocked=False button=1 buttons=[1] d...ces=[] time=1729263629.423459 type=mouse_release>)
    472 def _on_mouse_release(self, event: MouseEvent) -> None:
    473     """Called whenever mouse released in canvas.
    474
    475     Parameters
   (...)
    482     None
    483     """
--> 484     self._process_mouse_event(mouse_release_callbacks, event)
        event = <MouseEvent blocked=False button=1 buttons=[1] delta=[0. 0.] handled=False is_dragging=True last_event=MouseEvent modifiers=() native=<PyQt5.QtGui.QMouseEvent object at 0x000001D5B90ABBE0> pos=[1107  908] press_event=MouseEvent source=None sources=[] time=1729263629.423459 type=mouse_release>
        self = <napari._vispy.canvas.VispyCanvas object at 0x000001D5AF10C3D0>

File ~\anaconda3\envs\napari-env6\lib\site-packages\napari\_vispy\canvas.py:417, in VispyCanvas._process_mouse_event(self=<napari._vispy.canvas.VispyCanvas object>, mouse_callbacks=<function mouse_release_callbacks>, event=<ReadOnlyWrapper at 0x000001D5BF01A2C0 for MouseEvent>)
    415 layer = self.viewer.layers.selection.active
    416 if layer is not None:
--> 417     mouse_callbacks(layer, event)
        event = <ReadOnlyWrapper at 0x000001D5BF01A2C0 for MouseEvent at 0x000001D5BF06AD10>
        layer = <BoundingBoxLayer layer 'BoundingBoxLayer' at 0x1d5b9a9c1f0>
        mouse_callbacks = <function mouse_release_callbacks at 0x000001D5AA2D7C70>

File ~\anaconda3\envs\napari-env6\lib\site-packages\napari\utils\interactions.py:216, in mouse_release_callbacks(obj=<BoundingBoxLayer layer 'BoundingBoxLayer'>, event=<ReadOnlyWrapper at 0x000001D5BF01A2C0 for MouseEvent>)
    213 obj._persisted_mouse_event[gen].__wrapped__ = event
    214 with contextlib.suppress(StopIteration):
    215     # Run last part of the function to trigger release event
--> 216     next(gen)
        gen = <generator object ObjectListWidget.bounding_box_change at 0x000001D5BB4C3E60>
    217 # Finally delete the generator and stored event
    218 del obj._mouse_drag_gen[func]

File ~\anaconda3\envs\napari-env6\lib\site-packages\napari_nd_annotator\_widgets\object_list.py:478, in ObjectListWidget.bounding_box_change(self=<napari_nd_annotator._widgets.object_list.ObjectListWidget object>, layer=<BoundingBoxLayer layer 'BoundingBoxLayer'>, event=<ReadOnlyWrapper at 0x000001D5BF0A2780 for ReadOnlyWrapper>)
    476 if len(new_data) > len(previous_data):
    477     layer.data[-1][:] = np.clip(layer.data[-1], 0, np.asarray(self.image_layer.data.shape) - 1)
--> 478     layer.data = layer.data
        layer = <BoundingBoxLayer layer 'BoundingBoxLayer' at 0x1d5b9a9c1f0>
    479 self.update_items()
    480 if self.projections_widget is not None:

File ~\anaconda3\envs\napari-env6\lib\site-packages\napari_bbox\boundingbox\napari_0_4_18\bounding_boxes.py:594, in BoundingBoxLayer.data(self=<BoundingBoxLayer layer 'BoundingBoxLayer'>, data=array([[[  0., 511., 511.],
        [ 32., 511.,...[  0., 511.,   0.],
        [ 32., 511.,   0.]]]))
    586     face_color = np.concatenate(
    587         (
    588             face_color,
    589             self._get_new_bounding_box_color(n_bounding_boxes_difference, 'face'),
    590         )
    591     )
    593 self._data_view = BoundingBoxList(ndisplay=self._slice_input.ndisplay)
--> 594 self._data_view.slice_key = np.array(self._slice_indices)[
        self._data_view = <napari_bbox.boundingbox.napari_0_4_18._bounding_box_list.BoundingBoxList object at 0x000001D5C0F40FA0>
        self = <BoundingBoxLayer layer 'BoundingBoxLayer' at 0x1d5b9a9c1f0>
        np = <module 'numpy' from 'C:\\Users\\Administrateur\\anaconda3\\envs\\napari-env6\\lib\\site-packages\\numpy\\__init__.py'>
        self._slice_input = _SliceInput(ndisplay=2, world_slice=_ThickNDSlice(point=(np.float64(16.0), np.float64(255.34377141400137), np.float64(255.20712346099785)), margin_left=(np.float64(0.0), np.float64(0.0), np.float64(0.0)), margin_right=(np.float64(0.0), np.float64(0.0), np.float64(0.0))), order=(np.int64(0), np.int64(1), np.int64(2)))
    595     self._slice_input.not_displayed
    596 ]
    597 self.add(
    598     data,
    599     edge_width=edge_widths,
   (...)
    602     z_index=z_indices,
    603 )
    605 self._update_dims()

AttributeError: 'BoundingBoxLayer' object has no attribute '_slice_indices'

The rest of the plugin seems to work normally.

TAspert avatar Oct 18 '24 15:10 TAspert

I'm still not able to use the plugin with napari > 0.5. Were the changes ever implemented?

mrariden avatar Jul 30 '25 17:07 mrariden

The plugin was updated, so the error should have been gone. Are you using the newest version? Could you provide some information about the error? Stack trace, napari info would be super useful.

bauerdavid avatar Jul 30 '25 19:07 bauerdavid