AllenCell / napari-allencell-segmenter

A plugin that enables image segmentation provided by Allen Institute for Cell Science
BSD 3-Clause "New" or "Revised" License
16 stars 6 forks source link

Can't save selected layer #124

Open benjijamorris opened 2 years ago

benjijamorris commented 2 years ago

This text document allows the plugin developers to gather the information they need to understand and prioritize your bug report. Please write your responses in the space below each section (replace [your answer here] with your answer), then click the "Submit new issue" button when you are finished. You can preview the formatting of this document using the Preview tab above.

Description

A clear description of the bug When I try to save a selected layer (like the output from segmenter), a file with the correct name appears but I can't open it in napari, aicsimageio, or imagej

Error message

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\implementation.py in __call__(self=<HookImplementation plugin='builtins' spec='napari_write_image' trylast>, *args=(r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp', <class 'numpy.ndarray'> (38, 600, 600) bool, {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}))
     65     def __call__(self, *args):
---> 66         return self.function(*args)
        self.function = <function napari_write_image at 0x000001563AA098B0>
        args = ('C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp', <class 'numpy.ndarray'> (38, 600, 600) bool, {'name': '6. Size Filter', 'metadata': {}, 'scale': [1.0, 1.0, 1.0], 'translate': [0.0, 0.0, 0.0], 'rotate': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'shear': [0.0, 0.0, 0.0], 'opacity': 1.0, 'blending': 'translucent', 'visible': 2, 'experimental_clipping_planes': [], 'rgb': False, 'multiscale': False, 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'interpolation': 'nearest', 'rendering': 'mip', 'experimental_slicing_plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'enabled': False, 'thickness': 1.0}, 'iso_threshold': 0.5, 'attenuation': 0.05, 'gamma': 1, 'data': <class 'numpy.ndarray'> (38, 600, 600) bool})
     67

~\Anaconda3\envs\napari_env\lib\site-packages\napari\plugins\_builtins.py in napari_write_image(path=r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp', data=<class 'numpy.ndarray'> (38, 600, 600) bool, meta={'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...})
    103     if ext in imsave_extensions():
--> 104         imsave(path, data)
        global imsave = <function imsave at 0x000001563A933940>
        path = 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp'
        data = <class 'numpy.ndarray'> (38, 600, 600) bool
    105         return path

~\Anaconda3\envs\napari_env\lib\site-packages\napari\utils\io.py in imsave(filename=r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp', data=<class 'numpy.ndarray'> (38, 600, 600) bool)
     58
---> 59         imageio.imsave(filename, data)
        imageio.imsave = <function imwrite at 0x000001563A966550>
        filename = 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp'
        data = <class 'numpy.ndarray'> (38, 600, 600) bool
     60

~\Anaconda3\envs\napari_env\lib\site-packages\imageio\core\functions.py in imwrite(uri=r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp', im=<class 'numpy.ndarray'> (38, 600, 600) bool, format=None, **kwargs={})
    293     if not np.issubdtype(im.dtype, np.number):
--> 294         raise ValueError("Image is not numeric, but {}.".format(imt.__name__))
        global ValueError.format = undefined
        imt.__name__ = 'ndarray'
    295     elif im.ndim == 2:

ValueError: Image is not numeric, but ndarray.

The above exception was the direct cause of the following exception:

PluginCallError                           Traceback (most recent call last)
~\Anaconda3\envs\napari_env\lib\site-packages\napari\_qt\menus\file_menu.py in <lambda>()
     49             {
     50                 'text': trans._('Save Selected Layer(s)...'),
---> 51                 'slot': lambda: window.qt_viewer._save_layers_dialog(
        global window.qt_viewer._save_layers_dialog = undefined
        global selected = undefined
     52                     selected=True
     53                 ),

~\Anaconda3\envs\napari_env\lib\site-packages\napari\_qt\qt_viewer.py in _save_layers_dialog(self=<napari._qt.qt_viewer.QtViewer object>, selected=True)
    530         if filename:
    531             with warnings.catch_warnings(record=True) as wa:
--> 532                 saved = self.viewer.layers.save(filename, selected=selected)
        saved = undefined
        self.viewer.layers.save = <bound method LayerList.save of [<Image layer 'Image:0' at 0x1564eb14c70>, <Image layer '0 :: Image:0 :: Channel:0:0' at 0x1564f32d610>, <Image layer '0 :: Image:0 :: Channel:0:1' at 0x1563b50f640>, <Image layer '0 :: Image:0 :: Channel:0:2' at 0x1563b55a760>, <Image layer '0 :: Image:0 :: Channel:0:3' at 0x1563b5ef0d0>, <Image layer '0. 0 :: Image:0 :: Channel:0:0: ch[0] actb' at 0x1563b4ece20>, <Image layer '1. Intensity Normalization' at 0x1563cb38d90>, <Image layer '2. Edge Preserving Smoothing' at 0x15652c295e0>, <Image layer '3. Filament Filter 3D' at 0x156597d3c70>, <Image layer '4. Filament Filter 3D' at 0x15653cd6bb0>, <Image layer '5. Merge Segmentation' at 0x15653d8abe0>, <Image layer '6. Size Filter' at 0x1563cb38a00>]>
        filename = 'C:/Users/benjamin.morris/Downloads/test_09_22.bmp'
        selected = True
    533                 error_messages = "\n".join(
    534                     [str(x.message.args[0]) for x in wa]

~\Anaconda3\envs\napari_env\lib\site-packages\napari\components\layerlist.py in save(self=[<Image layer 'Image:0' at 0x1564eb14c70>, <Imag... <Image layer '6. Size Filter' at 0x1563cb38a00>], path='C:/Users/benjamin.morris/Downloads/test_09_22.bmp', selected=True, plugin=None)
    322             return []
    323
--> 324         return save_layers(path, layers, plugin=plugin)
        save_layers = <function save_layers at 0x000001564EB9D0D0>
        path = 'C:/Users/benjamin.morris/Downloads/test_09_22.bmp'
        layers = [<Image layer '6. Size Filter' at 0x1563cb38a00>]
        plugin = None
    325
    326     def _selection_context(self) -> dict:

~\Anaconda3\envs\napari_env\lib\site-packages\napari\plugins\io.py in save_layers(path='C:/Users/benjamin.morris/Downloads/test_09_22.bmp', layers=[<Image layer '6. Size Filter'>], plugin=None)
    207         )
    208     elif len(layers) == 1:
--> 209         _written = _write_single_layer_with_plugins(
        _written = undefined
        global _write_single_layer_with_plugins = <function _write_single_layer_with_plugins at 0x000001564EB9D700>
        path = 'C:/Users/benjamin.morris/Downloads/test_09_22.bmp'
        layers = [<Image layer '6. Size Filter' at 0x1563cb38a00>]
        global plugin_name = undefined
        plugin = None
    210             path, layers[0], plugin_name=plugin
    211         )

~\Anaconda3\envs\napari_env\lib\site-packages\napari\plugins\io.py in _write_single_layer_with_plugins(path='C:/Users/benjamin.morris/Downloads/test_09_22.bmp', layer=<Image layer '6. Size Filter'>, plugin_name=None)
    405
    406     # Call the hook_caller
--> 407     return hook_caller(
        hook_caller = <HookCaller napari_write_image>
        global _plugin = undefined
        plugin_name = None
        path = 'C:/Users/benjamin.morris/Downloads/test_09_22.bmp'
        global abspath_or_url = <function abspath_or_url at 0x0000015633E741F0>
        global data = undefined
        layer.data = <class 'numpy.ndarray'> (38, 600, 600) bool
        global meta = undefined
        layer._get_state = <bound method Image._get_state of <Image layer '6. Size Filter' at 0x1563cb38a00>>
    408         _plugin=plugin_name,
    409         path=abspath_or_url(path),

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\hooks.py in __call__(self=<HookCaller napari_write_image>, _plugin=None, _skip_impls=[], *args=(), **kwargs={'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}, 'path': r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp'})
    518             return self._call_plugin(_plugin, **kwargs)
    519
--> 520         result = self.call_with_result_obj(_skip_impls=_skip_impls, **kwargs)
        result = undefined
        self.call_with_result_obj = <bound method HookCaller.call_with_result_obj of <HookCaller napari_write_image>>
        _skip_impls = []
        kwargs = {'path': 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp', 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'name': '6. Size Filter', 'metadata': {}, 'scale': [1.0, 1.0, 1.0], 'translate': [0.0, 0.0, 0.0], 'rotate': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'shear': [0.0, 0.0, 0.0], 'opacity': 1.0, 'blending': 'translucent', 'visible': 2, 'experimental_clipping_planes': [], 'rgb': False, 'multiscale': False, 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'interpolation': 'nearest', 'rendering': 'mip', 'experimental_slicing_plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'enabled': False, 'thickness': 1.0}, 'iso_threshold': 0.5, 'attenuation': 0.05, 'gamma': 1, 'data': <class 'numpy.ndarray'> (38, 600, 600) bool}}
    521         return result.result
    522

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\hooks.py in call_with_result_obj(self=<HookCaller napari_write_image>, _skip_impls=[], **kwargs={'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}, 'path': r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp'})
    459         self._check_call_kwargs(kwargs)
    460         impls = [imp for imp in self.get_hookimpls() if imp not in _skip_impls]
--> 461         return self._hookexec(self, impls, kwargs)
        self._hookexec = <bound method PluginManager._hookexec of <napari.plugins._plugin_manager.NapariPluginManager object at 0x00000156332186A0>>
        self = <HookCaller napari_write_image>
        impls = [<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>]
        kwargs = {'path': 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp', 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'name': '6. Size Filter', 'metadata': {}, 'scale': [1.0, 1.0, 1.0], 'translate': [0.0, 0.0, 0.0], 'rotate': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'shear': [0.0, 0.0, 0.0], 'opacity': 1.0, 'blending': 'translucent', 'visible': 2, 'experimental_clipping_planes': [], 'rgb': False, 'multiscale': False, 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'interpolation': 'nearest', 'rendering': 'mip', 'experimental_slicing_plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'enabled': False, 'thickness': 1.0}, 'iso_threshold': 0.5, 'attenuation': 0.05, 'gamma': 1, 'data': <class 'numpy.ndarray'> (38, 600, 600) bool}}
    462
    463     def __call__(

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\manager.py in _hookexec(self=<napari.plugins._plugin_manager.NapariPluginManager object>, caller=<HookCaller napari_write_image>, methods=[<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>], kwargs={'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}, 'path': r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp'})
    160             The result object produced by the multicall loop.
    161         """
--> 162         return self._inner_hookexec(caller, methods, kwargs)
        self._inner_hookexec = <function PluginManager.__init__.<locals>.<lambda> at 0x000001563320DCA0>
        caller = <HookCaller napari_write_image>
        methods = [<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>]
        kwargs = {'path': 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp', 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'name': '6. Size Filter', 'metadata': {}, 'scale': [1.0, 1.0, 1.0], 'translate': [0.0, 0.0, 0.0], 'rotate': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'shear': [0.0, 0.0, 0.0], 'opacity': 1.0, 'blending': 'translucent', 'visible': 2, 'experimental_clipping_planes': [], 'rgb': False, 'multiscale': False, 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'interpolation': 'nearest', 'rendering': 'mip', 'experimental_slicing_plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'enabled': False, 'thickness': 1.0}, 'iso_threshold': 0.5, 'attenuation': 0.05, 'gamma': 1, 'data': <class 'numpy.ndarray'> (38, 600, 600) bool}}
    163
    164     def iter_available(

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\manager.py in <lambda>(c=<HookCaller napari_write_image>, m=[<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>], k={'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}, 'path': r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp'})
    121         self.trace = _tracing.TagTracer().get("pluginmanage")
    122         self.hook = _HookRelay(self)
--> 123         self._inner_hookexec: HookExecFunc = lambda c, m, k: c.multicall(
        global self._inner_hookexec = undefined
        global HookExecFunc = typing.Callable[[ForwardRef('HookCaller'), typing.List[napari_plugin_engine.implementation.HookImplementation], dict], napari_plugin_engine.callers.HookResult]
        c = <HookCaller napari_write_image>
        m = [<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>]
        k = {'path': 'C:\\Users\\benjamin.morris\\Downloads\\test_09_22.bmp', 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'name': '6. Size Filter', 'metadata': {}, 'scale': [1.0, 1.0, 1.0], 'translate': [0.0, 0.0, 0.0], 'rotate': [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'shear': [0.0, 0.0, 0.0], 'opacity': 1.0, 'blending': 'translucent', 'visible': 2, 'experimental_clipping_planes': [], 'rgb': False, 'multiscale': False, 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'interpolation': 'nearest', 'rendering': 'mip', 'experimental_slicing_plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'enabled': False, 'thickness': 1.0}, 'iso_threshold': 0.5, 'attenuation': 0.05, 'gamma': 1, 'data': <class 'numpy.ndarray'> (38, 600, 600) bool}}
        c.multicall = <function _multicall at 0x0000015639A92160>
        global firstresult = undefined
        c.is_firstresult = True
    124             m, k, firstresult=c.is_firstresult
    125         )

~\Anaconda3\envs\napari_env\lib\site-packages\napari_plugin_engine\callers.py in _multicall(hook_impls=[<HookImplementation plugin='svg' spec='napari_write_image' trylast>, <HookImplementation plugin='builtins' spec='napari_write_image' trylast>], caller_kwargs={'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'meta': {'attenuation': 0.05, 'blending': 'translucent', 'colormap': 'gray', 'contrast_limits': [0.0, 1.0], 'data': <class 'numpy.ndarray'> (38, 600, 600) bool, 'experimental_clipping_planes': [], 'experimental_slicing_plane': {'enabled': False, 'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'gamma': 1, 'interpolation': 'nearest', 'iso_threshold': 0.5, ...}, 'path': r'C:\Users\benjamin.morris\Downloads\test_09_22.bmp'}, firstresult=True)
    209     finally:
    210         if firstresult and errors:
--> 211             raise errors[-1]
        errors = [PluginCallError("Error in plugin 'builtins', hook 'napari_write_image': Image is not numeric, but ndarray.")]
    212
    213         outcome = HookResult(

PluginCallError: Error in plugin 'builtins', hook 'napari_write_image': Image is not numeric, but ndarray.
* If you can't find the error message, go to Plugins > Plugin Errors > napari-allencell-segmenter
* Most of the time, the most helpful information is at the very bottom of the error output

Expected Behavior

What did you expect to happen instead? I expected to be able to view the segmented image

Reproduction

Please list the exact steps we can take to reproduce this bug.

  1. Load 3D image
  2. Run segmenter workflow
  3. select final layer
  4. File -> Save Selected Layer

Environment

Operating system (ex. MacOS Big Sur): Windows 10 Python version (ex. 3.8): 3.9 How did you install the napari viewer (as a bundled app or through command line with pip)?: pip install, napari version