Skip to content

Commit b8ae691

Browse files
committed
Add extinfo command
1 parent 11d3587 commit b8ae691

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/omero_zarr/cli.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
image_to_zarr,
4242
plate_to_zarr,
4343
)
44+
from .extinfo import (
45+
get_images,
46+
set_external_info,
47+
get_path,
48+
)
4449

4550
HELP = """Export data in zarr format.
4651
@@ -108,6 +113,7 @@
108113

109114
POLYGONS_HELP = """Export ROI Polygons on the Image or Plate in zarr format"""
110115

116+
EXTINFO_HELP = """Set the external info path for an ome.zarr image."""
111117

112118
def gateway_required(func: Callable) -> Callable:
113119
"""
@@ -284,6 +290,11 @@ def _configure(self, parser: Parser) -> None:
284290
help="The Image to export.",
285291
)
286292

293+
exinfo = parser.add(sub, self.extinfo, EXTINFO_HELP)
294+
exinfo.add_argument("object",
295+
type=ProxyStringType(),
296+
help="Object in Class:ID format")
297+
287298
for subcommand in (polygons, masks, export):
288299
subcommand.add_argument(
289300
"--output", type=str, default="", help="The output directory"
@@ -335,6 +346,21 @@ def export(self, args: argparse.Namespace) -> None:
335346
plate = self._lookup(self.gateway, "Plate", args.object.id)
336347
plate_to_zarr(plate, args)
337348

349+
@gateway_required
350+
def extinfo(self, args: argparse.Namespace) -> None:
351+
for img in get_images(self.gateway, args.object):
352+
path = get_path(self.gateway, img.getId())
353+
img = img._obj
354+
if path.endswith("OME/METADATA.ome.xml"):
355+
path = path.replace("OME/METADATA.ome.xml", "0")
356+
path = f"/{path}"
357+
img = set_external_info(img, path)
358+
img = self.gateway.getUpdateService().saveAndReturnObject(img)
359+
self.ctx.out(f"Set path to '{path}' for image {img.id._val}")
360+
else:
361+
self.ctx.out(f"'{path}' for image {img.id._val} doesn't seem to be an ome.zarr, skipping.")
362+
363+
338364
def _lookup(
339365
self, gateway: BlitzGateway, otype: str, oid: int
340366
) -> BlitzObjectWrapper:

src/omero_zarr/extinfo.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from omero.gateway import BlitzGateway
2+
from omero.gateway import BlitzObjectWrapper
3+
from omero.model import ExternalInfoI, ImageI
4+
from omero.rtypes import rstring, rlong
5+
from omero_sys_ParametersI import ParametersI
6+
from omero.model import Image
7+
from omero.model import Plate
8+
from omero.model import Screen
9+
from omero.model import Dataset
10+
from omero.model import Project
11+
12+
13+
def get_path(conn: BlitzGateway, image_id: int) -> str:
14+
params = ParametersI()
15+
params.addId(image_id)
16+
query = """
17+
select fs from Fileset as fs
18+
join fetch fs.images as image
19+
left outer join fetch fs.usedFiles as usedFile
20+
join fetch usedFile.originalFile as f
21+
join fetch f.hasher where image.id = :id
22+
"""
23+
fs = conn.getQueryService().findByQuery(query, params)
24+
res = fs._getUsedFiles()[0]._clientPath._val
25+
return res
26+
27+
28+
def set_external_info(img: ImageI, path: str) -> ImageI:
29+
info = ExternalInfoI()
30+
info.entityType = rstring("com.glencoesoftware.ngff:multiscales")
31+
info.entityId = rlong(3)
32+
info.lsid = rstring(path)
33+
img.details.externalInfo = info
34+
return img
35+
36+
37+
def _lookup(conn: BlitzGateway, type: str, oid: int) -> BlitzObjectWrapper:
38+
conn.SERVICE_OPTS.setOmeroGroup("-1")
39+
obj = conn.getObject(type, oid)
40+
if not obj:
41+
raise ValueError(f"No such {type}: {oid}")
42+
return obj
43+
44+
45+
def get_images(conn: BlitzGateway, object):
46+
if isinstance(object, list):
47+
for x in object:
48+
yield from get_images(conn, x)
49+
elif isinstance(object, Screen):
50+
scr = _lookup(conn, "Screen", object.id)
51+
for plate in scr.listChildren():
52+
yield from get_images(conn, plate._obj)
53+
elif isinstance(object, Plate):
54+
plt = _lookup(conn, "Plate", object.id)
55+
for well in plt.listChildren():
56+
for idx in range(0, well.countWellSample()):
57+
img = well.getImage(idx)
58+
yield img
59+
elif isinstance(object, Project):
60+
prj = _lookup(conn, "Project", object.id)
61+
for ds in prj.listChildren():
62+
yield from get_images(conn, ds._obj)
63+
elif isinstance(object, Dataset):
64+
ds = _lookup(conn, "Dataset", object.id)
65+
for img in ds.listChildren():
66+
yield img
67+
elif isinstance(object, Image):
68+
img = _lookup(conn, "Image", object.id)
69+
yield img
70+
else:
71+
raise ValueError(f"Unsupported type: {object.__class__.__name__}")

0 commit comments

Comments
 (0)