diff --git a/omero_figure/omeroutils.py b/omero_figure/omeroutils.py index 367c0c779..aff928a44 100644 --- a/omero_figure/omeroutils.py +++ b/omero_figure/omeroutils.py @@ -40,3 +40,15 @@ def get_timestamps(conn, image): if t in timemap: time_list.append(timemap[t]) return time_list + + +def get_wellsample_index(conn, wellsample_id): + params = ParametersI() + params.addId(wellsample_id) + query = """select index(wellSamples) from Well well + left outer join well.wellSamples as wellSamples + where wellSamples.id = :id + """ + qs = conn.getQueryService() + rsp = qs.projection(query, params, conn.SERVICE_OPTS) + return rsp[0][0].val diff --git a/omero_figure/urls.py b/omero_figure/urls.py index 0cc2a89bc..c734a78c7 100644 --- a/omero_figure/urls.py +++ b/omero_figure/urls.py @@ -76,6 +76,10 @@ # Use query ?image=1&image=2 re_path(r'^timestamps/$', views.timestamps, name='figure_timestamps'), + # Get parents (e.g. Plate, Well, WellSample) for images + # Use query ?image=1&image=2 + re_path(r'^parents/$', views.parents, name='figure_parents'), + # Get Z scale for images # Use query ?image=1&image=2 re_path(r'^z_scale/$', views.z_scale, name='figure_z_scale'), diff --git a/omero_figure/views.py b/omero_figure/views.py index 23b561660..9718a439a 100644 --- a/omero_figure/views.py +++ b/omero_figure/views.py @@ -26,6 +26,8 @@ import json import time +from omeroweb.webclient.show import paths_to_object + from omeroweb.webgateway.marshal import imageMarshal from omeroweb.webgateway.views import _get_prepared_image from omeroweb.webclient.views import run_script @@ -40,7 +42,7 @@ from io import BytesIO from omeroweb.webclient.decorators import login_required -from .omeroutils import get_timestamps +from .omeroutils import get_timestamps, get_wellsample_index from . import utils import logging @@ -160,6 +162,36 @@ def timestamps(request, conn=None, **kwargs): return JsonResponse(data) +@login_required() +def parents(request, conn=None, **kwargs): + + image_ids = request.GET.getlist('image') + try: + image_ids = [int(iid) for iid in image_ids] + except ValueError: + return Http404("Invalid 'image' id") + + parents = {} + for img_id in image_ids: + img_parents = {} + for img_path in paths_to_object(conn, image_id=img_id): + for item in img_path: + o_type = item["type"] + del item["type"] + img_parents[o_type] = item + if o_type == "wellsample": + item["index"] = get_wellsample_index(conn, item["id"]) + continue + obj = conn.getObject(o_type, item["id"]) + if o_type == "well": + item["label"] = obj.getWellPos() + else: + item["name"] = obj.getName() + parents[img_id] = img_parents + + return JsonResponse({"parents": parents}) + + @login_required() def z_scale(request, conn=None, **kwargs): diff --git a/src/js/models/panel_model.js b/src/js/models/panel_model.js index bc9dc7c94..6c5129031 100644 --- a/src/js/models/panel_model.js +++ b/src/js/models/panel_model.js @@ -374,6 +374,9 @@ } else if (format === "name") { text = this.get('datasetName') ? this.get('datasetName') : "No/Many Datasets"; } + } else { + // screen, plate, well, (name or id) + text = "" + this.get(property)?.[format] ?? "Not Found"; } return text; }, @@ -1025,6 +1028,30 @@ } }, + addLabelsFromPlatesWellsFields: function(label_data) { + + // TODO: could ignore image IDs if Plate/Well/Field loaded already + var image_ids = this.map(function(s){return s.get('imageId')}); + image_ids = "image=" + image_ids.join("&image="); + var url = BASE_WEBFIGURE_URL + "parents/?" + image_ids; + console.log('url', url); + $.getJSON(url, function(data){ + console.log(data); + // {screen: {id:3, name:abc}, plate: {id:1, name:foo}, well:{id:2, name:A1}} + const parents = data.parents; + + // Add parents to each panel, then add label + this.forEach(function(p){ + var iid = p.get('imageId'); + if (parents[iid]) { + p.set(parents[iid]); + } + console.log("Adding label..", label_data); + p.add_labels([label_data]); + }); + }.bind(this)); + }, + createLabelsFromTags: function(options) { // Loads Tags for selected images and creates labels var image_ids = this.map(function(s){return s.get('imageId')}) diff --git a/src/js/views/panel_view.js b/src/js/views/panel_view.js index e2bf96bcd..7d58b0104 100644 --- a/src/js/views/panel_view.js +++ b/src/js/views/panel_view.js @@ -219,11 +219,12 @@ format = prop_nf[1] ? prop_nf[1] : "index"; precision = param_dict["precision"] !== undefined ? param_dict["precision"] : 0; // decimal places default to 0 label_value = self.model.get_time_label_text(format, param_dict["offset"], precision); - } else if (['image', 'dataset'].includes(prop_nf[0])){ + } else if (['image', 'dataset', 'screen', 'plate', 'well', 'wellsample'].includes(prop_nf[0])){ format = prop_nf[1] ? prop_nf[1] : "name"; label_value = self.model.get_name_label_text(prop_nf[0], format); + console.log("render_label label_value", label_value, prop_nf); //Escape the underscore for markdown - label_value = label_value.replaceAll("_", "\\_"); + label_value = ("" + label_value).replaceAll("_", "\\_"); } else if (['x', 'y', 'z', 'width', 'height', 'w', 'h', 'rotation', 'rot'].includes(prop_nf[0])){ format = prop_nf[1] ? prop_nf[1] : "pixel"; precision = param_dict["precision"] !== undefined ? param_dict["precision"] : 2; // decimal places default to 2 diff --git a/src/js/views/right_panel_view.js b/src/js/views/right_panel_view.js index a8fecf58a..42ebfdd4a 100644 --- a/src/js/views/right_panel_view.js +++ b/src/js/views/right_panel_view.js @@ -353,6 +353,18 @@ return false; } + // If we need SPW info and we don't have it, load... + if (label_text.includes('[plate.name]') || label_text.includes('well.name') || label_text.includes('field.index')) { + // Load Plate Name for images... + console.log("label_text", label_text); + selected.addLabelsFromPlatesWellsFields({ + text: label_text, + position: position, + size: font_size, + color: color}); + return false; + } + if (label_text == '[tags]') { // Load Tags for this image and create labels diff --git a/src/templates/labels_form_inner_template.html b/src/templates/labels_form_inner_template.html index a2ea5e3f8..0574c681c 100644 --- a/src/templates/labels_form_inner_template.html +++ b/src/templates/labels_form_inner_template.html @@ -13,6 +13,8 @@