Skip to content

Commit

Permalink
Add export and impo(rt) commands
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikl committed Jan 30, 2024
1 parent eb785c6 commit b06b9a8
Showing 1 changed file with 138 additions and 5 deletions.
143 changes: 138 additions & 5 deletions src/omero_cli_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from __future__ import print_function

import omero
from past.builtins import long
from builtins import str
from builtins import range
Expand All @@ -33,14 +35,14 @@
from omero.cli import BaseControl
from omero.cli import CLI
from omero.cli import ProxyStringType
from omero.gateway import BlitzGateway
from omero.gateway import BlitzGateway, DatasetWrapper
from omero.model import Image
from omero.model import Plate
from omero.model import Screen
from omero.model import Dataset
from omero.model import Project
from omero.model import StatsInfoI
from omero.rtypes import rint, rdouble
from omero.rtypes import rint, rdouble, rstring, rlong
from omero.util import pydict_text_io

from omero import UnloadedEntityException
Expand Down Expand Up @@ -377,19 +379,21 @@ def _configure(self, parser):
set_cmd = parser.add(sub, self.set, SET_HELP)
edit = parser.add(sub, self.edit, EDIT_HELP)
test = parser.add(sub, self.test, TEST_HELP)
export = parser.add(sub, self.export, "Export rendering settings as yaml files")
impo = parser.add(sub, self.impo, "Import rendering settings from yaml files")

render_type = ProxyStringType("Image")
src_help = ("Rendering settings source")

for x in (get, info, copy, test):
for x in (get, info, copy, test, export):
x.add_argument("object", type=render_type, help=src_help)

tgt_help = ("Objects to apply the rendering settings to")
for x in (set_cmd, edit):
x.add_argument("object", type=render_type, help=tgt_help,
nargs="+")

for x in (copy, set_cmd, edit):
for x in (copy, set_cmd, edit, impo):
x.add_argument(
"--skipthumbs", help="Do not regenerate thumbnails "
"immediately", action="store_true")
Expand All @@ -406,7 +410,7 @@ def _configure(self, parser):
copy.add_argument("target", type=render_type, help=tgt_help,
nargs="+")

for x in (set_cmd, edit):
for x in (set_cmd, edit, impo):
x.add_argument(
"--disable", help="Disable non specified channels ",
action="store_true")
Expand All @@ -428,6 +432,14 @@ def _configure(self, parser):
help="If underlying pixel data available test thumbnail retrieval"
)

export.add_argument("--sep", default="|", help="Separator character (default: |)")
export.add_argument("--traverse", action="store_true", help="Export settings for all images of a dataset (default: just first one)")

impo.add_argument("--sep", default="|", help="Separator character (default: |)")
impo.add_argument("--dataset", action="store_true", help="Rendering settings should be applied to the whole dataset")
impo.add_argument("--spw", action="store_true", help="If target is Screen/Plate/Well (NOT SUPPORTED YET)")


def _lookup(self, gateway, type, oid):
# TODO: move _lookup to a _configure type
gateway.SERVICE_OPTS.setOmeroGroup('-1')
Expand Down Expand Up @@ -537,6 +549,127 @@ def __info(self, args):
finally:
img._closeRE()


def _get_datasets_for_image(self, gateway, img_id):
"""
Get all datasets an image is part of.
:param gateway: Ref to gateway
:param img: The image
:return: The datasets
"""
query = "select i from Image i join fetch i.datasetLinks idl " \
"join fetch idl.parent d where i.id = :id"
params = omero.sys.ParametersI()
params.map['id'] = rlong(img_id)
img = gateway.getQueryService().findByQuery(query, params)
datasets = []
for link in img.iterateDatasetLinks():
datasets.append(link.parent)
return datasets


@gateway_required
def impo(self, args):
"""Implements the impo(rt) command"""
filename = args.channels
filename = filename.replace(".yml", "")
ds_name = filename.split(args.sep)[0]
img_name = filename.split(args.sep)[1]

set_args = args
if args.dataset:
ds_query = "select d from Dataset d where d.name = :name"
params = omero.sys.ParametersI()
params.map['name'] = rstring(ds_name)
datasets = self.gateway.getQueryService().findAllByQuery(ds_query, params)
if not datasets:
self.ctx.err(f"No dataset with name {ds_name} found.")
return
elif len(datasets) > 1:
self.ctx.dbg("More than one dataset found, using latest one")
target_ds = max(datasets, key=lambda ds: ds.getId().getValue())
else:
target_ds = datasets[0]
set_args.object = target_ds
self.set(set_args)
else:
img_query = "select c from DatasetImageLink l " \
"join l.child as c " \
"join l.parent as p " \
"where p.name = :name1 and c.name = :name2"
params = omero.sys.ParametersI()
params.map['name1'] = rstring(ds_name)
params.map['name2'] = rstring(img_name)
images = self.gateway.getQueryService().findAllByQuery(img_query, params)
if not images:
self.ctx.err(f"No image with name {img_name} found within a dataset {ds_name}.")
return
elif len(images) > 1:
self.ctx.dbg("More than one images found, using latest one.")
target_img = max(images, key=lambda img: img.getId().getValue())
else:
target_img = images[0]
set_args.object = target_img
self.set(set_args)


def __do_export(self, ds, img, sep):
"""
Exports the rendering settings of an image to a file
called <IMAGE_NAME><SEPARATOR><DATASET_NAME>.yml
:param ds: The dataset
:param img: The image
:param sep: The separator
:return: None
"""
try:
ro = RenderObject(img)
name = f"{ds.getName()}{sep}{img.getName()}.yml"
with open(name, "w") as out:
out.write(yaml.dump(ro.to_dict(),
explicit_start=True,
width=80, indent=4,
default_flow_style=False).rstrip())
except Exception as e:
self.ctx.err('ERROR: %s' % e)
finally:
img._closeRE()


@gateway_required
def export(self, args):
"""Implements the export command"""
if isinstance(args.object, Project):
prj = self._lookup(self.gateway, "Project", args.object.id)
for ds in prj.listChildren():
ds = self._lookup(self.gateway, "Dataset", ds.id)
for img in ds.listChildren():
self.__do_export(ds, img, args.sep)
if not args.traverse:
break

elif isinstance(args.object, Dataset):
ds = self._lookup(self.gateway, "Dataset", args.object.id)
for img in ds.listChildren():
self.__do_export(ds, img, args.sep)
if not args.traverse:
break

elif isinstance(args.object, Image):
img = self._lookup(self.gateway, "Image", args.object.id)
ds = self._get_datasets_for_image(self.gateway, args.object.id.getValue())
if len(ds) > 1:
self.ctx.out("Warning, more than one dataset found, using latest one")
res = max(ds, key=lambda d: d.getId().getValue())
else:
res = ds[0]
res = DatasetWrapper(conn=self.gateway, obj=res)
self.__do_export(res, img, args.sep)

else:
self.ctx.err(f"{args.object.__class__.__name__} not supported yet ")


@gateway_required
def copy(self, args):
""" Implements the 'copy' command """
Expand Down

0 comments on commit b06b9a8

Please sign in to comment.