add a few more anon checks

This commit is contained in:
Ross
2024-10-21 13:27:22 +01:00
parent eeaa345f3c
commit bfe5be807e
+41 -29
View File
@@ -22,7 +22,7 @@
</details> </details>
<details> <details>
<summary>Settings</summary> <summary>Settings</summary>
<input type="checkbox" id="check-annonymisation-ocr" checked><label for="check-annonymisation-ocr">Check for annonymisation (OCR)</label> <input type="checkbox" id="check-annonymisation-ocr"><label for="check-annonymisation-ocr">Check for annonymisation (OCR)</label>
<input type="checkbox" id="show-thumbnails"><label for="Show thumbnails">Show thumbnails</label> <input type="checkbox" id="show-thumbnails"><label for="Show thumbnails">Show thumbnails</label>
<input type="checkbox" id="show-viewer"><label for="Show Viewer">Show viewer</label> <input type="checkbox" id="show-viewer"><label for="Show Viewer">Show viewer</label>
</details> </details>
@@ -47,6 +47,15 @@
</div> </div>
</details> </details>
<div class="alert alert-warning hide anon-alert" role="alert">
<p>The system has detected files that do not appear to be annonymised. These have been highlighted below.</p>
<p>If you believe this is a false positive please contact ross.kruger@nhs.net with details about the file that has been flagged.</p>
<details><summary>Override annonymisation check</summary>
<p>By clicking the button below you can override the annonymisation check and upload the files anyway. Only do this if you are sure this is a false positive.</p>
<button id="override-anon" _="on click remove @disabled from #uploadButton then alert('Upload enabled')">Override annonymisation check</button>
</div>
<h4>Selected files:</h4> <h4>Selected files:</h4>
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''></div> <div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''></div>
@@ -116,15 +125,12 @@
} }
function uploadFiles(files_to_upload, current_chunk, total_chunks){ function uploadFiles(files_to_upload, current_chunk, total_chunks){
console.log("uploading", files_to_upload)
// Create a FormData object to store the form data // Create a FormData object to store the form data
const formData = new FormData(); const formData = new FormData();
// Append each selected file to the FormData object // Append each selected file to the FormData object
for (let i = 0; i < files_to_upload.length; i++) { for (let i = 0; i < files_to_upload.length; i++) {
formData.append("files", files_to_upload[i]); formData.append("files", files_to_upload[i]);
} }
console.log("formdata", formData)
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open("POST", "{% url 'api-1:upload_dicom' %}", true); xhr.open("POST", "{% url 'api-1:upload_dicom' %}", true);
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}"); xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
@@ -134,8 +140,6 @@
window.upload_count += 1; window.upload_count += 1;
if (xhr.status === 200) { if (xhr.status === 200) {
// Handle successful response from the server // Handle successful response from the server
console.log('Files uploaded successfully!');
console.log(xhr.response);
window.upload_results["uploaded"].push(...JSON.parse(xhr.response)["uploaded"]); window.upload_results["uploaded"].push(...JSON.parse(xhr.response)["uploaded"]);
window.upload_results["duplicates"].push(...JSON.parse(xhr.response)["duplicates"]); window.upload_results["duplicates"].push(...JSON.parse(xhr.response)["duplicates"]);
window.upload_results["failed"].push(...JSON.parse(xhr.response)["failed"]); window.upload_results["failed"].push(...JSON.parse(xhr.response)["failed"]);
@@ -180,14 +184,12 @@
xhr.send(formData); xhr.send(formData);
} }
function checkAnnonymisation(byteArray) { function checkAnnonymisation(byteArray, file) {
// We need to setup a try/catch block because parseDicom will throw an exception // 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) // if you attempt to parse a non dicom part 10 file (or one that is corrupted)
try { try {
console.log("bytearray", byteArray)
// parse byteArray into a DataSet object using the parseDicom library // parse byteArray into a DataSet object using the parseDicom library
var dataSet = dicomParser.parseDicom(byteArray); var dataSet = dicomParser.parseDicom(byteArray);
console.log("ds", dataSet)
// dataSet contains the parsed elements. Each element is available via a property // 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 // in the dataSet.elements object. The property name is based on the elements group
@@ -200,24 +202,25 @@
var study_description = dataSet.string('x00081030'); var study_description = dataSet.string('x00081030');
var accession_number = dataSet.string('x00080050').toLowerCase(); var accession_number = dataSet.string('x00080050').toLowerCase();
var patient_id = dataSet.string('x00100020').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; not_anon = false;
site_codes = ["ref", "rk9", "ra9", "rh8", "rbz", "rba"] site_codes = ["ref", "rk9", "ra9", "rh8", "rbz", "rba"]
errors = []
for (let i = 0; i < site_codes.length; i++) { for (let i = 0; i < site_codes.length; i++) {
if ( if ( accession_number.startsWith(site_codes[i]))
accession_number.startsWith(site_codes[i]) ||
patient_id.startsWith(site_codes[i])
)
{ {
not_anon = true; not_anon = true;
errors.push(`Accession number starts with ${site_codes[i]} (${accession_number})`);
}
if ( patient_id.startsWith(site_codes[i]))
{
not_anon = true;
errors.push(`Patient ID starts with ${site_codes[i]} (${patient_id})`);
} }
} }
console.log(errors)
if (not_anon) { if (not_anon) {
toastr.warning(`File does not appear to be annonymised<br/>Accession: ${accession_number} <br/>Patient ID: ${patient_id}<br/>`, 'Anonymisation warning', { toastr.warning(`File does not appear to be annonymised<br/>Accession: ${accession_number} <br/>Patient ID: ${patient_id}<br/>`, 'Anonymisation warning', {
@@ -237,7 +240,16 @@
"showMethod": "fadeIn", "showMethod": "fadeIn",
"hideMethod": "fadeOut", "hideMethod": "fadeOut",
}); });
$("uploadButton").prop("disabled", true); $("#uploadButton").prop("disabled", true);
$(".anon-alert").show();
setTimeout(
function(errors) {
console.log(errors)
// We delay this a few seconds otherwise it does not work
$(`.dicom-file[data-path='${file.webkitRelativePath}']`).addClass("image-ident-warning").append($(`<div>${errors.join("<br/>")}</div>`));
}, 2000, errors
)
} }
// TODO: fix // TODO: fix
@@ -269,7 +281,8 @@
return false; return false;
} }
} }
async function loadDicomViewerTest(callback) { async function loadDicomViewerUploads(callback) {
$("#uploadButton").attr("disabled", false);
$("#single-dicom-viewer").hide(); $("#single-dicom-viewer").hide();
console.log("load") console.log("load")
$("#single-dicom-viewer").empty() $("#single-dicom-viewer").empty()
@@ -285,7 +298,6 @@
const readFile = (file, el) => { const readFile = (file, el) => {
reader(file).then(reader => { reader(file).then(reader => {
console.log("hello", file, el, image)
//if ($("#id_examination").find(":selected")[0].dataset.select2Id == "2") { //if ($("#id_examination").find(":selected")[0].dataset.select2Id == "2") {
// var byteArray = new Uint8Array(reader.result); // var byteArray = new Uint8Array(reader.result);
// console.log("etrxact", reader) // console.log("etrxact", reader)
@@ -296,7 +308,6 @@
image.title = file.name; image.title = file.name;
image.src = reader.result; image.src = reader.result;
image.className = "temp-thumb"; image.className = "temp-thumb";
console.log("read", el);
$(el).append(image); $(el).append(image);
//images.push(reader.result); //images.push(reader.result);
loadViewer(images); loadViewer(images);
@@ -315,8 +326,7 @@
const readDicomFile = (file) => { const readDicomFile = (file) => {
return dicomReader(file).then(reader => { return dicomReader(file).then(reader => {
var byteArray = new Uint8Array(reader.result); var byteArray = new Uint8Array(reader.result);
console.log("etrxact", reader) return checkAnnonymisation(byteArray, file);
return checkAnnonymisation(byteArray);
}); });
} }
@@ -341,12 +351,12 @@
let item = document.createElement("li"); let item = document.createElement("li");
item.className = "dicom-file"; item.className = "dicom-file";
item.textContent = file.webkitRelativePath; item.textContent = file.webkitRelativePath;
item.dataset.path = file.webkitRelativePath;
output.appendChild(item); output.appendChild(item);
//await readFile(file, item); //await readFile(file, item);
let url = URL.createObjectURL(file) let url = URL.createObjectURL(file)
console.log(url)
imageId = `wadouri:${url}`; imageId = `wadouri:${url}`;
if ($("#show-viewer").is(":checked")) { if ($("#show-viewer").is(":checked")) {
images.push(imageId); images.push(imageId);
@@ -384,8 +394,6 @@
} }
} }
console.log(images)
const event = new CustomEvent('loadDicomViewerUrls', { const event = new CustomEvent('loadDicomViewerUrls', {
"detail": {"images": images, "annontations": undefined} "detail": {"images": images, "annontations": undefined}
@@ -401,7 +409,6 @@
} }
function ocr(url, input) { function ocr(url, input) {
console.log("OCR", input)
Tesseract.recognize( Tesseract.recognize(
url, url,
'eng', 'eng',
@@ -414,7 +421,6 @@
l = text.toLowerCase(); l = text.toLowerCase();
uploading_el = $(`img[data-input-id='${input.id}'], div[data-input-id='${input.id}']`) uploading_el = $(`img[data-input-id='${input.id}'], div[data-input-id='${input.id}']`)
uploading_el.removeClass("image-ident-loading"); uploading_el.removeClass("image-ident-loading");
console.log("found text", l);
if (l.includes("accession") || l.includes("number") || l.search( if (l.includes("accession") || l.includes("number") || l.search(
/(ref|rk9|rh8|ra9|rbz)\d+/g) > -1) { /(ref|rk9|rh8|ra9|rbz)\d+/g) > -1) {
console.log("Match found ", input); console.log("Match found ", input);
@@ -457,7 +463,7 @@
// output.appendChild(item); // output.appendChild(item);
//} //}
loadDicomViewerTest(); loadDicomViewerUploads();
}, },
false, false,
); );
@@ -469,4 +475,10 @@
}); });
</script> </script>
<script type="text/hyperscript">
init
add @disabled to #uploadButton
end
</script>
{% endblock %} {% endblock %}