Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attempts to create a writer #69

Merged
merged 26 commits into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
447ffd6
attempts to create a writer
glyg Dec 3, 2020
ad261bc
attempts to create a writer
glyg Dec 3, 2020
2d83edd
adds the files
glyg Dec 4, 2020
07e6cb8
Merge branch 'writer' of github.com:glyg/ome-zarr-py into writer
glyg Dec 4, 2020
3424efa
Merge 'origin/master' into HEAD
joshmoore Dec 6, 2020
552ea9d
Fix issues from 'pre-commit run -a'
joshmoore Dec 6, 2020
212db6a
passes the writer test
glyg Dec 7, 2020
c970c82
WIP add write mechanisms to LocalZarrLocaltion
glyg Dec 7, 2020
ffa2bda
fixes obvious lint pbs
glyg Dec 7, 2020
371404e
Sorry for the nosie I'll get used to it
glyg Dec 7, 2020
2a12507
Relaxing typing constrains, mypy passes
glyg Dec 7, 2020
7b9599a
adds channels metadata, read from omero spec if nothing else
glyg Dec 11, 2020
d55edae
Slight refactoring of ome_zarr.writer
joshmoore Jan 11, 2021
7c86ddf
Merge pull request #1 from joshmoore/writer
glyg Jan 12, 2021
fce7c96
partly fixes writer test
glyg Jan 12, 2021
fe5d61c
removes unnecessary if block in Reader
glyg Jan 12, 2021
f6123c2
pre-commit fixes
joshmoore Jan 26, 2021
9731606
Try bumping to napari 0.4.4
joshmoore Feb 4, 2021
d5f1614
Register show-viewer in conftest as workaround
joshmoore Feb 4, 2021
6c91ed0
Merge branch 'master' into writer
joshmoore Feb 4, 2021
64bafb1
Add downsampling
joshmoore Mar 22, 2021
b832df5
Use dataset variable
joshmoore Mar 22, 2021
e51b1be
Revert debugging raise
joshmoore Mar 23, 2021
d35cc5e
Remove unnecessary omero metadata
joshmoore Mar 23, 2021
0d0ebfd
write_image: accept array or list
joshmoore Mar 23, 2021
f22c564
write_image: revert array or list
joshmoore Mar 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#name: z
name: z
channels:
- defaults
- ome
Expand Down
76 changes: 76 additions & 0 deletions ome_zarr/writer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Image writer utility

"""
import logging

from typing import Any, Dict, Iterator, List, Optional, Type, Union, Tuple, cast
import zarr

import numpy as np

from .io import parse_url
from .reader import Node


LOGGER = logging.getLogger("ome_zarr.writer")

def write_image(
path: str,
image: np.ndarray,
name: str = "0",
group: str = None,
chunks: Union[Tuple[int], int] = None,
byte_order: Union[str, List[str]] = "tczyx",
**metadata):
"""Writes an image to the zarr store according to ome-zarr specification

Parameters
----------
path: str,
a path to the zarr store location
image: np.ndarray
the image to save
group: str, optional
the group within the zarr store to store the data in
chunks: int or tuple of ints,
size of the saved chunks to store the image
byte_order: str or list of str, default "tczyx"
combination of the letters defining the order
in which the dimensions are saved
"""
zarr_location = parse_url(path)

## I assume this should be dealt with in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think what's needed first is a way to pass mode through to the parse_url and *Location classes.

## the ZarrLocation classes
store = zarr.DirectoryStore(path)
image = np.asarray(image)

if image.ndim > 5:
# Maybe we can split the more than 5D images in subroups?
raise ValueError("Only images of 5D or less are supported")

shape_5d = (*(1,)*(5 - image.ndim), *image.shape)
image = image.reshape(shape_5d)
omero = metadata.get("omero", {})

# Update the size entry anyway
omero["size"]= {
"t": image.shape[0],
"c": image.shape[1],
"z": image.shape[2],
"height": image.shape[3],
"width": image.shape[4],
}

metadata["omero"] = omero
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is currently missing the multiscales metadata. I'd propose moving write_multiscales from ome_zarr.data to your writer module.


root = zarr.group(store)
if group is not None:
grp = root.create_group(group)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require_group should do what you want.

else:
grp = root

grp.create_dataset(name, data=image, chunks=chunks)

for entry, value in metadata.items():
grp.attrs[entry] = value
23 changes: 23 additions & 0 deletions tests/test_writer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
import numpy as np

from ome_zarr.writer import write_image
from ome_zarr.io import parse_url
from ome_zarr.reader import Reader


class TestWriter:
@pytest.fixture(autouse=True)
def initdir(self, tmpdir):
self.path = tmpdir.mkdir("data")

def create_data(self, shape, dtype, mean_val=10):
rng = np.random.default_rng(0)
return rng.poisson(mean_val, size=shape).astype(dtype)

def test_writer(self):

data = self.create_data((1, 2, 1, 256, 256), np.uint8)
write_image(self.path, data)
reader = Reader(self.path)
assert len(list(reader())) == 3