Comments (6)
Wow, cool!
How do I make it display in color mode, I guess that has to do with the "omero" key, right? What's the best way to pass that?
Omero key shouldn't be necessary. I believe if you set channel_axis = 0
the colors should work.
Another minor issue is that, if I zoom in too much it becomes blank, can I limit the zoom level?
Hmm I'm not sure about this. I have a PR I'm about to merge upgrading Viv (#126), and I wonder if that would vix the issue. In the run_vizarr
function, you can set the url to the netlify deploy preview link and see if the upgrade fixes it.
BTW, would you consider having such feature in napari_lazy_openslide so it can work out of the box?
Yeah, definitely. I wonder if this functionality would be best implemented as a method on the OpenSideStore
that returns another class wrapping the store (instead of inheriting the store). E.g.
from napari_lazy_openslide import OpenSlideStore
OpenSlideStore('./data.svs').as_ngff() # returns store transformer
EDIT: Also, @oeway, an as_ngff()
method could add the additional axes
metadata to the mulitscales
metadata so that channel_axis
does not need to be provided.
from vizarr.
Hi @oeway ! We currently don't support interleaved RGB/A images in the vizarr client. The last two dimensions of an array must be YX. However, we have added support for this in Viv, and I can look into adding that functionality client-side in vizarr.
I'm sorry, but as a work around on the python side, you could wrap the OpenslideStore
in another zarr store that performs the translation of (y, x, c)
to (c, y, x)
. You need to proxy requests for .zarray
metadata to make the following changes:
shape
:(y, x, 4) -> (4, y, x)
chunks
(tilesize, tilesize, 4) -> (1, tilesize, tilesize)
.
Any zarr client will now request keys in the form "level/c.y.x" from the store. It gets tricky because the chunk shapes are different but in theory (I haven't tested this) it could look like:
from napari_lazy_openslide import OpenSlideStore
from zarr.util import json_dumps, json_loads
import numpy as np
def _parse_chunk_path(path: str):
"""Returns x,y chunk coords and pyramid level from string key"""
level, ckey = path.split("/")
c, y, x = map(int, ckey.split("."))
return c, x, y, int(level)
class Wrapper(OpenSlideStore):
def __getitem__(self, key):
if key in self._store: # metadata store for OpenSlideStore
# key is for metadata
res = self._store[key]
if key.endswith('.zarray'):
meta = json_loads(res)
meta.shape = [meta.shape[2], meta.shape[0], meta.shape[1]]
meta.chunks = [1, meta.chunks[0], meta.chunks[1]]
return json_dumps(meta)
else:
# zgroup
return res
cidx, y, x, level = _parse_chunk_path(key)
buf = store[f"{level}/{y}.{x}.0"] # could cache this result
arr = np.frombuffer(buf, dtype='uint8').reshape(self.tilesize, self.tilesize, -1)
data = arr[:, :, cidx] # cou
return data.tobytes()
It gets a little tricky because the chunk shape of the original array is (tilesize, tilesize, 4)
and the zarr array would need to map to (1, tilesize, tilesize)
.
from vizarr.
Hi @manzt Thanks for the detailed explanation!
I started to try the Wrapper code you wrote above, and here is a version with some fix, but still not working:
from napari_lazy_openslide import OpenSlideStore
from zarr.util import json_dumps, json_loads
import numpy as np
def _parse_chunk_path(path: str):
"""Returns x,y chunk coords and pyramid level from string key"""
level, ckey = path.split("/")
c, y, x = map(int, ckey.split("."))
return c, x, y, int(level)
class Wrapper(OpenSlideStore):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __getitem__(self, key):
if key in self._store: # metadata store for OpenSlideStore
# key is for metadata
res = self._store[key]
print(self._store.keys())
if key.endswith('.zarray'):
meta = json_loads(res)
meta["shape"] = [meta["shape"][2], meta["shape"][0], meta["shape"][1]]
meta["chunks"] = [1, meta["chunks"][0], meta["chunks"][1]]
return json_dumps(meta)
elif key.endswith('.zgroup') or key.endswith('.zattrs'):
# zgroup
return res
cidx, y, x, level = _parse_chunk_path(key)
buf = self._store[f"{level}/{y}.{x}.0"] # <-------------------------Is this correct?
arr = np.frombuffer(buf, dtype='uint8').reshape(self.tilesize, self.tilesize, -1)
data = arr[:, :, cidx] # cou
return data.tobytes()
You wrote store[...]
in your previous code, I guess you mean self._store
?
And the issue now is that the line buf = self._store[f"{level}/{y}.{x}.0"]
generates error, for example: KeyError: '7/0.0.0'
. And here are the keys in self._store
: dict_keys(['.zgroup', '.zattrs', '0/.zarray', '1/.zarray', '2/.zarray', '3/.zarray', '4/.zarray', '5/.zarray', '6/.zarray', '7/.zarray', '8/.zarray', '9/.zarray', '10/.zarray']).
How should I access the array data with f"{level}/{y}.{x}.0"
in this case?
from vizarr.
You wrote
store[...]
in your previous code, I guess you meanself._store
?
Oh that's my mistake. The code snippet I shared I just typed here as an idea and didn't test at all.
self._store
is just a dict containing the zarr metadata. You should call the parent class (OpenSlideStore
) __getitem__
method.
def __getitem__(key):
# ....
buf = super().__getitem__(f"{level}/{y}.{x}.0")
from vizarr.
@manzt Thank you! It's working now! Awesome!
For others who might be interested in this, here is the working version for me:
import numpy as np
from napari_lazy_openslide import OpenSlideStore
from zarr.util import json_dumps, json_loads
def _parse_chunk_path(path: str):
"""Returns x,y chunk coords and pyramid level from string key"""
level, ckey = path.split("/")
c, y, x = map(int, ckey.split("."))
return c, x, y, int(level)
class OpenSlideStoreWrapper(OpenSlideStore):
def __getitem__(self, key):
if key in self._store: # metadata store for OpenSlideStore
# key is for metadata
res = self._store[key]
if key.endswith('.zarray'):
meta = json_loads(res)
meta["shape"] = [meta["shape"][2], meta["shape"][0], meta["shape"][1]]
meta["chunks"] = [1, meta["chunks"][0], meta["chunks"][1]]
return json_dumps(meta)
elif key.endswith('.zgroup') or key.endswith('.zattrs'):
# zgroup
return res
cidx, y, x, level = _parse_chunk_path(key)
buf = super().__getitem__(f"{level}/{x}.{y}.0") # could cache this result
arr = np.frombuffer(buf, dtype='uint8').reshape(self._tilesize, self._tilesize, -1)
data = arr[:, :, cidx] # cou
return data.tobytes()
How do I make it display in color mode, I guess that has to do with the "omero"
key, right? What's the best way to pass that? Another minor issue is that, if I zoom in too much it becomes blank, can I limit the zoom level?
BTW, would you consider having such feature in napari_lazy_openslide so it can work out of the box?
from vizarr.
All works now, see a gif below:
The .as_ngff()
method sounds awesome! Looking forward to it!
from vizarr.
Related Issues (20)
- Visualzation of ROIs embedded in ome.zarr? HOT 7
- Vizarr demo for Jupyterlab and JupyterLite in the browser HOT 1
- Example image link is broken HOT 3
- 3D visualization of volumetric data (e.g. segmentations) HOT 3
- Allow setting z/t plane
- Issue with tissue image display HOT 4
- Channel range widget input HOT 1
- Support bioformats2raw layout HOT 11
- Counter-intuitive layer ordering
- colab notebook not working with zarr HOT 2
- Loading issue for OME-NGFF 0.4 dataset with large number of channels HOT 2
- Allow to set position via URL HOT 1
- Use naming convention for event listener names
- Display of HCS Plate not fully working HOT 7
- Question about vizarr's mandelbrot demo HOT 1
- Image origin in Vizarr HOT 1
- How to load local zarr files through imjoy_plugin.py HOT 1
- Explore a custom store for tiled
- OME-NGFF v0.5 (coordinateSystems) support
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vizarr.