ome/napari-ome-zarr

Converting image to labels

Closed this issue · 1 comments

Hello!

I have a couple of datasets with have segmentations in them, stored under /labels/mask. The plugin loads the image and the label just fine, displaying both layers:
image

However, we aim to edit the segmentations to edit some mistakes that our automatic process makes. For this we want to convert the /[1] image to a label by right-clicking and choosing the "Convert to labels" option:
image

This results in the error below, however. Is this a problem with our implementation or there something in the plugin which it doesn't like?

AttributeError                            Traceback (most recent call last)
File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/app_model/backends/qt/_qaction.py:62, in QCommandAction._on_triggered(self=QMenuItemAction(MenuItem(when=None, group='1_con...tle=None, toggled=None), alt=None), app='napari'), checked=False)
     58 def _on_triggered(self, checked: bool) -> None:
     59     # execute_command returns a Future, for the sake of eventually being
     60     # asynchronous without breaking the API.  For now, we call result()
     61     # to raise any exceptions.
---> 62     self._app.commands.execute_command(self._command_id).result()
        self._command_id = 'napari:layer:convert_to_labels'
        self = QMenuItemAction(MenuItem(when=None, group='1_conversion', order=None, command=CommandRule(id='napari:layer:convert_to_labels', title='Convert to Labels', category=None, tooltip=None, status_tip=None, icon=None, enablement=Expr.parse('num_selected_image_layers >= 1 or num_selected_shapes_layers >= 1 and all_selected_layers_same_type and not selected_empty_shapes_layer'), short_title=None, toggled=None), alt=None), app='napari')
        self._app = Application('napari')

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/app_model/registries/_commands_reg.py:206, in CommandsRegistry.execute_command(self=<CommandsRegistry at 0x1446362b0 (101 commands)>, id='napari:layer:convert_to_labels', execute_asynchronously=False, *args=(), **kwargs={})
    202 except Exception as e:
    203     if self._raise_synchronous_exceptions:
    204         # note, the caller of this function can also achieve this by
    205         # calling `future.result()` on the returned future object.
--> 206         raise e
    207     future.set_exception(e)
    209 return future

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/app_model/registries/_commands_reg.py:201, in CommandsRegistry.execute_command(self=<CommandsRegistry at 0x1446362b0 (101 commands)>, id='napari:layer:convert_to_labels', execute_asynchronously=False, *args=(), **kwargs={})
    199 future: Future = Future()
    200 try:
--> 201     future.set_result(cmd(*args, **kwargs))
        future = <Future at 0x145a592b0 state=pending>
        cmd = <function _convert_to_labels at 0x2a2ffd310>
        args = ()
        kwargs = {}
    202 except Exception as e:
    203     if self._raise_synchronous_exceptions:
    204         # note, the caller of this function can also achieve this by
    205         # calling `future.result()` on the returned future object.

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/in_n_out/_store.py:936, in Store.inject_processors.<locals>._deco.<locals>._exec(*args=(), **kwargs={})
    934 @wraps(func)
    935 def _exec(*args: P.args, **kwargs: P.kwargs) -> R:
--> 936     result = func(*args, **kwargs)
        func = <function _convert_to_labels at 0x2a2421670>
        args = ()
        kwargs = {}
    937     if result is not None:
    938         self.process(
    939             result,
    940             type_hint=type_hint,
   (...)
    943             _funcname=getattr(func, "__qualname__", str(func)),
    944         )

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/in_n_out/_store.py:804, in Store.inject.<locals>._inner.<locals>._exec(*args=(), **kwargs={})
    797 logger.debug(
    798     "  Calling %s with %r (injected %r)",
    799     _fname,
    800     bound.arguments,
    801     _injected_names,
    802 )
    803 try:
--> 804     result = func(**bound.arguments)
        bound = <BoundArguments (ll=[<Image layer '/' at 0x2a08226d0>])>
        func = <function _convert_to_labels at 0x142fb60d0>
        bound.arguments = {'ll': [<Image layer '/' at 0x2a08226d0>]}
    805 except TypeError as e:
    806     if "missing" not in e.args[0]:

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/napari/layers/_layer_actions.py:70, in _convert_to_labels(ll=[<Image layer '/' at 0x2a08226d0>])
     69 def _convert_to_labels(ll: LayerList):
---> 70     return _convert(ll, 'labels')
        ll = [<Image layer '/' at 0x2a08226d0>]

File ~/Library/napari-0.4.18/envs/napari-0.4.18/lib/python3.9/site-packages/napari/layers/_layer_actions.py:59, in _convert(ll=[<Image layer '/' at 0x2a08226d0>], type_='labels')
     57     data = lay.to_labels()
     58 else:
---> 59     data = lay.data.astype(int) if type_ == 'labels' else lay.data
        lay = <Image layer '/ [1]' at 0x16a379f10>
        type_ == 'labels' = True
        type_ = 'labels'
     60 new_layer = Layer.create(data, lay._get_base_state(), type_)
     61 ll.insert(idx, new_layer)

AttributeError: 'MultiScaleData' object has no attribute 'astype'```

Update:
After some messing around with the metadata it seems to work as intended now. There was something not quite right with the way I wrote the labels to the zarr file.