bauerdavid / napari-nD-annotator

BSD 3-Clause "New" or "Revised" License
29 stars 2 forks source link

Bug with napari>=0.5 #50

Open m-albert opened 3 months ago

m-albert commented 3 months ago

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 :)

bauerdavid commented 3 months ago

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 commented 2 months ago

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.

m-albert commented 2 months ago

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!

TAspert commented 1 week ago

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!

bauerdavid commented 1 week ago

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

TAspert commented 1 week ago

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.