From ea42f7f0c7838be8f5e953cd99c191d59962f508 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 7 Oct 2024 08:58:15 +0100 Subject: [PATCH] update dicom viewer to support load by imageid --- anatomy/static/js/dicomViewer.js | 75 ++++++++++++++---------- atlas/templates/atlas/series_viewer.html | 8 ++- atlas/views.py | 13 ++++ 3 files changed, 61 insertions(+), 35 deletions(-) diff --git a/anatomy/static/js/dicomViewer.js b/anatomy/static/js/dicomViewer.js index 13bfbf12..95460979 100644 --- a/anatomy/static/js/dicomViewer.js +++ b/anatomy/static/js/dicomViewer.js @@ -585,13 +585,14 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l //}); } else { let url; - // This doesn't seem to have any benefit - //if (data_url.startsWith("http")) { - // url = data_url; - //} else { - // url = window.location.href.replace(/\/\#\/?$/, '') + "/" + data_url - //} - url = data_url; + // Cornerstone needs the whole url to load? (not relative) + if (data_url.startsWith("http")) { + url = data_url; + } else { + url = window.location.href.replace(/\/\#\/?$/, '').replace("index.html", "") + "/" + data_url + } + //url = data_url; + if (url.endsWith("dcm")) { url = "wadouri:" + url; @@ -618,7 +619,11 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l //console.log("LOAD and cache, then", image); loadCornerstoneMainImage(element, image, stack, db, load_as_stack); - checkAnonStatus(image.data) + + // We can only check dicom data if it exists (e.g. not on jpegs) + if (image.data != undefined) { + checkAnonStatus(image.data) + } let load_annotation_image = true; if (load_annotation_image) { @@ -1215,6 +1220,12 @@ export function loadStackIndex(new_index, dicom_element) { //c = cornerstone.getEnabledElement(dicom_element) } +export function loadImageById(imageId, dicom_element) { + cornerstone.loadImage(imageId).then(b => { + cornerstone.displayImage(dicom_element, b); + }); +} + function urltoFile(url, filename, mimeType) { return fetch(url) .then(function (res) { @@ -1277,34 +1288,34 @@ export function getNextAnnotationImage(element) { } function manualScrollDicom(n, dicom_element) { - // There must be a better way to do this... - //dicom_element = document.getElementById("dicom-image"); - let c = cornerstone.getEnabledElement(dicom_element); + // There must be a better way to do this... + //dicom_element = document.getElementById("dicom-image"); + let c = cornerstone.getEnabledElement(dicom_element); - let max = c.toolStateManager.toolState.stack.data[0].imageIds.length; + let max = c.toolStateManager.toolState.stack.data[0].imageIds.length; - if (max < 2) { - return; - } + if (max < 2) { + return; + } - let current_index = - c.toolStateManager.toolState.stack.data[0].currentImageIdIndex; + let current_index = + c.toolStateManager.toolState.stack.data[0].currentImageIdIndex; - let new_index = current_index + n - - let corrected_index = Math.min(Math.max(new_index, 0), max) + let new_index = current_index + n - // TODO: if loop - //if (new_index >= max) { - // corrected_index = new_index - max; - //} else if (new_index < 0) { - // corrected_index = new_index + max; - //} + let corrected_index = Math.min(Math.max(new_index, 0), max) - c.toolStateManager.toolState.stack.data[0].currentImageIdIndex = corrected_index; - let id = c.toolStateManager.toolState.stack.data[0].imageIds[corrected_index]; - cornerstone.loadImage(id).then((b) => { - cornerstone.displayImage(dicom_element, b); - }); - // c = cornerstone.getEnabledElement(dicom_element) + // TODO: if loop + //if (new_index >= max) { + // corrected_index = new_index - max; + //} else if (new_index < 0) { + // corrected_index = new_index + max; + //} + + c.toolStateManager.toolState.stack.data[0].currentImageIdIndex = corrected_index; + let id = c.toolStateManager.toolState.stack.data[0].imageIds[corrected_index]; + cornerstone.loadImage(id).then((b) => { + cornerstone.displayImage(dicom_element, b); + }); + // c = cornerstone.getEnabledElement(dicom_element) } \ No newline at end of file diff --git a/atlas/templates/atlas/series_viewer.html b/atlas/templates/atlas/series_viewer.html index d3aba48b..d42721f6 100755 --- a/atlas/templates/atlas/series_viewer.html +++ b/atlas/templates/atlas/series_viewer.html @@ -215,9 +215,10 @@ $("#add-finding-button").click(() => { $("#hidden-form").show() dicom_element = $(".cornerstone-element").get(0); - cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element); - cornerstone.reset(dicom_element); - cornerstone.resize(dicom_element, true); + //cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element); + //cornerstone.reset(dicom_element); + ////cornerstone.resize(dicom_element, true); + $("#add-finding-button").hide() //$("#finding-form").empty().append( // $("#hidden-form form").clone() //); @@ -225,6 +226,7 @@ }); $("#cancel-add-finding-button").click((e) => { $("#hidden-form").hide() + $("#add-finding-button").show() e.preventDefault(); }); diff --git a/atlas/views.py b/atlas/views.py index 9a2d44b5..1c1f7ccf 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -1,6 +1,9 @@ import json import pprint +from typing import Any from dal import autocomplete +from django.db.models.base import Model as Model +from django.db.models.query import QuerySet from django.shortcuts import render, get_object_or_404, redirect from django import forms from django.utils import timezone @@ -563,12 +566,21 @@ class CaseDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView): template_name = "confirm_delete.html" +# TODO fix permissions class SeriesFindingDelete(RevisionMixin, PermissionRequiredMixin, DeleteView): permission_required = "atlas.delete_seriesfinding" model = SeriesFinding template_name = "confirm_delete.html" # success_url = reverse_lazy("atlas:case_view") + def get_object(self): + series_finding = super().get_object() + series = series_finding.series + if series.check_user_can_edit(self.request.user): + return series_finding + else: + raise PermissionDenied + def get_success_url(self): pk = self.kwargs["pk"] series_id = get_object_or_404(SeriesFinding, pk=pk).series.id @@ -1375,6 +1387,7 @@ class SeriesImagesZipView(SeriesImagesZipViewBase, SuperuserRequiredMixin): series_object = Series +# At the moment only the series owner / author can delete findings but anyone can create def create_series_findings(request): # posts = Post.objects.all() response_data = {}