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

Support export of Fileset:ID #123

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
6 changes: 5 additions & 1 deletion src/omero_zarr/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from omero.cli import CLI, BaseControl, Parser, ProxyStringType
from omero.gateway import BlitzGateway, BlitzObjectWrapper
from omero.model import ImageI, PlateI
from omero.model import FilesetI, ImageI, PlateI
from zarr.hierarchy import open_group
from zarr.storage import FSStore

Expand All @@ -20,6 +20,7 @@
from .raw_pixels import (
add_omero_metadata,
add_toplevel_metadata,
fileset_to_zarr,
image_to_zarr,
plate_to_zarr,
)
Expand Down Expand Up @@ -323,6 +324,9 @@ def export(self, args: argparse.Namespace) -> None:
elif isinstance(args.object, PlateI):
plate = self._lookup(self.gateway, "Plate", args.object.id)
plate_to_zarr(plate, args)
elif isinstance(args.object, FilesetI):
fileset = self._lookup(self.gateway, "Fileset", args.object.id)
fileset_to_zarr(fileset, args)

def _lookup(
self, gateway: BlitzGateway, otype: str, oid: int
Expand Down
68 changes: 64 additions & 4 deletions src/omero_zarr/raw_pixels.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,74 @@

from . import __version__
from . import ngff_version as VERSION
from .util import marshal_axes, marshal_transformations, open_store, print_status
from .util import (
get_minimum_image_ome_xml,
marshal_axes,
marshal_transformations,
open_store,
print_status,
)


def image_to_zarr(image: omero.gateway.ImageWrapper, args: argparse.Namespace) -> None:
def fileset_to_zarr(
fileset: omero.gateway.FilesetWrapper, args: argparse.Namespace
) -> None:
"""Exports a FileSet according to bioformats2raw.layout"""
images = list(fileset.copyImages())
images_to_zarr(images, args)


def images_to_zarr(
images: List[omero.gateway.ImageWrapper],
args: argparse.Namespace,
target_dir: str = None,
) -> None:
"""Exports images in bioformats2raw.layout, each under path '0', '1' etc."""
if target_dir is None:
target_dir = args.output if args.output else "zarr_export"
dir_index = 1
dir_name = target_dir
while os.path.exists(dir_name):
dir_name = f"{target_dir}({dir_index})"
dir_index += 1
os.mkdir(dir_name)

# write bioformats2raw.layout
zattrs = os.path.join(dir_name, ".zattrs")
with open(zattrs, "w") as zfile:
zfile.write(
"""{
"bioformats2raw.layout" : 3
}"""
)
# write OME/METADATA.ome.xml
ome_dir = os.path.join(dir_name, "OME")
xml_path = os.path.join(ome_dir, "METADATA.ome.xml")
os.mkdir(ome_dir)
images = list(images) # in case it's a generator
ome_xml = get_minimum_image_ome_xml(images)
with open(xml_path, "w") as xml_file:
xml_file.write(ome_xml)

# write images
for index, image in enumerate(images):
target = os.path.join(dir_name, str(index))
image_to_zarr(image, args, target)


def image_to_zarr(
image: omero.gateway.ImageWrapper, args: argparse.Namespace, target: str = None
) -> None:
"""
Export an image to zarr
@param target: Optional path/to/image.zarr. Default is args.output/ID.zarr
"""
target_dir = args.output
cache_dir = target_dir if args.cache_numpy else None

name = os.path.join(target_dir, "%s.zarr" % image.id)
if target is None:
name = os.path.join(target_dir, "%s.zarr" % image.id)
else:
name = target
print(f"Exporting to {name} ({VERSION})")
store = open_store(name)
root = open_group(store)
Expand Down
62 changes: 62 additions & 0 deletions src/omero_zarr/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
from typing import Dict, List

from omero.gateway import ImageWrapper
from omero.model.enums import (
PixelsTypedouble,
PixelsTypefloat,
PixelsTypeint8,
PixelsTypeint16,
PixelsTypeint32,
PixelsTypeuint8,
PixelsTypeuint16,
PixelsTypeuint32,
)
from zarr.storage import FSStore


Expand Down Expand Up @@ -112,3 +122,55 @@ def marshal_transformations(
zooms["y"] = zooms["y"] * multiscales_zoom

return transformations


def get_minimum_image_ome_xml(images: List[ImageWrapper]) -> str:
Copy link
Member

Choose a reason for hiding this comment

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

Might be worth considering ome_model or ome_types for this? cc: @seb

Copy link
Member Author

Choose a reason for hiding this comment

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

Using ome-types in 553b35f

"""Generates minimal OME.xml for"""

omero_pix_types = {
PixelsTypeint8: "int8",
PixelsTypeuint8: "uint8",
PixelsTypeint16: "int16",
PixelsTypeuint16: "uint16",
PixelsTypeint32: "int32",
PixelsTypeuint32: "uint32",
PixelsTypefloat: "float32",
PixelsTypedouble: "double",
}

images_xml = []
for image in images:
image_id = image.id
name = image.name
pixels_id = image.getPixelsId()
pixels_type = image.getPrimaryPixels().getPixelsType().getValue()
p_type = omero_pix_types[pixels_type]
size_x = image.getSizeX()
size_y = image.getSizeY()
size_z = image.getSizeZ()
size_c = image.getSizeC()
size_t = image.getSizeT()
images_xml.append(
f"""<Image ID="Image:{image_id}" Name="{name}">
<Pixels
ID="Pixels:{pixels_id}"
DimensionOrder="XYZCT"
Type="{p_type}"
SizeX="{size_x}"
SizeY="{size_y}"
SizeZ="{size_z}"
SizeC="{size_c}"
SizeT="{size_t}">
<MetadataOnly/>
</Pixels>
</Image>"""
)

img_xml = "\n".join(images_xml)
return f"""<?xml version="1.0" encoding="UTF-8"?>
<OME xmlns="http://www.openmicroscopy.org/Schemas/OME/2016-06"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2016-06
http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd">
{img_xml}
</OME>"""