Skip to content

Instantly share code, notes, and snippets.

@dpwrussell
Created July 3, 2014 18:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpwrussell/012cabf3a948dc8b184a to your computer and use it in GitHub Desktop.
Save dpwrussell/012cabf3a948dc8b184a to your computer and use it in GitHub Desktop.
Calculate the tree of objects that will chgrp and any other objects which might be affected by this change
def getAllObjects(conn, project_ids, dataset_ids, image_ids, screen_ids,
plate_ids):
"""
Given a list of containers and images, calculate all the descendants
and necessary siblings (for any filesets)
"""
#TODO Handle None inputs, maybe add defaults
params = omero.sys.ParametersI()
# params.addId(experimenter_id)
qs = conn.getQueryService()
project_ids = set(project_ids)
dataset_ids = set(dataset_ids)
image_ids = set(image_ids)
fileset_ids = set([])
plate_ids = set(plate_ids)
screen_ids = set(screen_ids)
print('Initial List')
print('Projects', project_ids)
print('Datasets', dataset_ids)
print('Screens', screen_ids)
print('Plates', plate_ids)
print('Images', image_ids)
# Get any datasets for projects
if project_ids:
params.map = {}
params.map['pids'] = rlist([rlong(x) for x in list(project_ids)])
q = '''
select pdlink.child.id
from ProjectDatasetLink pdlink
where pdlink.parent.id in (:pids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
dataset_ids.add(e[0].val)
# Get any plates for screens
if screen_ids:
params.map = {}
params.map['sids'] = rlist([rlong(x) for x in screen_ids])
q = '''
select splink.child.id
from ScreenPlateLink splink
where splink.parent.id in (:sids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
plate_ids.add(e[0].val)
# Get any images for datasets
if dataset_ids:
params.map = {}
params.map['dids'] = rlist([rlong(x) for x in dataset_ids])
q = '''
select dilink.child.id,
dilink.child.fileset.id
from DatasetImageLink dilink
where dilink.parent.id in (:dids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
image_ids.add(e[0].val)
fileset_ids.add(e[1].val)
# Get any images for plates
# TODO Seemed no need to add the filesets for plates as it isn't possible to
# link it from outside of its plate. This may be true for the client, but it
# certainly isn't true for the model so maybe allow this to also get
# filesets
if plate_ids:
params.map = {}
params.map['plids'] = rlist([rlong(x) for x in plate_ids])
q = '''
select ws.image.id
from WellSample ws
join ws.plateAcquisition pa
where pa.plate.id in (:plids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
image_ids.add(e[0].val)
# Get any extra images due to filesets
if image_ids:
params.map = {}
params.map['fsids'] = rlist([rlong(x) for x in fileset_ids])
q = '''
select image.id
from Image image
left outer join image.datasetLinks dilink
where image.fileset.id in (select fs.id
from Image im
join im.fileset fs
where fs.id in (:fsids)
group by fs.id
having count(im.id)>1)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
image_ids.add(e[0].val)
# Get any additional datasets that may need updating as their children have
# been snatched. Orphaned may also need updated which will be a None in the
# response, this is because an image in a moving fileset might be orphaned
extra_dataset_ids = set([])
if image_ids:
params.map = {
'iids': rlist([rlong(x) for x in image_ids]),
'dids': rlist([rlong(x) for x in dataset_ids])
}
q = '''
select distinct dilink.parent.id
from Image image
left outer join image.datasetLinks dilink
where image.id in (:iids)
and dilink.parent.id not in (:dids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
extra_dataset_ids.add(e[0].val)
# Get any additional projects that may need updating as their children have
# been snatched. There is no need to check for orphans because if a dataset
# is being removed from somewhere else, it can not exist as an orphan.
extra_project_ids = set([])
if dataset_ids:
params.map = {
'dids': rlist([rlong(x) for x in dataset_ids]),
'pids': rlist([rlong(x) for x in project_ids])
}
q = '''
select distinct pdlink.parent.id
from ProjectDatasetLink pdlink
where pdlink.child.id in (:dids)
and pdlink.parent.id not in (:pids)
'''
for e in qs.projection(q, params, conn.SERVICE_OPTS):
extra_project_ids.add(e[0].val)
# We now have the complete list of objects that will change group
# We also have an additional list of datasets/projects that may have had
# snatched children and thus may need updating in the client if the
# dataset/project has gone from N to 0 children
print('Complete List')
print('Projects', project_ids)
print('Datasets', dataset_ids)
print('Screens', screen_ids)
print('Plates', plate_ids)
print('Images', image_ids)
print('Extra Datasets', extra_dataset_ids)
print('Extra Projects', extra_project_ids)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment