many improvements
This commit is contained in:
@@ -167,7 +167,7 @@ $(document).ready(function () {
|
||||
|
||||
window.loadDicomViewerEvent = new Event('loadDicomViewer');
|
||||
window.addEventListener('loadDicomViewer', function (e) {
|
||||
//console.log("listen", e.detail)
|
||||
console.log("LoadDicomViewer event", e.detail)
|
||||
let images = [];
|
||||
//console.log($("#image_form_set img"));
|
||||
$(e.detail).each((n, el) => {
|
||||
@@ -179,6 +179,7 @@ window.addEventListener('loadDicomViewer', function (e) {
|
||||
|
||||
window.loadDicomViewerEvent = new Event('loadDicomViewerUrls');
|
||||
window.addEventListener('loadDicomViewerUrls', function (e) {
|
||||
console.log("LoadDicomViewer unls event", e.detail)
|
||||
|
||||
loadDicomViewer(e.detail.images, e.detail.annotations);
|
||||
}, false);
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
|
||||
function addFile(f, feedback) {
|
||||
console.log("add file", f)
|
||||
let dT = new DataTransfer();
|
||||
dT.clearData();
|
||||
dT.items.add(f);
|
||||
@@ -162,9 +163,6 @@
|
||||
// Probably no need to await here anymore
|
||||
//await readFile(el.files[0], el);
|
||||
|
||||
|
||||
|
||||
|
||||
$(el).parent().parent().find(".temp-thumb").remove();
|
||||
|
||||
let url = URL.createObjectURL(el.files[0])
|
||||
@@ -196,9 +194,9 @@
|
||||
checkHash(hash, el);
|
||||
|
||||
if ($("#drop-filenames").length > 0) {
|
||||
$("#drop-filenames").append(
|
||||
`<span data-input-id='${el.id}'><span>${n}: ${el.files[0].name}</span><img class='uploading${extra_class}' data-input-id='${el.id}' src=${url}></span>`
|
||||
)
|
||||
$("#drop-filenames").append(
|
||||
`<span data-input-id='${el.id}'><span>${n}: ${el.files[0].name}</span><img class='uploading${extra_class}' data-input-id='${el.id}' src=${url}></span>`
|
||||
)
|
||||
}
|
||||
} else {
|
||||
imageId = `wadouri:${url}`;
|
||||
@@ -223,7 +221,7 @@
|
||||
console.log("image", image)
|
||||
|
||||
let bytesView = image.getPixelData()
|
||||
let str = new TextDecoder("utf-8").decode(bytesView, );
|
||||
let str = new TextDecoder("utf-8").decode(bytesView, );
|
||||
|
||||
console.log("bytes", bytesView)
|
||||
console.log("str", str)
|
||||
@@ -363,7 +361,7 @@
|
||||
//}
|
||||
|
||||
image_set = $("#image_form_set .temp-thumb").get() //.map(function() { return $(this).attr("src")}).get();
|
||||
console.log(image_set);
|
||||
console.log("image set", image_set);
|
||||
//console.log()
|
||||
//if (n == image_set.length) {
|
||||
const event = new CustomEvent('loadDicomViewer', {
|
||||
@@ -376,4 +374,169 @@
|
||||
updateImagePositions();
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
function extractDicomDetails(byteArray) {
|
||||
// We need to setup a try/catch block because parseDicom will throw an exception
|
||||
// if you attempt to parse a non dicom part 10 file (or one that is corrupted)
|
||||
try {
|
||||
console.log("bytearray", byteArray)
|
||||
// parse byteArray into a DataSet object using the parseDicom library
|
||||
var dataSet = dicomParser.parseDicom(byteArray);
|
||||
console.log("ds", dataSet)
|
||||
|
||||
// dataSet contains the parsed elements. Each element is available via a property
|
||||
// in the dataSet.elements object. The property name is based on the elements group
|
||||
// and element in the following format: xggggeeee where gggg is the group number
|
||||
// and eeee is the element number with lowercase hex characters.
|
||||
|
||||
// To access the data for an element, we need to know its type and its tag.
|
||||
// We will get the sopInstanceUid from the file which is a string and
|
||||
// has the tag (0020,000D)
|
||||
var study_description = dataSet.string('x00081030');
|
||||
var accession_number = dataSet.string('x00080050').toLowerCase();
|
||||
var patient_id = dataSet.string('x00100020').toLowerCase();
|
||||
var modality = dataSet.string('x00080060');
|
||||
var projection = dataSet.string('x00185101');
|
||||
|
||||
try {
|
||||
var plane = dataSet.string('x00180022').toLowerCase();
|
||||
} catch (err) {
|
||||
var plane = "";
|
||||
}
|
||||
console.log("STUDY", study_description);
|
||||
console.log("acc", accession_number);
|
||||
console.log("pid", patient_id);
|
||||
console.log("projection", projection);
|
||||
console.log("plane", plane);
|
||||
|
||||
function select_plane(option) {
|
||||
let plane_select_object = document.getElementsByName("plane")[0]
|
||||
const $options = Array.from(plane_select_object.options);
|
||||
const optionToSelect = $options.find(item => item.text === option);
|
||||
optionToSelect.selected = true;
|
||||
|
||||
}
|
||||
|
||||
if (plane.includes("axial")) {
|
||||
select_plane("axial");
|
||||
} else if (plane.includes("sagittal")) {
|
||||
select_plane("sagittal");
|
||||
} else if (plane.includes("coronal")) {
|
||||
select_plane("coronal");
|
||||
} else if (plane.includes("ap")) {
|
||||
select_plane("AP");
|
||||
} else if (plane.includes("lat") | plane.includes("lateral")) {
|
||||
select_plane("lateral");
|
||||
} else if (plane.includes("pa")) {
|
||||
select_plane("PA");
|
||||
|
||||
}
|
||||
|
||||
|
||||
modality_map = {
|
||||
"DX": "Radiograph",
|
||||
"CR": "Radiograph",
|
||||
"CT": "CT",
|
||||
"MR": "MR",
|
||||
"RF": "Fluroscopy",
|
||||
"US": "Ultrasound",
|
||||
}
|
||||
|
||||
if (modality in modality_map) {
|
||||
let modality_select_object = document.getElementsByName("modality")[0]
|
||||
const $options = Array.from(modality_select_object.options);
|
||||
const optionToSelect = $options.find(item => item.text === modality_map[modality]);
|
||||
optionToSelect.selected = true;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
toastr.info(`Unable to automatically set modality: ${modality}`);
|
||||
}
|
||||
|
||||
// If the dicom study_description contains multiple values select the first
|
||||
study_description = study_description.split(",")[0].trim();
|
||||
|
||||
to_replace = ["lt", "rt", "contrast", "LT", "RT", "Contrast"];
|
||||
|
||||
for (let i = 0; i < to_replace.length; i++) {
|
||||
|
||||
study_description = study_description.replace(to_replace[i], "");
|
||||
}
|
||||
|
||||
let select_object = document.getElementsByName("examination")[0]
|
||||
|
||||
if (select_object.value == "") {
|
||||
$.get(`${select_object.dataset.autocompleteLightUrl}?q=${study_description}`, (data) => {
|
||||
console.log(data)
|
||||
if (data.results.length == 1) {
|
||||
|
||||
$(select_object).select2("trigger", "select", {
|
||||
data: data.results[0]
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
not_anon = false;
|
||||
|
||||
site_codes = ["ref", "rk9", "ra9", "rh8", "rbz", "rba"]
|
||||
|
||||
for (let i = 0; i < site_codes.length; i++) {
|
||||
if (
|
||||
accession_number.startsWith(site_codes[i]) ||
|
||||
patient_id.startsWith(site_codes[i])) {
|
||||
not_anon = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (not_anon) {
|
||||
toastr.warning(`File does not appear to be annonymised<br/>Accession: ${accession_number} <br/>Patient ID: ${patient_id}<br/>`, 'Anonymisation warning', {
|
||||
"closeButton": false,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toast-top-full-width",
|
||||
"preventDuplicates": false,
|
||||
"onclick": null,
|
||||
"showDuration": "0",
|
||||
"hideDuration": "0",
|
||||
"timeOut": 0,
|
||||
"extendedTimeOut": 0,
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut",
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: fix
|
||||
//$.ajax({
|
||||
// url: `{% url 'generic:examination-autocomplete' %}/${encodeURI(study_description)}`,
|
||||
// //context: document.body,
|
||||
// success: function(data){
|
||||
// console.log(data)
|
||||
// }
|
||||
//});
|
||||
|
||||
//// try to match with a study description (if not already selected)
|
||||
//if ($(`#id_examination_to option`).length < 1) {
|
||||
// option = $(`#id_examination_from option[title*='${study_description}' i]`);
|
||||
|
||||
// if (option.length) {
|
||||
// option.appendTo($("#id_examination_to"));
|
||||
// toastr.success(`Examination set to ${option.attr('title')} from dicom data`);
|
||||
// } else {
|
||||
// toastr.warning(
|
||||
// `Unable to set examination ${study_description} from dicom data (it needs creating)`);
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
+14
-3
@@ -20,7 +20,7 @@ from pydicom.errors import InvalidDicomError
|
||||
|
||||
from django.core.files.storage import FileSystemStorage
|
||||
from django.conf import settings
|
||||
from django.utils.html import format_html
|
||||
from django.utils.html import format_html, mark_safe
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
@@ -39,6 +39,8 @@ from helpers.images import (
|
||||
pretty_print_dicom,
|
||||
)
|
||||
|
||||
import mimetypes
|
||||
|
||||
|
||||
from generic.models import (
|
||||
CidUser,
|
||||
@@ -1199,11 +1201,20 @@ class Resource(models.Model, AuthorMixin):
|
||||
if self.url:
|
||||
html = f"<a target='_blank' href='{self.url}'>{self.name}</a>"
|
||||
elif self.file:
|
||||
html = f"<a target='_blank' href='{self.file.url}'>{self.name}</a>"
|
||||
filetype, _ = mimetypes.guess_type(self.file.url)
|
||||
|
||||
match filetype.split("/"):
|
||||
case "image", _:
|
||||
html = f"<img src='{self.file.url}'>"
|
||||
case "video", _:
|
||||
html = f"<video controls><source src='{self.file.url}'></video>"
|
||||
|
||||
case _:
|
||||
html = f"<a target='_blank' href='{self.file.url}'>{self.name}</a>"
|
||||
else:
|
||||
html = self.name
|
||||
|
||||
return format_html(html)
|
||||
return format_html("<details class='resource-block'><summary>{}</summary>{}</details>", self.name, mark_safe(html))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
|
||||
|
||||
{% if not completed %}
|
||||
<h5>Resources</h4>
|
||||
<ul>
|
||||
{% for caseresource in resources %}
|
||||
<li>
|
||||
{{caseresource.resource.get_display}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if resources %}
|
||||
<h5>Resources</h4>
|
||||
<ul class="no-list-style">
|
||||
{% for caseresource in resources %}
|
||||
<li>
|
||||
{{caseresource.resource.get_display}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -108,14 +110,16 @@
|
||||
{% endif %}
|
||||
|
||||
{% if completed %}
|
||||
<h5>Resources</h4>
|
||||
<ul>
|
||||
{% for caseresource in resources %}
|
||||
<li>
|
||||
{{caseresource.resource.get_display}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if resources %}
|
||||
<h5>Resources</h4>
|
||||
<ul class="no-list-style">
|
||||
{% for caseresource in resources %}
|
||||
<li>
|
||||
{{caseresource.resource.get_display}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
<a href="{% url 'atlas:add_self_review' cid_user_exam.id case.id %}"><button>Add self review</button></a>
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
{% extends 'atlas/base.html' %}
|
||||
|
||||
{% load static%}
|
||||
|
||||
{% block content %}
|
||||
<h2>Upload dicoms</h2>
|
||||
User: {{user}}<br/>
|
||||
|
||||
<div role="alert" class="alert alert-warning">
|
||||
Please note this form will not annonymise files. Please ensure that you have done so prior to using it.
|
||||
</div>
|
||||
|
||||
<div>This form allows you to quickly upload dicom files to the server. Select the folder containing the dicom files below.</div>
|
||||
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="file" name="dicom_files" id="filepicker" webkitdirectory multiple>
|
||||
<input type="submit" value="Upload">
|
||||
|
||||
</form>
|
||||
|
||||
<div>Selected files:</div>
|
||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''></div>
|
||||
<ul id="listing"></ul>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'js/upload_form_helpers.js' %}"></script>
|
||||
<script>
|
||||
|
||||
function checkAnnonymisation(byteArray) {
|
||||
// We need to setup a try/catch block because parseDicom will throw an exception
|
||||
// if you attempt to parse a non dicom part 10 file (or one that is corrupted)
|
||||
try {
|
||||
console.log("bytearray", byteArray)
|
||||
// parse byteArray into a DataSet object using the parseDicom library
|
||||
var dataSet = dicomParser.parseDicom(byteArray);
|
||||
console.log("ds", dataSet)
|
||||
|
||||
// dataSet contains the parsed elements. Each element is available via a property
|
||||
// in the dataSet.elements object. The property name is based on the elements group
|
||||
// and element in the following format: xggggeeee where gggg is the group number
|
||||
// and eeee is the element number with lowercase hex characters.
|
||||
|
||||
// To access the data for an element, we need to know its type and its tag.
|
||||
// We will get the sopInstanceUid from the file which is a string and
|
||||
// has the tag (0020,000D)
|
||||
var study_description = dataSet.string('x00081030');
|
||||
var accession_number = dataSet.string('x00080050').toLowerCase();
|
||||
var patient_id = dataSet.string('x00100020').toLowerCase();
|
||||
console.log("STUDY", study_description);
|
||||
console.log("acc", accession_number);
|
||||
console.log("pid", patient_id);
|
||||
|
||||
|
||||
not_anon = false;
|
||||
|
||||
site_codes = ["ref", "rk9", "ra9", "rh8", "rbz", "rba"]
|
||||
|
||||
for (let i = 0; i < site_codes.length; i++) {
|
||||
if (
|
||||
accession_number.startsWith(site_codes[i]) ||
|
||||
patient_id.startsWith(site_codes[i]) ||
|
||||
patient_id.startsWith("pat"))
|
||||
{
|
||||
not_anon = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (not_anon) {
|
||||
toastr.warning(`File does not appear to be annonymised<br/>Accession: ${accession_number} <br/>Patient ID: ${patient_id}<br/>`, 'Anonymisation warning', {
|
||||
"closeButton": false,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toast-top-full-width",
|
||||
"preventDuplicates": false,
|
||||
"onclick": null,
|
||||
"showDuration": "0",
|
||||
"hideDuration": "0",
|
||||
"timeOut": 0,
|
||||
"extendedTimeOut": 0,
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut",
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: fix
|
||||
//$.ajax({
|
||||
// url: `{% url 'generic:examination-autocomplete' %}/${encodeURI(study_description)}`,
|
||||
// //context: document.body,
|
||||
// success: function(data){
|
||||
// console.log(data)
|
||||
// }
|
||||
//});
|
||||
|
||||
//// try to match with a study description (if not already selected)
|
||||
//if ($(`#id_examination_to option`).length < 1) {
|
||||
// option = $(`#id_examination_from option[title*='${study_description}' i]`);
|
||||
|
||||
// if (option.length) {
|
||||
// option.appendTo($("#id_examination_to"));
|
||||
// toastr.success(`Examination set to ${option.attr('title')} from dicom data`);
|
||||
// } else {
|
||||
// toastr.warning(
|
||||
// `Unable to set examination ${study_description} from dicom data (it needs creating)`);
|
||||
|
||||
// }
|
||||
//}
|
||||
return true;
|
||||
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function loadDicomViewerTest(callback) {
|
||||
console.log("load")
|
||||
$("#single-dicom-viewer").empty()
|
||||
//images = []
|
||||
//Function that returns a promise to read the file
|
||||
const reader = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => resolve(fileReader);
|
||||
fileReader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
|
||||
const readFile = (file, el) => {
|
||||
reader(file).then(reader => {
|
||||
console.log("hello", file, el, image)
|
||||
//if ($("#id_examination").find(":selected")[0].dataset.select2Id == "2") {
|
||||
// var byteArray = new Uint8Array(reader.result);
|
||||
// console.log("etrxact", reader)
|
||||
// extractDicomStudyDescription(byteArray);
|
||||
//}
|
||||
var image = new Image();
|
||||
image.height = 100;
|
||||
image.title = file.name;
|
||||
image.src = reader.result;
|
||||
image.className = "temp-thumb";
|
||||
console.log("read", el);
|
||||
$(el).append(image);
|
||||
//images.push(reader.result);
|
||||
loadViewer(images);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
const dicomReader = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => resolve(fileReader);
|
||||
fileReader.readAsArrayBuffer(file);
|
||||
});
|
||||
}
|
||||
|
||||
const readDicomFile = (file) => {
|
||||
return dicomReader(file).then(reader => {
|
||||
var byteArray = new Uint8Array(reader.result);
|
||||
console.log("etrxact", reader)
|
||||
return checkAnnonymisation(byteArray);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
file_set = document.getElementById("filepicker").files;
|
||||
|
||||
|
||||
let output = document.getElementById("listing");
|
||||
images = [];
|
||||
for (const file of file_set) {
|
||||
//await readFile(file);
|
||||
dicom = await readDicomFile(file);
|
||||
|
||||
if (dicom) {
|
||||
let item = document.createElement("li");
|
||||
item.textContent = file.webkitRelativePath;
|
||||
output.appendChild(item);
|
||||
//await readFile(file, item);
|
||||
|
||||
|
||||
let url = URL.createObjectURL(file)
|
||||
console.log(url)
|
||||
imageId = `wadouri:${url}`;
|
||||
images.push(imageId);
|
||||
|
||||
const element = $(`<div class='temp-thumb' src=${imageId}></div>`).get(0)
|
||||
item.appendChild(element);
|
||||
cornerstone.enable(element);
|
||||
cornerstone.loadAndCacheImage(imageId).then(function (image) {
|
||||
cornerstone.displayImage(element, image);
|
||||
cornerstone.resize(element)
|
||||
|
||||
|
||||
|
||||
let bytesView = image.getPixelData()
|
||||
let str = new TextDecoder("utf-8").decode(bytesView, );
|
||||
|
||||
//extractDicomDetails(image.data.byteArray)
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(images)
|
||||
|
||||
|
||||
const event = new CustomEvent('loadDicomViewerUrls', {
|
||||
"detail": {"images": images, "annontations": undefined}
|
||||
});
|
||||
|
||||
window.dispatchEvent(event);
|
||||
|
||||
|
||||
|
||||
}
|
||||
$(document).ready(function () {
|
||||
document.getElementById("filepicker").addEventListener(
|
||||
"change",
|
||||
(event) => {
|
||||
//let output = document.getElementById("listing");
|
||||
//for (const file of event.target.files) {
|
||||
// let item = document.createElement("li");
|
||||
// item.textContent = file.webkitRelativePath;
|
||||
// output.appendChild(item);
|
||||
//}
|
||||
|
||||
loadDicomViewerTest();
|
||||
},
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -1,4 +1,5 @@
|
||||
<div class="floating-header">
|
||||
<a href="{% url 'atlas:case_detail' pk=case.pk %}" title="View the Case">View</a>
|
||||
<a href="{% url 'atlas:case_update' pk=case.pk %}" title="Edit the Case">Edit</a>
|
||||
<a href="{% url 'atlas:case_clone' pk=case.pk %}"
|
||||
title="Clone the Case (duplicate everything but the images)">Clone</a>
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
author: {{resource.get_authors}}<br>
|
||||
|
||||
{{resource.case}}
|
||||
|
||||
<div>
|
||||
<a href="{% url 'atlas:resource_view' resource.pk %}" target="_blank">View Resource</a>
|
||||
</div>
|
||||
|
||||
{% if resource.case_set.all %}
|
||||
<h3>Cases</h3>
|
||||
|
||||
@@ -247,165 +247,6 @@
|
||||
//
|
||||
// }
|
||||
|
||||
function extractDicomDetails(byteArray) {
|
||||
// We need to setup a try/catch block because parseDicom will throw an exception
|
||||
// if you attempt to parse a non dicom part 10 file (or one that is corrupted)
|
||||
try {
|
||||
console.log("bytearray", byteArray)
|
||||
// parse byteArray into a DataSet object using the parseDicom library
|
||||
var dataSet = dicomParser.parseDicom(byteArray);
|
||||
console.log("ds", dataSet)
|
||||
|
||||
// dataSet contains the parsed elements. Each element is available via a property
|
||||
// in the dataSet.elements object. The property name is based on the elements group
|
||||
// and element in the following format: xggggeeee where gggg is the group number
|
||||
// and eeee is the element number with lowercase hex characters.
|
||||
|
||||
// To access the data for an element, we need to know its type and its tag.
|
||||
// We will get the sopInstanceUid from the file which is a string and
|
||||
// has the tag (0020,000D)
|
||||
var study_description = dataSet.string('x00081030');
|
||||
var accession_number = dataSet.string('x00080050').toLowerCase();
|
||||
var patient_id = dataSet.string('x00100020').toLowerCase();
|
||||
var modality = dataSet.string('x00080060');
|
||||
var projection = dataSet.string('x00185101');
|
||||
var plane = dataSet.string('x00180022').toLowerCase();
|
||||
console.log("STUDY", study_description);
|
||||
console.log("acc", accession_number);
|
||||
console.log("pid", patient_id);
|
||||
console.log("projection", projection);
|
||||
console.log("plane", plane);
|
||||
|
||||
function select_plane(option) {
|
||||
let plane_select_object = document.getElementsByName("plane")[0]
|
||||
const $options = Array.from(plane_select_object.options);
|
||||
const optionToSelect = $options.find(item => item.text === option);
|
||||
optionToSelect.selected = true;
|
||||
|
||||
}
|
||||
|
||||
if (plane.includes("axial")) {
|
||||
select_plane("axial");
|
||||
} else if (plane.includes("sagittal")) {
|
||||
select_plane("sagittal");
|
||||
} else if (plane.includes("coronal")) {
|
||||
select_plane("coronal");
|
||||
} else if (plane.includes("ap")) {
|
||||
select_plane("AP");
|
||||
} else if (plane.includes("lat") | plane.includes("lateral")) {
|
||||
select_plane("lateral");
|
||||
} else if (plane.includes("pa")) {
|
||||
select_plane("PA");
|
||||
|
||||
}
|
||||
|
||||
|
||||
modality_map = {
|
||||
"DX": "Radiograph",
|
||||
"CR": "Radiograph",
|
||||
"CT": "CT",
|
||||
"MR": "MR",
|
||||
"RF": "Fluroscopy",
|
||||
"US": "Ultrasound",
|
||||
}
|
||||
|
||||
if (modality in modality_map) {
|
||||
let modality_select_object = document.getElementsByName("modality")[0]
|
||||
const $options = Array.from(modality_select_object.options);
|
||||
const optionToSelect = $options.find(item => item.text === modality_map[modality]);
|
||||
optionToSelect.selected = true;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
toastr.info(`Unable to automatically set modality: ${modality}`);
|
||||
}
|
||||
|
||||
// If the dicom study_description contains multiple values select the first
|
||||
study_description = study_description.split(",")[0].trim();
|
||||
|
||||
to_replace = ["lt", "rt", "contrast", "LT", "RT", "Contrast"];
|
||||
|
||||
for (let i = 0; i < to_replace.length; i++) {
|
||||
|
||||
study_description = study_description.replace(to_replace[i], "");
|
||||
}
|
||||
|
||||
let select_object = document.getElementsByName("examination")[0]
|
||||
|
||||
if (select_object.value == "") {
|
||||
$.get(`${select_object.dataset.autocompleteLightUrl}?q=${study_description}`, (data) => {
|
||||
console.log(data)
|
||||
if (data.results.length==1){
|
||||
|
||||
$(select_object).select2("trigger","select", {
|
||||
data: data.results[0]
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
not_anon = false;
|
||||
|
||||
site_codes = ["ref", "rk9", "ra9", "rh8", "rbz", "rba"]
|
||||
|
||||
for (let i = 0; i < site_codes.length; i++) {
|
||||
if (
|
||||
accession_number.startsWith(site_codes[i])
|
||||
|| patient_id.startsWith(site_codes[i])) {
|
||||
not_anon = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (not_anon) {
|
||||
toastr.warning(`File does not appear to be annonymised<br/>Accession: ${accession_number} <br/>Patient ID: ${patient_id}<br/>`, 'Anonymisation warning', {
|
||||
"closeButton": false,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toast-top-full-width",
|
||||
"preventDuplicates": false,
|
||||
"onclick": null,
|
||||
"showDuration": "0",
|
||||
"hideDuration": "0",
|
||||
"timeOut": 0,
|
||||
"extendedTimeOut": 0,
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut",
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: fix
|
||||
//$.ajax({
|
||||
// url: `{% url 'generic:examination-autocomplete' %}/${encodeURI(study_description)}`,
|
||||
// //context: document.body,
|
||||
// success: function(data){
|
||||
// console.log(data)
|
||||
// }
|
||||
//});
|
||||
|
||||
//// try to match with a study description (if not already selected)
|
||||
//if ($(`#id_examination_to option`).length < 1) {
|
||||
// option = $(`#id_examination_from option[title*='${study_description}' i]`);
|
||||
|
||||
// if (option.length) {
|
||||
// option.appendTo($("#id_examination_to"));
|
||||
// toastr.success(`Examination set to ${option.attr('title')} from dicom data`);
|
||||
// } else {
|
||||
// toastr.warning(
|
||||
// `Unable to set examination ${study_description} from dicom data (it needs creating)`);
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
@@ -39,11 +39,13 @@ urlpatterns = [
|
||||
path("uploads", views.user_uploads, name="user_uploads"),
|
||||
path("uploads/<int:user_pk>/user", views.other_user_uploads, name="other_user_uploads"),
|
||||
path("uploads/all", views.all_uploads, name="all_uploads"),
|
||||
path("uploads/new", views.new_uploads, name="new_uploads"),
|
||||
path("uploads/case/<int:case_id>", views.user_uploads, name="user_uploads_case"),
|
||||
path("uploads/<int:user_pk>/user/case/<int:case_id>", views.other_user_uploads, name="other_user_uploads_case"),
|
||||
path("uploads/series_id/<str:series_instance_uid>", views.user_uploads_series, name="user_uploads_series"),
|
||||
path("resource/", views.ResourceView.as_view(), name="resource_view"),
|
||||
path("resource/<int:pk>/", views.resource_detail, name="resource_detail"),
|
||||
path("resource/<int:pk>/view", views.resource_view, name="resource_view"),
|
||||
path("resource/<int:pk>/update", views.ResourceUpdate.as_view(), name="resource_update"),
|
||||
path("resource/<int:pk>/delete", views.ResourceDelete.as_view(), name="resource_delete"),
|
||||
path(
|
||||
|
||||
@@ -370,6 +370,12 @@ def resource_detail(request, pk):
|
||||
|
||||
return render(request, "atlas/resource_detail.html", {"resource": resource})
|
||||
|
||||
@login_required
|
||||
def resource_view(request, pk):
|
||||
resource = get_object_or_404(Resource, pk=pk)
|
||||
|
||||
return HttpResponse(resource.get_display())
|
||||
|
||||
|
||||
@login_required
|
||||
def author_detail(request, pk):
|
||||
@@ -444,6 +450,9 @@ def user_uploads_series(request, series_instance_uid: str):
|
||||
{"dicoms": dicoms, "series_id": series_instance_uid},
|
||||
)
|
||||
|
||||
@login_required
|
||||
def new_uploads(request):
|
||||
return render(request, "atlas/new_uploads.html", {})
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<br/>
|
||||
{% if can_edit %}
|
||||
<a href="{% url exam.get_app_name|add:':exam_update' exam.id %}" title="Edit the Exam">Edit</a>
|
||||
<a href="{% url exam.get_app_name|add:':exam_dteail' exam.id %}" title="View the exam">Edit</a>
|
||||
\ <a href="{% url exam.get_app_name|add:':exam_update' exam.id %}" title="Edit the Exam">Edit</a>
|
||||
\ <a href="{% url exam.get_app_name|add:':exam_delete' exam.id %}" title="Delete the Exam">Delete</a>
|
||||
\ <a href="{% url exam.get_app_name|add:':exam_clone' exam.id %}" title="Clone the Exam">Clone</a>
|
||||
\ <a href="{% url exam.get_app_name|add:':exam_authors' exam.id %}" title="Edit Exam Authors">Authors</a>
|
||||
|
||||
@@ -1109,4 +1109,17 @@ tr:has(> td > a) {
|
||||
padding: 0;
|
||||
text-decoration: underline;
|
||||
color: #3282b8;
|
||||
}
|
||||
|
||||
.resource-block {
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.resource-block video {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.no-list-style {
|
||||
list-style-type: none;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
Reference in New Issue
Block a user