From ab843f1acaf4404160ffbf916f1e352882ff19d9 Mon Sep 17 00:00:00 2001 From: Tom-TBT Date: Sat, 9 Mar 2024 17:08:19 +0100 Subject: [PATCH 1/8] plateAcquisition filter in plate display --- .../data/includes/center_plugin.thumbs.js.html | 13 ++++--------- .../webclient/templates/webclient/data/plate.html | 10 +++++----- omeroweb/webgateway/plategrid.py | 8 ++++++-- .../static/webgateway/js/ome.plateview.js | 15 +++++++++------ omeroweb/webgateway/urls.py | 2 +- omeroweb/webgateway/views.py | 9 +++++++-- 6 files changed, 32 insertions(+), 25 deletions(-) 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 d800ffff92..372e0fc4bd 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/webgateway/plategrid.py b/omeroweb/webgateway/plategrid.py index 3cacbe686f..c5dc0341a2 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 try: import long @@ -29,7 +29,7 @@ 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, acqid, thumbprefix="", plate_layout=None): """ Constructor @@ -39,6 +39,7 @@ def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None): self.plate = conn.getObject("plate", long(pid)) self._conn = conn self.field = fid + self.acquisition = acqid self._thumbprefix = thumbprefix self._metadata = None self.plate_layout = plate_layout @@ -63,6 +64,9 @@ def metadata(self): "where well.plate.id = :id " "and index(ws) = :wsidx" ) + if self.acquisition > 0: + params.add("acqid", rlong(self.acquisition)) + query += " and ws.plateAcquisition.id = :acqid" 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..9fe73227ed 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,16 @@ 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+'/'; + if (acquisition === undefined) { + acquisition = 0; + } + var url = opts.baseurl+'/plate/'+pid+'/'+field+'/'+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 d564a727fe..5de30d8c6d 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1663,7 +1663,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=0, conn=None, **kwargs): """ Layout depends on settings 'omero.web.plate_layout' which can be overridden with request param e.g. ?layout=shrink. @@ -1675,6 +1675,10 @@ def plateGrid_json(request, pid, field=0, conn=None, **kwargs): field = long(field or 0) except ValueError: field = 0 + try: + acquisition = long(acquisition or 0) + except ValueError: + acquisition = 0 prefix = kwargs.get("thumbprefix", "webgateway_render_thumbnail") thumbsize = getIntOrDefault(request, "size", None) logger.debug(thumbsize) @@ -1693,7 +1697,8 @@ def get_thumb_url(iid): conn, pid, field, - kwargs.get("urlprefix", get_thumb_url), + acquisition, + thumbprefix=kwargs.get("urlprefix", get_thumb_url), plate_layout=layout, ) From 46b2b8dccf7af5fa49b98bd61e9fe63b3a5540c8 Mon Sep 17 00:00:00 2001 From: Tom Boissonnet Date: Mon, 11 Mar 2024 10:56:16 +0100 Subject: [PATCH 2/8] changed float() to int() --- omeroweb/webgateway/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index f5d5b8bfd8..f0cb0b8c68 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1654,7 +1654,7 @@ def plateGrid_json(request, pid, field=0, acquisition=0, conn=None, **kwargs): except ValueError: field = 0 try: - acquisition = long(acquisition or 0) + acquisition = int(acquisition or 0) except ValueError: acquisition = 0 prefix = kwargs.get("thumbprefix", "webgateway_render_thumbnail") From 63389859741e1917ac87fe99fbd9909a989406b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Mar 2024 16:48:41 +0100 Subject: [PATCH 3/8] offset WellSample index for plateAcq --- omeroweb/webclient/views.py | 17 +++++++++++++++++ omeroweb/webgateway/plategrid.py | 20 +++++++++++++++++--- omeroweb/webgateway/views.py | 2 +- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/omeroweb/webclient/views.py b/omeroweb/webclient/views.py index 0978f6d4e0..0dfb072c91 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 ac076045ef..27a9bf6631 100644 --- a/omeroweb/webgateway/plategrid.py +++ b/omeroweb/webgateway/plategrid.py @@ -25,12 +25,15 @@ class PlateGrid(object): methods useful for displaying the contents of the plate as a grid. """ - def __init__(self, conn, pid, fid, acqid, thumbprefix="", plate_layout=None): + def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None, acqid=0): """ 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 + + acqid: the acquisition ID. Using it, the field index (fid) must + be in the range [0, max_sample_per_well] for that acquisition. """ self.plate = conn.getObject("plate", int(pid)) self._conn = conn @@ -58,11 +61,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 > 0: + # Offseting 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)) - query += " and ws.plateAcquisition.id = :acqid" + else: + query += "and index(ws) = :wsidx " results = q.projection(query, params, self._conn.SERVICE_OPTS) min_row = 0 diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index f0cb0b8c68..7d82712744 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1675,9 +1675,9 @@ def get_thumb_url(iid): conn, pid, field, - acquisition, thumbprefix=kwargs.get("urlprefix", get_thumb_url), plate_layout=layout, + acqid=acquisition ) plate = plateGrid.plate From a2f7881214d23695413a1ee62e262b1d286ed2f5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:52:04 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- omeroweb/webgateway/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index 7d82712744..cd8e2a7d38 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1677,7 +1677,7 @@ def get_thumb_url(iid): field, thumbprefix=kwargs.get("urlprefix", get_thumb_url), plate_layout=layout, - acqid=acquisition + acqid=acquisition, ) plate = plateGrid.plate From b17e4857626b254e866a393e59e09bd8564fab0a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Mar 2024 11:47:07 +0100 Subject: [PATCH 5/8] run name in image tooltip --- omeroweb/webgateway/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index cd8e2a7d38..07eb5eeebe 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1825,6 +1825,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' @@ -1840,6 +1842,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 From 92e324928567c20a015b3c8a80192e5a855f0a0f Mon Sep 17 00:00:00 2001 From: Tom-TBT Date: Fri, 22 Mar 2024 23:04:49 +0100 Subject: [PATCH 6/8] improved PlateGrid docstring --- omeroweb/webgateway/plategrid.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/omeroweb/webgateway/plategrid.py b/omeroweb/webgateway/plategrid.py index 27a9bf6631..553fbd3e3f 100644 --- a/omeroweb/webgateway/plategrid.py +++ b/omeroweb/webgateway/plategrid.py @@ -32,8 +32,14 @@ def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None, acqid=0): 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 - acqid: the acquisition ID. Using it, the field index (fid) must - be in the range [0, max_sample_per_well] for that acquisition. + 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 @@ -63,7 +69,7 @@ def metadata(self): "where well.plate.id = :id " ) if self.acquisition > 0: - # Offseting index per well for the plateacquisition + # Offseting field index per well for the plateacquisition query += ( "and ws.plateAcquisition.id = :acqid " "and index(ws) - (" From eeeee88d8fa4bbe4b1d8cc1eda3bda634da4447f Mon Sep 17 00:00:00 2001 From: Tom-TBT Date: Fri, 22 Mar 2024 23:35:18 +0100 Subject: [PATCH 7/8] changed undefined runid to None --- omeroweb/webgateway/plategrid.py | 4 ++-- .../webgateway/static/webgateway/js/ome.plateview.js | 7 ++++--- omeroweb/webgateway/views.py | 9 +++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/omeroweb/webgateway/plategrid.py b/omeroweb/webgateway/plategrid.py index 553fbd3e3f..9d6e8a966d 100644 --- a/omeroweb/webgateway/plategrid.py +++ b/omeroweb/webgateway/plategrid.py @@ -25,7 +25,7 @@ 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, acqid=0): + def __init__(self, conn, pid, fid, thumbprefix="", plate_layout=None, acqid=None): """ Constructor @@ -68,7 +68,7 @@ def metadata(self): "join img.details.owner author " "where well.plate.id = :id " ) - if self.acquisition > 0: + if self.acquisition is not None: # Offseting field index per well for the plateacquisition query += ( "and ws.plateAcquisition.id = :acqid " diff --git a/omeroweb/webgateway/static/webgateway/js/ome.plateview.js b/omeroweb/webgateway/static/webgateway/js/ome.plateview.js index 9fe73227ed..ed69bca6d0 100644 --- a/omeroweb/webgateway/static/webgateway/js/ome.plateview.js +++ b/omeroweb/webgateway/static/webgateway/js/ome.plateview.js @@ -211,10 +211,11 @@ jQuery._WeblitzPlateview = function (container, options) { if (field === undefined) { field = 0; } - if (acquisition === undefined) { - acquisition = 0; + + var url = opts.baseurl+'/plate/'+pid+'/'+field+'/' + if (acquisition) { + url += acquisition+'/'; } - var url = opts.baseurl+'/plate/'+pid+'/'+field+'/'+acquisition+'/'; if (opts.size) { url += '?size='+opts.size; } diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index 07eb5eeebe..30703ccc4a 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1641,7 +1641,7 @@ def urlprefix(iid): @login_required() @jsonp -def plateGrid_json(request, pid, field=0, acquisition=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. @@ -1654,9 +1654,10 @@ def plateGrid_json(request, pid, field=0, acquisition=0, conn=None, **kwargs): except ValueError: field = 0 try: - acquisition = int(acquisition or 0) - except ValueError: - acquisition = 0 + acquisition = int(acquisition) + except: + acquisition = None + prefix = kwargs.get("thumbprefix", "webgateway_render_thumbnail") thumbsize = getIntOrDefault(request, "size", None) logger.debug(thumbsize) From 977f7b65169e6dee479197a9156993bbadd2d2e2 Mon Sep 17 00:00:00 2001 From: Tom-TBT Date: Fri, 22 Mar 2024 23:44:35 +0100 Subject: [PATCH 8/8] fix try/except for acquisition id --- omeroweb/webgateway/views.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/omeroweb/webgateway/views.py b/omeroweb/webgateway/views.py index 30703ccc4a..462f99ded9 100644 --- a/omeroweb/webgateway/views.py +++ b/omeroweb/webgateway/views.py @@ -1653,10 +1653,12 @@ def plateGrid_json(request, pid, field=0, acquisition=None, conn=None, **kwargs) field = int(field or 0) except ValueError: field = 0 - try: - acquisition = int(acquisition) - except: - acquisition = None + + 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)