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 4345bfa
Showing 1 changed file with 139 additions and 4 deletions.
143 changes: 139 additions & 4 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 @@ -40,7 +42,7 @@
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
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,129 @@ def __info(self, args):
finally:
img._closeRE()


def _get_datasets_for_image(self, gateway, img):
"""
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'] = 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)
if len(ds) > 1:
self.ctx.out("Warning, more than one dataset found, using latest one")
ds_id = 0
res = None
for d in ds:
if d.getId().getValue() > ds_id:
ds_id = d.getId().getValue()
res = d
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 4345bfa

Please sign in to comment.