Bug with napari>=0.5
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 :)
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...
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.
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!
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 could you copy the whole trace? My guess is that you should also update the napari-bbox package.
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.
I'm still not able to use the plugin with napari > 0.5. Were the changes ever implemented?
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.