ome/napari-ome-zarr

Unable to load webknossos hosted zarr datasets

Opened this issue · 14 comments

When testing to load ome/zarr data from webknossos, I could not see any data, everything is shown black. This might be due to 1) Fortran (column-major) order data, and/or 2) the dimension order cxyz.

Steps to reproduce:

  1. I adapted filename_patterns in napari.yaml of this plugin to be able to open the webknossos zarr-streamed datasets (e.g. adding https://*.webknossos.org/data/zarr/*)
  2. Opening any of these datasets does not show any data:
  • python3 -m napari "https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color"
  • python3 -m napari "https://data-humerus.webknossos.org/data/zarr/scalable_minds/skin/color"

Please note that the datasets for the different resolutions can be loaded via zarr-python, e.g. using

zarr.open_array("https://data-humerus.webknossos.org/data/zarr/scalable_minds/skin/color/1")

Additional info:

$ cat /etc/debian_version 
10.12
$ python --version
Python 3.8.11
$ napari --version
napari version 0.4.16
$ pip3 list | grep napari-ome-zarr
napari-ome-zarr                   0.5.2

Looking at https://ome.github.io/ome-ngff-validator/?source=https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color I can see that the /1/.zarray has:
"dimension_seperator": "." whereas for OME-NGFF versions 0.2 and above, a / is expected as the dimension separator.

And running napari as you did...

$ napari --plugin napari-ome-zarr https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color -vvv
...
22:18:03 DEBUG Created nested FSStore(https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color/labels, r, {'dimension_separator': '/', 'normalize_keys': False})
...
22:15:46 DEBUG https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color/4-4-2/0/8/25/15

I noticed that opening in vizarr, https://hms-dbmi.github.io/vizarr/?source=https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color I see a lot of 404s for URLs like:
https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color/4-4-2/0.0.1.0, so it's being less picky about the separator, but still not finding chunks.

I also just learned last week that . is not allowed as dimension separator in OME-Zarr. To me that is a bit weird, because the underlying Zarr spec supports both separators and, therefore, many OME-Zarr implementations also do. Anyways, that is probably something we should propose for version 0.5 ome/ngff#135.

Btw, the dataset opens well in Neuroglancer.

I noticed that opening in vizarr, https://hms-dbmi.github.io/vizarr/?source=https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color I see a lot of 404s for URLs like:
https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color/4-4-2/0.0.1.0, so it's being less picky about the separator, but still not finding chunks.

This is due to an offset of the data, which just starts at x, y, z = 2679, 4224, 1719, the first chunks are all empty.

Other than ome/ngff#135 are there any actions here?

I was going to start looking at a fix here, but I can't even get as far as I did above #66 (comment)

(napari) Williams-MacBook-Pro:napari-ome-zarr wmoore$ napari --plugin napari-ome-zarr https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color
Traceback (most recent call last):
  File "/Users/wmoore/opt/anaconda3/envs/napari/bin/napari", line 8, in <module>
    sys.exit(main())
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/__main__.py", line 446, in main
    _run()
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/__main__.py", line 311, in _run
    viewer._window._qt_viewer._qt_open(
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/_qt/qt_viewer.py", line 754, in _qt_open
    self.viewer.open(
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/components/viewer_model.py", line 931, in open
    self._add_layers_with_plugins(
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/components/viewer_model.py", line 1134, in _add_layers_with_plugins
    layer_data, hookimpl = read_data_with_plugins(
  File "/Users/wmoore/opt/anaconda3/envs/napari/lib/python3.9/site-packages/napari/plugins/io.py", line 86, in read_data_with_plugins
    raise ValueError(
ValueError: There is no registered plugin named 'napari-ome-zarr'.
Names of plugins offering readers are: {'builtins', 'ome-types'}

I assume that this in napari.yml means that the plugin is not used to open the file (even though I'm specifying it on the command line):

      filename_patterns:
        - "*.zarr"
        - "*.zarr*"

since the URL contains /zarr/ but not .zarr.

cc: @DragaDoncila in case there's any way to let users override the patterns.

I know there is a discussion in zarr v3 to make .zarr suffixes mandatory, but is this already a requirement in the OME-NGFF spec?

Not currently an NGFF requirement, no. In this case it's a napari mechanism for filtering inputs to plugins.

@jstriebel with the fix at ome/ome-zarr-py#235 and the filename_pattern change to allow "*zarr*", I can open in napari with:

$ napari --plugin napari-ome-zarr https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color -vvv

I see chunks loaded using . separator, but I can't see anything in napari (playing with rendering settings and trying different slider positions).

Screenshot 2022-11-11 at 13 51 35

And testing with vizarr as above gives 404s for ALL the chunk URLs. e.g. https://data-humerus.webknossos.org/data/zarr/scalable_minds/l4_sample_dev/color/4-4-2/0.0.18.23.

Any ideas?

That dataset has an implicit offset. Can check a location starting from x, y, z = 2679, 4224, 1719?

Ah, thanks - I found it eventually!

Screenshot 2022-11-11 at 14 30 15

cc: @DragaDoncila in case there's any way to let users override the patterns.

Iirc through the command line you could assign a preference for a filename pattern to a plugin, even if that reader doesn't declare that filename pattern in its list.

from napari.settings import get_settings
get_settings().plugins.extension2reader['*blah*'] = 'not-a-blah-reader' 

I haven't fully explored that behaviour to see if we would actually try the plugin, but I think we might? I'm travelling atm so can't investigate.

We also need to improve that error message about no registered plugin, since it's very misleading.

Thanks, @DragaDoncila. (Safe travels). Perhaps printing ... all patterns(?), similar patterns(?!) would help users. "Did you mean /zarr/"?

@joshmoore do you mean on the napari side when a user tries to read a file and it kinda matches a filename pattern but not quite? I'm not sure what heuristic we could use to determine this approximate match but there are options out there. It's something we could consider, but would just want to be very careful about the information being actually useful. If there's a slight difference in file extension but a huge difference in the actual file format, we wouldn't want a user thinking they can just tweak the extension and the plugin would work.