Skip to content

Commit

Permalink
Merge pull request #3776 from chris-allan/plate-metadata-perf-develop
Browse files Browse the repository at this point in the history
Optimize plate grid metadata
  • Loading branch information
joshmoore committed May 6, 2015
2 parents d5d12a9 + a56dc76 commit 0882649
Show file tree
Hide file tree
Showing 6 changed files with 552 additions and 27 deletions.
12 changes: 8 additions & 4 deletions components/tools/OmeroPy/src/omero/gateway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5603,10 +5603,14 @@ def getGridSize(self):
:rtype: dict of {'rows': rSize, 'columns':cSize}
"""
if self._gridSize is None:
r, c = 0, 0
for child in self._listChildren():
r, c = max(child.row.val, r), max(child.column.val, c)
self._gridSize = {'rows': r+1, 'columns': c+1}
q = self._conn.getQueryService()
params = omero.sys.ParametersI()
params.addId(self.getId())
query = "select max(row), max(column) from Well "\
"where plate.id = :id"
res = q.projection(query, params, self._conn.SERVICE_OPTS)
(row, col) = res[0]
self._gridSize = {'rows': row.val+1, 'columns': col.val+1}
return self._gridSize

def getWellGrid(self, index=0):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2015 Glencoe Software, Inc.
# All rights reserved.
#
# Use is subject to license terms supplied in LICENSE.txt

"""
gateway tests - Testing the gateway image wrapper
pytest fixtures used as defined in conftest.py:
- gatewaywrapper
"""

import pytest

from omero.model import ImageI
from omero.rtypes import rstring, rtime
from datetime import datetime


@pytest.fixture()
def image(request, gatewaywrapper):
"""Creates an Image."""
gatewaywrapper.loginAsAuthor()
gw = gatewaywrapper.gateway
update_service = gw.getUpdateService()
image = ImageI()
image.name = rstring('an image')
# 2015-04-21 01:15:00
image.acquisitionDate = rtime(1429578900000L)
image_id, = update_service.saveAndReturnIds([image])
return gw.getObject('Image', image_id)


@pytest.fixture()
def image_no_acquisition_date(request, gatewaywrapper):
"""Creates an Image."""
gatewaywrapper.loginAsAuthor()
gw = gatewaywrapper.gateway
update_service = gw.getUpdateService()
image = ImageI()
image.name = rstring('an image')
image.acquisitionDate = rtime(0L)
image_id, = update_service.saveAndReturnIds([image])
return gw.getObject('Image', image_id)


class TestImageWrapper(object):

def testGetDate(self, gatewaywrapper, image):
date = image.getDate()
assert date == datetime.fromtimestamp(1429578900L)

def testGetDateNoAcquisitionDate(
self, gatewaywrapper, image_no_acquisition_date):
date = image_no_acquisition_date.getDate()
creation_event_date = image_no_acquisition_date.creationEventDate()
assert date == creation_event_date

def testSimpleMarshal(self, gatewaywrapper, image):
marshalled = image.simpleMarshal()
assert marshalled == {
'description': '',
'author': 'Author ',
'date': 1429578900.0,
'type': 'Image',
'id': image.getId(),
'name': 'an image'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2015 Glencoe Software, Inc.
# All rights reserved.
#
# Use is subject to license terms supplied in LICENSE.txt

"""
gateway tests - Testing the gateway plate wrapper
pytest fixtures used as defined in conftest.py:
- gatewaywrapper
"""

import pytest

from omero.model import PlateI, WellI, WellSampleI, ImageI
from omero.rtypes import rstring, rint, rtime
from uuid import uuid4


def uuid():
return str(uuid4())


@pytest.fixture()
def plate(request, gatewaywrapper):
"""Creates a Plate."""
gatewaywrapper.loginAsAuthor()
gw = gatewaywrapper.gateway
update_service = gw.getUpdateService()
plate = PlateI()
plate.name = rstring(uuid())
for well_index in range(3):
well = WellI()
well.row = rint(well_index**2)
well.column = rint(well_index**3)
for well_sample_index in range(2):
well_sample = WellSampleI()
image = ImageI()
image.name = rstring('%s_%d' % (uuid(), well_sample_index))
image.acquisitionDate = rtime(0)
well_sample.image = image
well.addWellSample(well_sample)
plate.addWell(well)
plate_id, = update_service.saveAndReturnIds([plate])
return gw.getObject('Plate', plate_id)


class TestPlateWrapper(object):

def testGetGridSize(self, gatewaywrapper, plate):
assert plate.getGridSize() == {'rows': 5L, 'columns': 9L}
86 changes: 86 additions & 0 deletions components/tools/OmeroWeb/omeroweb/webgateway/plategrid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2015 Glencoe Software, Inc.
# All rights reserved.
#
# Use is subject to license terms supplied in LICENSE.txt

"""
Module to encapsulate operations concerned with displaying the contents of a
plate as a grid.
"""

import logging

import omero.sys
from omero.rtypes import rint

logger = logging.getLogger(__name__)


class PlateGrid(object):
"""
A PlateGrid object encapsulates a PlateI reference and provides a number of
methods useful for displaying the contents of the plate as a grid.
"""

def __init__(self, conn, pid, fid, thumbprefix=''):
self.plate = conn.getObject('plate', long(pid))
self._conn = conn
self.field = fid
self._thumbprefix = thumbprefix
self._metadata = None

@property
def metadata(self):
if self._metadata is None:
self.plate.setGridSizeConstraints(8, 12)
size = self.plate.getGridSize()
grid = [[None] * size['columns'] for _ in range(size['rows'])]

q = self._conn.getQueryService()
params = omero.sys.ParametersI()
params.addId(self.plate.id)
params.add('wsidx', rint(self.field))
query = "select well.row, well.column, img.id, img.name, "\
"author.firstName||' '||author.lastName, "\
"well.id, img.acquisitionDate, "\
"img.details.creationEvent.time, "\
"img.description "\
"from Well well "\
"join well.wellSamples ws "\
"join ws.image img "\
"join img.details.owner author "\
"where well.plate.id = :id "\
"and index(ws) = :wsidx"

for res in q.projection(query, params, self._conn.SERVICE_OPTS):
row, col, img_id, img_name, author, well_id, acq_date, \
create_date, description = res

if acq_date is not None and acq_date.val > 0:
date = acq_date.val / 1000
else:
date = create_date.val / 1000
description = (description and description.val) or ''

wellmeta = {'type': 'Image',
'id': img_id.val,
'name': img_name.val,
'description': description,
'author': author.val,
'date': date,
'wellId': well_id.val,
'field': self.field}

if callable(self._thumbprefix):
wellmeta['thumb_url'] = self._thumbprefix(str(img_id.val))
else:
wellmeta['thumb_url'] = self._thumbprefix + str(img_id.val)

grid[row.val][col.val] = wellmeta

self._metadata = {'grid': grid,
'collabels': self.plate.getColumnLabels(),
'rowlabels': self.plate.getRowLabels()}
return self._metadata
31 changes: 8 additions & 23 deletions components/tools/OmeroWeb/omeroweb/webgateway/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from django.core.servers.basehttp import FileWrapper
from omero.rtypes import rlong, unwrap
from omero.constants.namespaces import NSBULKANNOTATIONS
from plategrid import PlateGrid
from omero_version import build_year
from marshal import imageMarshal, shapeMarshal

Expand Down Expand Up @@ -1328,43 +1329,27 @@ def urlprefix(iid):
def plateGrid_json(request, pid, field=0, conn=None, **kwargs):
"""
"""
plate = conn.getObject('plate', long(pid))
try:
field = long(field or 0)
except ValueError:
field = 0
if plate is None:
return HttpJavascriptResponseServerError('""')
grid = []
prefix = kwargs.get('thumbprefix', 'webgateway.views.render_thumbnail')
thumbsize = int(request.REQUEST.get('size', 64))
logger.debug(thumbsize)
server_id = kwargs['server_id']

def urlprefix(iid):
return reverse(prefix, args=(iid, thumbsize))
xtra = {'thumbUrlPrefix': kwargs.get('urlprefix', urlprefix)}
server_id = kwargs['server_id']
plateGrid = PlateGrid(conn, pid, field,
kwargs.get('urlprefix', urlprefix))
plate = plateGrid.plate
if plate is None:
return Http404

rv = webgateway_cache.getJson(request, server_id, plate,
'plategrid-%d-%d' % (field, thumbsize))
if rv is None:
plate.setGridSizeConstraints(8, 12)
for row in plate.getWellGrid(field):
tr = []
for e in row:
if e:
i = e.getImage()
if i:
t = i.simpleMarshal(xtra=xtra)
t['wellId'] = e.getId()
t['field'] = field
tr.append(t)
continue
tr.append(None)
grid.append(tr)
rv = {'grid': grid,
'collabels': plate.getColumnLabels(),
'rowlabels': plate.getRowLabels()}
rv = plateGrid.metadata
webgateway_cache.setJson(request, server_id, plate, json.dumps(rv),
'plategrid-%d-%d' % (field, thumbsize))
else:
Expand Down
Loading

0 comments on commit 0882649

Please sign in to comment.