diff --git a/omeroweb/webclient/templates/webclient/data/includes/center_plugin.thumbs.js.html b/omeroweb/webclient/templates/webclient/data/includes/center_plugin.thumbs.js.html index 01b61b00fd..e742f9b14b 100644 --- a/omeroweb/webclient/templates/webclient/data/includes/center_plugin.thumbs.js.html +++ b/omeroweb/webclient/templates/webclient/data/includes/center_plugin.thumbs.js.html @@ -666,7 +666,7 @@ html = "" + html; $("#filter_by_tag").html(html); - // hide filtered images + // hide filtered images $("#dataIcons li.row").each(function() { var $this = $(this), iid = parseInt($this.attr("data-id"), 10); @@ -1005,14 +1005,9 @@ switch(nodeType) { case 'plate': - // Only load plates if it has a single 'Run' (or none) - if (node.children.length < 2) { - url += 'load_plate/' + nodeType + '/' + nodeId + '/?index=' + newField; - if (show) { - url += "&show=" + show; - } - } else { - url = undefined; + url += 'load_plate/' + nodeType + '/' + nodeId + '/?index=' + newField; + if (show) { + url += "&show=" + show; } break; case 'acquisition': diff --git a/omeroweb/webclient/templates/webclient/data/plate.html b/omeroweb/webclient/templates/webclient/data/plate.html index b56234ab48..f38d68edb3 100644 --- a/omeroweb/webclient/templates/webclient/data/plate.html +++ b/omeroweb/webclient/templates/webclient/data/plate.html @@ -22,11 +22,11 @@ --> {% endcomment %} - + - +
diff --git a/omeroweb/webclient/views.py b/omeroweb/webclient/views.py index c9dd82121f..504ce999d3 100755 --- a/omeroweb/webclient/views.py +++ b/omeroweb/webclient/views.py @@ -1468,6 +1468,23 @@ def load_plate(request, o1_type=None, o1_id=None, conn=None, **kwargs): template = None if "plate" in kw or "acquisition" in kw: fields = manager.getNumberOfFields() + if "acquisition" in kw: + # need to offset the index for 0-indexing at acquisition level + qs = conn.getQueryService() + p = omero.sys.ParametersI() + p.add("acqid", rlong(o1_id)) + query = ( + "SELECT max(index(ws)) - min(index(ws)) " + "FROM Well w " + "JOIN w.wellSamples ws " + "WHERE ws.plateAcquisition.id = :acqid " + "GROUP BY w.id" + ) + res = [r[0].getValue() for r in qs.projection(query, p, conn.SERVICE_OPTS)] + if len(res) >= 1: + # The range of the fields is set for the current acquisition + fields = (0, max(res)) + if fields is not None: form_well_index = WellIndexForm(initial={"index": index, "range": fields}) if index == 0: diff --git a/omeroweb/webgateway/plategrid.py b/omeroweb/webgateway/plategrid.py index 636eb56d15..9d6e8a966d 100644 --- a/omeroweb/webgateway/plategrid.py +++ b/omeroweb/webgateway/plategrid.py @@ -13,7 +13,7 @@ import logging import omero.sys -from omero.rtypes import rint +from omero.rtypes import rint, rlong logger = logging.getLogger(__name__) @@ -25,16 +25,26 @@ class PlateGrid(object): methods useful for displaying the contents of the plate as a grid. """ - def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None): + def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None, acqid=None): """ Constructor param: plate_layout is "expand" to expand plate to multiple of 8 x 12 or "shrink" to ignore all wells before the first row/column + + fid: the field index relative to the lowest "absolute field index" + for that well. When filtering the image samples with an + acquisition ID (acqid), the lowest field index may be + different for each well. + In the range [0, max_sample_per_well] + (or [0, max_sample_per_well_per_acquisition] with an acqid) + + acqid: the acquisition ID to filter the WellSamples. """ self.plate = conn.getObject("plate", int(pid)) self._conn = conn self.field = fid + self.acquisition = acqid self._thumbprefix = thumbprefix self._metadata = None self.plate_layout = plate_layout @@ -57,8 +67,22 @@ def metadata(self): "join ws.image img " "join img.details.owner author " "where well.plate.id = :id " - "and index(ws) = :wsidx" ) + if self.acquisition is not None: + # Offseting field index per well for the plateacquisition + query += ( + "and ws.plateAcquisition.id = :acqid " + "and index(ws) - (" + " SELECT MIN(index(ws_inner)) " + " FROM Well well_inner " + " JOIN well_inner.wellSamples ws_inner " + " WHERE ws_inner.plateAcquisition.id = :acqid " + " AND well_inner.id = well.id " + ") = :wsidx " + ) + params.add("acqid", rlong(self.acquisition)) + else: + query += "and index(ws) = :wsidx " results = q.projection(query, params, self._conn.SERVICE_OPTS) min_row = 0 diff --git a/omeroweb/webgateway/static/webgateway/js/ome.plateview.js b/omeroweb/webgateway/static/webgateway/js/ome.plateview.js index 7b8b911dab..ed69bca6d0 100644 --- a/omeroweb/webgateway/static/webgateway/js/ome.plateview.js +++ b/omeroweb/webgateway/static/webgateway/js/ome.plateview.js @@ -4,7 +4,7 @@ * Depends on jquery * * Copyright (c) 2011 Glencoe Software, Inc. All rights reserved. - * + * * This software is distributed under the terms described by the LICENCE file * you can find at the root of the distribution bundle, which states you are * free to use it only for non commercial purposes. @@ -39,14 +39,14 @@ * - adds the pv-focus css class to the thumb pointed to by the elm jQuery object * removing it from any other thumbnail eventually focused on this plate * - elm is the jQuery object for the thumb to be focused - * + * * plate.rmFocus(elm) * - removes the pv-focus css class to the thumb pointed to by the elm jQuery object * or from any thumbnail in this plate if elm is null or undefined * - elm is the optional jQuery object for the thumb to loose focused * * - Events - - * + * * thumbClick(ev, welldata, thumb) * - triggered when there's a mouse click on a thumb. * - welldata holds a dictionary holding metadata for the clicked well @@ -65,7 +65,7 @@ * - thumb is the jQuery object for the thumb image * * - jQuery obj data attributes - - * + * * noFocus * - if true, prevents css pv-focus class to be added on setFocus * @@ -205,13 +205,17 @@ jQuery._WeblitzPlateview = function (container, options) { _this.self.trigger('_resetLoaded'); }; - this.load = function (pid,field) { + this.load = function (pid,field,acquisition) { $('table img', _this.self).remove(); $('table div.placeholder', _this.self).removeClass('placeholder').addClass('loading'); if (field === undefined) { field = 0; } - var url = opts.baseurl+'/plate/'+pid+'/'+field+'/'; + + var url = opts.baseurl+'/plate/'+pid+'/'+field+'/' + if (acquisition) { + url += acquisition+'/'; + } if (opts.size) { url += '?size='+opts.size; } diff --git a/omeroweb/webgateway/urls.py b/omeroweb/webgateway/urls.py index 449360d6f1..3d529ab41a 100644 --- a/omeroweb/webgateway/urls.py +++ b/omeroweb/webgateway/urls.py @@ -365,7 +365,7 @@ """ webgateway_plategrid_json = re_path( - r"^plate/(?P[0-9]+)/(?:(?P[0-9]+)/)?$", + r"^plate/(?P[0-9]+)/(?:(?P[0-9]+)/)?(?:(?P[0-9]+)/)?$", views.plateGrid_json, name="webgateway_plategrid_json", ) diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index 4448d376ab..228d8a124d 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1602,7 +1602,7 @@ def urlprefix(iid): @login_required() @jsonp -def plateGrid_json(request, pid, field=0, conn=None, **kwargs): +def plateGrid_json(request, pid, field=0, acquisition=None, conn=None, **kwargs): """ Layout depends on settings 'omero.web.plate_layout' which can be overridden with request param e.g. ?layout=shrink. @@ -1614,6 +1614,13 @@ def plateGrid_json(request, pid, field=0, conn=None, **kwargs): field = int(field or 0) except ValueError: field = 0 + + if acquisition is not None: + try: + acquisition = int(acquisition) + except ValueError: + acquisition = None + prefix = kwargs.get("thumbprefix", "webgateway_render_thumbnail") thumbsize = getIntOrDefault(request, "size", None) logger.debug(thumbsize) @@ -1631,8 +1638,9 @@ def get_thumb_url(iid): conn, pid, field, - kwargs.get("urlprefix", get_thumb_url), + thumbprefix=kwargs.get("urlprefix", get_thumb_url), plate_layout=layout, + acqid=acquisition, ) plate = plateGrid.plate @@ -1773,6 +1781,8 @@ def marshal_pos(w): d[x] = {"value": p.getValue(), "unit": str(p.getUnit())} return d + plate = well.getParent() + run_d = {r.getId(): r.getName() for r in plate.listPlateAcquisitions()} wellImgs = [] for ws in well.listChildren(): # optionally filter by acquisition 'run' @@ -1788,6 +1798,8 @@ def marshal_pos(w): pos = marshal_pos(ws) if len(pos.keys()) > 0: m["position"] = pos + if ws.plateAcquisition is not None: + m["name"] += f" [Run: {run_d[ws.plateAcquisition._id._val]}]" wellImgs.append(m) return wellImgs