comparison OrthancServer/OrthancExplorer/explorer.js @ 4697:569d9ef165b1

Added "short", "simplify" and/or "full" options to control the format of DICOM tags wherever possible
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 18 Jun 2021 16:08:35 +0200
parents 8262ffb393ff
children f0038043fb97 283d246fafdb
comparison
equal deleted inserted replaced
4696:dd6274412ff4 4697:569d9ef165b1
49 var LIMIT_RESOURCES = 100; 49 var LIMIT_RESOURCES = 100;
50 50
51 var currentPage = ''; 51 var currentPage = '';
52 var currentUuid = ''; 52 var currentUuid = '';
53 53
54 var ACQUISITION_NUMBER = '0020,0012';
55 var IMAGES_IN_ACQUISITION = '0020,1002';
56 var IMAGE_ORIENTATION_PATIENT = '0020,0037';
57 var IMAGE_POSITION_PATIENT = '0020,0032';
58 var INSTANCE_CREATION_DATE = '0008,0012';
59 var INSTANCE_CREATION_TIME = '0008,0013';
60 var INSTANCE_NUMBER = '0020,0013';
61 var MANUFACTURER = '0008,0070';
62 var OTHER_PATIENT_IDS = '0010,1000';
63 var PATIENT_BIRTH_DATE = '0010,0030';
64 var PATIENT_NAME = '0010,0010';
65 var SERIES_DATE = '0008,0021';
66 var SERIES_DESCRIPTION = '0008,103e';
67 var SERIES_INSTANCE_UID = '0020,000e';
68 var SERIES_TIME = '0008,0031';
69 var SOP_INSTANCE_UID = '0008,0018';
70 var STUDY_DATE = '0008,0020';
71 var STUDY_DESCRIPTION = '0008,1030';
72 var STUDY_INSTANCE_UID = '0020,000d';
73 var STUDY_TIME = '0008,0030';
74
75 var ANONYMIZED_FROM = 'AnonymizedFrom';
76 var MODIFIED_FROM = 'ModifiedFrom';
77
54 78
55 function DeepCopy(obj) 79 function DeepCopy(obj)
56 { 80 {
57 return jQuery.extend(true, {}, obj); 81 return jQuery.extend(true, {}, obj);
58 } 82 }
156 headers : authorizationTokens 180 headers : authorizationTokens
157 } 181 }
158 ); 182 );
159 183
160 184
161 function SplitLongUid(s)
162 {
163 return '<span>' + s.substr(0, s.length / 2) + '</span> <span>' + s.substr(s.length / 2, s.length - s.length / 2) + '</span>';
164 }
165
166
167 function ParseDicomDate(s) 185 function ParseDicomDate(s)
168 { 186 {
169 y = parseInt(s.substr(0, 4), 10); 187 y = parseInt(s.substr(0, 4), 10);
170 m = parseInt(s.substr(4, 2), 10) - 1; 188 m = parseInt(s.substr(4, 2), 10) - 1;
171 d = parseInt(s.substr(6, 2), 10); 189 d = parseInt(s.substr(6, 2), 10);
257 return order; 275 return order;
258 }); 276 });
259 } 277 }
260 278
261 279
280 function GetMainDicomTag(mainDicomTags, tag)
281 {
282 if (tag in mainDicomTags) {
283 return mainDicomTags[tag].Value;
284 } else {
285 return '';
286 }
287 }
288
289
262 function SortOnDicomTag(arr, tag, isInteger, reverse) 290 function SortOnDicomTag(arr, tag, isInteger, reverse)
263 { 291 {
264 return Sort(arr, function(a) { 292 return Sort(arr, function(a) {
265 return a.MainDicomTags[tag]; 293 return GetMainDicomTag(a.MainDicomTags, tag);
266 }, isInteger, reverse); 294 }, isInteger, reverse);
267 } 295 }
268 296
269 297
270 298
289 node = node.add($('<span>') 317 node = node.add($('<span>')
290 .addClass('ui-li-count') 318 .addClass('ui-li-count')
291 .text(count)); 319 .text(count));
292 } 320 }
293 321
294 if (link != null) 322 if (link != null &&
323 link)
295 { 324 {
296 node = $('<a>').attr('href', link).append(node); 325 node = $('<a>').attr('href', link).append(node);
297 326
298 if (isReverse) 327 if (isReverse)
299 node.attr('data-direction', 'reverse') 328 node.attr('data-direction', 'reverse')
314 343
315 for (var i in tags) 344 for (var i in tags)
316 { 345 {
317 if (tagsToIgnore.indexOf(i) == -1) 346 if (tagsToIgnore.indexOf(i) == -1)
318 { 347 {
319 v = tags[i]; 348 v = GetMainDicomTag(tags, i);
320 349
321 if (i == "PatientBirthDate" || 350 if (i == PATIENT_BIRTH_DATE ||
322 i == "StudyDate" || 351 i == STUDY_DATE ||
323 i == "SeriesDate") 352 i == SERIES_DATE ||
353 i == INSTANCE_CREATION_DATE)
324 { 354 {
325 v = FormatDicomDate(v); 355 v = FormatDicomDate(v);
326 } 356 }
327 else if (i == "DicomStudyInstanceUID" || 357 else if (i == STUDY_INSTANCE_UID ||
328 i == "DicomSeriesInstanceUID") 358 i == SERIES_INSTANCE_UID ||
359 i == SOP_INSTANCE_UID)
329 { 360 {
330 v = SplitLongUid(v); 361 // Possibly split a long UID
331 } 362 // v = '<span>' + s.substr(0, s.length / 2) + '</span><span>' + s.substr(s.length / 2, s.length - s.length / 2) + '</span>';
332 else if (i == "ImagePositionPatient" || 363 }
333 i == "ImageOrientationPatient") 364 else if (i == IMAGE_POSITION_PATIENT ||
365 i == IMAGE_ORIENTATION_PATIENT)
334 { 366 {
335 v = FormatFloatSequence(v); 367 v = FormatFloatSequence(v);
336 } 368 }
337 369
338 target.append($('<p>') 370 target.append($('<p>')
339 .text(i + ': ') 371 .text(tags[i].Name + ': ')
340 .append($('<strong>').text(v))); 372 .append($('<strong>').html(v)));
341 } 373 }
342 } 374 }
343 } 375 }
344 376
345 377
346 function FormatPatient(patient, link, isReverse) 378 function FormatPatient(patient, link, isReverse)
347 { 379 {
348 var node = $('<div>').append($('<h3>').text(patient.MainDicomTags.PatientName)); 380 var node = $('<div>').append($('<h3>').text(GetMainDicomTag(patient.MainDicomTags, PATIENT_NAME)));
349 381
350 FormatMainDicomTags(node, patient.MainDicomTags, [ 382 FormatMainDicomTags(node, patient.MainDicomTags, [
351 "PatientName" 383 PATIENT_NAME
352 // "OtherPatientIDs" 384 //, OTHER_PATIENT_IDS
353 ]); 385 ]);
354 386
355 return CompleteFormatting(node, link, isReverse, patient.Studies.length); 387 return CompleteFormatting(node, link, isReverse, patient.Studies.length);
356 } 388 }
357 389
363 var node; 395 var node;
364 396
365 if (includePatient) { 397 if (includePatient) {
366 label = study.Label; 398 label = study.Label;
367 } else { 399 } else {
368 label = study.MainDicomTags.StudyDescription; 400 label = GetMainDicomTag(study.MainDicomTags, STUDY_DESCRIPTION);
369 } 401 }
370 402
371 node = $('<div>').append($('<h3>').text(label)); 403 node = $('<div>').append($('<h3>').text(label));
372 404
373 if (includePatient) { 405 if (includePatient) {
374 FormatMainDicomTags(node, study.PatientMainDicomTags, [ 406 FormatMainDicomTags(node, study.PatientMainDicomTags, [
375 'PatientName' 407 PATIENT_NAME
376 ]); 408 ]);
377 } 409 }
378 410
379 FormatMainDicomTags(node, study.MainDicomTags, [ 411 FormatMainDicomTags(node, study.MainDicomTags, [
380 'StudyDescription', 412 STUDY_DESCRIPTION,
381 'StudyTime' 413 STUDY_TIME
382 ]); 414 ]);
383 415
384 return CompleteFormatting(node, link, isReverse, study.Series.length); 416 return CompleteFormatting(node, link, isReverse, study.Series.length);
385 } 417 }
386 418
400 { 432 {
401 c = series.Instances.length + '/' + series.ExpectedNumberOfInstances; 433 c = series.Instances.length + '/' + series.ExpectedNumberOfInstances;
402 } 434 }
403 435
404 node = $('<div>') 436 node = $('<div>')
405 .append($('<h3>').text(series.MainDicomTags.SeriesDescription)) 437 .append($('<h3>').text(GetMainDicomTag(series.MainDicomTags, SERIES_DESCRIPTION)))
406 .append($('<p>').append($('<em>') 438 .append($('<p>').append($('<em>')
407 .text('Status: ') 439 .text('Status: ')
408 .append($('<strong>').text(series.Status)))); 440 .append($('<strong>').text(series.Status))));
409 441
410 FormatMainDicomTags(node, series.MainDicomTags, [ 442 FormatMainDicomTags(node, series.MainDicomTags, [
411 "SeriesDescription", 443 SERIES_DESCRIPTION,
412 "SeriesTime", 444 SERIES_TIME,
413 "Manufacturer", 445 MANUFACTURER,
414 "ImagesInAcquisition", 446 IMAGES_IN_ACQUISITION,
415 "SeriesDate", 447 SERIES_DATE,
416 "ImageOrientationPatient" 448 IMAGE_ORIENTATION_PATIENT
417 ]); 449 ]);
418 450
419 return CompleteFormatting(node, link, isReverse, c); 451 return CompleteFormatting(node, link, isReverse, c);
420 } 452 }
421 453
423 function FormatInstance(instance, link, isReverse) 455 function FormatInstance(instance, link, isReverse)
424 { 456 {
425 var node = $('<div>').append($('<h3>').text('Instance: ' + instance.IndexInSeries)); 457 var node = $('<div>').append($('<h3>').text('Instance: ' + instance.IndexInSeries));
426 458
427 FormatMainDicomTags(node, instance.MainDicomTags, [ 459 FormatMainDicomTags(node, instance.MainDicomTags, [
428 "AcquisitionNumber", 460 ACQUISITION_NUMBER,
429 "InstanceNumber", 461 INSTANCE_NUMBER,
430 "InstanceCreationDate", 462 INSTANCE_CREATION_DATE,
431 "InstanceCreationTime" 463 INSTANCE_CREATION_TIME,
432 ]); 464 ]);
433 465
434 return CompleteFormatting(node, link, isReverse); 466 return CompleteFormatting(node, link, isReverse);
435 } 467 }
436 468
532 return false; 564 return false;
533 }); 565 });
534 566
535 567
536 $('#find-patients').live('pagebeforeshow', function() { 568 $('#find-patients').live('pagebeforeshow', function() {
537 GetResource('/patients?expand&since=0&limit=' + (LIMIT_RESOURCES + 1), function(patients) { 569 GetResource('/patients?expand&since=0&limit=' + (LIMIT_RESOURCES + 1) + '&full', function(patients) {
538 var target = $('#all-patients'); 570 var target = $('#all-patients');
539 var count, showAlert, p; 571 var count, showAlert, p;
540 572
541 573
542 $('li', target).remove(); 574 $('li', target).remove();
543 575
544 SortOnDicomTag(patients, 'PatientName', false, false); 576 SortOnDicomTag(patients, PATIENT_NAME, false, false);
545 577
546 if (patients.length <= LIMIT_RESOURCES) { 578 if (patients.length <= LIMIT_RESOURCES) {
547 count = patients.length; 579 count = patients.length;
548 showAlert = false; 580 showAlert = false;
549 } 581 }
577 var count, showAlert; 609 var count, showAlert;
578 610
579 $('li', target).remove(); 611 $('li', target).remove();
580 612
581 for (var i = 0; i < studies.length; i++) { 613 for (var i = 0; i < studies.length; i++) {
582 patient = studies[i].PatientMainDicomTags.PatientName; 614 patient = GetMainDicomTag(studies[i].PatientMainDicomTags, PATIENT_NAME);
583 study = studies[i].MainDicomTags.StudyDescription; 615 study = GetMainDicomTag(studies[i].MainDicomTags, STUDY_DESCRIPTION);
584 616
585 s = ""; 617 s = "";
586 if (typeof patient === 'string') { 618 if (typeof patient === 'string') {
587 s = patient; 619 s = patient;
588 } 620 }
624 } 656 }
625 } 657 }
626 658
627 659
628 $('#find-studies').live('pagebeforeshow', function() { 660 $('#find-studies').live('pagebeforeshow', function() {
629 GetResource('/studies?expand&since=0&limit=' + (LIMIT_RESOURCES + 1), function(studies) { 661 GetResource('/studies?expand&since=0&limit=' + (LIMIT_RESOURCES + 1) + '&full', function(studies) {
630 FormatListOfStudies('#all-studies', '#alert-studies', '#count-studies', studies); 662 FormatListOfStudies('#all-studies', '#alert-studies', '#count-studies', studies);
631 }); 663 });
632 }); 664 });
633 665
634 666
655 var pageData, target, v; 687 var pageData, target, v;
656 688
657 if ($.mobile.pageData) { 689 if ($.mobile.pageData) {
658 pageData = DeepCopy($.mobile.pageData); 690 pageData = DeepCopy($.mobile.pageData);
659 691
660 GetResource('/patients/' + pageData.uuid, function(patient) { 692 GetResource('/patients/' + pageData.uuid + '?full', function(patient) {
661 GetResource('/patients/' + pageData.uuid + '/studies', function(studies) { 693 GetResource('/patients/' + pageData.uuid + '/studies?full', function(studies) {
662 SortOnDicomTag(studies, 'StudyDate', false, true); 694 SortOnDicomTag(studies, STUDY_DATE, false, true);
663 695
664 $('#patient-info li').remove(); 696 $('#patient-info li').remove();
665 $('#patient-info') 697 $('#patient-info')
666 .append('<li data-role="list-divider">Patient</li>') 698 .append('<li data-role="list-divider">Patient</li>')
667 .append(FormatPatient(patient)) 699 .append(FormatPatient(patient))
669 701
670 target = $('#list-studies'); 702 target = $('#list-studies');
671 $('li', target).remove(); 703 $('li', target).remove();
672 704
673 for (var i = 0; i < studies.length; i++) { 705 for (var i = 0; i < studies.length; i++) {
674 if (i == 0 || studies[i].MainDicomTags.StudyDate != studies[i - 1].MainDicomTags.StudyDate) 706 if (i == 0 ||
707 GetMainDicomTag(studies[i].MainDicomTags, STUDY_DATE) !=
708 GetMainDicomTag(studies[i - 1].MainDicomTags, STUDY_DATE))
675 { 709 {
676 target.append($('<li>') 710 target.append($('<li>')
677 .attr('data-role', 'list-divider') 711 .attr('data-role', 'list-divider')
678 .text(FormatDicomDate(studies[i].MainDicomTags.StudyDate))); 712 .text(FormatDicomDate(GetMainDicomTag(studies[i].MainDicomTags, STUDY_DATE))));
679 } 713 }
680 714
681 target.append(FormatStudy(studies[i], '#study?uuid=' + studies[i].ID)); 715 target.append(FormatStudy(studies[i], '#study?uuid=' + studies[i].ID));
682 } 716 }
683 717
684 SetupAnonymizedOrModifiedFrom('#patient-anonymized-from', patient, 'patient', 'AnonymizedFrom'); 718 SetupAnonymizedOrModifiedFrom('#patient-anonymized-from', patient, 'patient', ANONYMIZED_FROM);
685 SetupAnonymizedOrModifiedFrom('#patient-modified-from', patient, 'patient', 'ModifiedFrom'); 719 SetupAnonymizedOrModifiedFrom('#patient-modified-from', patient, 'patient', MODIFIED_FROM);
686 720
687 target.listview('refresh'); 721 target.listview('refresh');
688 722
689 // Check whether this patient is protected 723 // Check whether this patient is protected
690 $.ajax({ 724 $.ajax({
712 var pageData, target; 746 var pageData, target;
713 747
714 if ($.mobile.pageData) { 748 if ($.mobile.pageData) {
715 pageData = DeepCopy($.mobile.pageData); 749 pageData = DeepCopy($.mobile.pageData);
716 750
717 GetResource('/studies/' + pageData.uuid, function(study) { 751 GetResource('/studies/' + pageData.uuid + '?full', function(study) {
718 GetResource('/patients/' + study.ParentPatient, function(patient) { 752 GetResource('/patients/' + study.ParentPatient + '?full', function(patient) {
719 GetResource('/studies/' + pageData.uuid + '/series', function(series) { 753 GetResource('/studies/' + pageData.uuid + '/series?full', function(series) {
720 SortOnDicomTag(series, 'SeriesDate', false, true); 754 SortOnDicomTag(series, SERIES_DATE, false, true);
721 755
722 $('#study .patient-link').attr('href', '#patient?uuid=' + patient.ID); 756 $('#study .patient-link').attr('href', '#patient?uuid=' + patient.ID);
723 $('#study-info li').remove(); 757 $('#study-info li').remove();
724 $('#study-info') 758 $('#study-info')
725 .append('<li data-role="list-divider">Patient</li>') 759 .append('<li data-role="list-divider">Patient</li>')
726 .append(FormatPatient(patient, '#patient?uuid=' + patient.ID, true)) 760 .append(FormatPatient(patient, '#patient?uuid=' + patient.ID, true))
727 .append('<li data-role="list-divider">Study</li>') 761 .append('<li data-role="list-divider">Study</li>')
728 .append(FormatStudy(study)) 762 .append(FormatStudy(study))
729 .listview('refresh'); 763 .listview('refresh');
730 764
731 SetupAnonymizedOrModifiedFrom('#study-anonymized-from', study, 'study', 'AnonymizedFrom'); 765 SetupAnonymizedOrModifiedFrom('#study-anonymized-from', study, 'study', ANONYMIZED_FROM);
732 SetupAnonymizedOrModifiedFrom('#study-modified-from', study, 'study', 'ModifiedFrom'); 766 SetupAnonymizedOrModifiedFrom('#study-modified-from', study, 'study', MODIFIED_FROM);
733 767
734 target = $('#list-series'); 768 target = $('#list-series');
735 $('li', target).remove(); 769 $('li', target).remove();
736 for (var i = 0; i < series.length; i++) { 770 for (var i = 0; i < series.length; i++) {
737 if (i == 0 || series[i].MainDicomTags.SeriesDate != series[i - 1].MainDicomTags.SeriesDate) 771 if (i == 0 ||
772 GetMainDicomTag(series[i].MainDicomTags, SERIES_DATE) !=
773 GetMainDicomTag(series[i - 1].MainDicomTags, SERIES_DATE))
738 { 774 {
739 target.append($('<li>') 775 target.append($('<li>')
740 .attr('data-role', 'list-divider') 776 .attr('data-role', 'list-divider')
741 .text(FormatDicomDate(series[i].MainDicomTags.SeriesDate))); 777 .text(FormatDicomDate(GetMainDicomTag(series[i].MainDicomTags, SERIES_DATE))));
742 } 778 }
743 779
744 target.append(FormatSeries(series[i], '#series?uuid=' + series[i].ID)); 780 target.append(FormatSeries(series[i], '#series?uuid=' + series[i].ID));
745 } 781 }
746 target.listview('refresh'); 782 target.listview('refresh');
759 var pageData, target; 795 var pageData, target;
760 796
761 if ($.mobile.pageData) { 797 if ($.mobile.pageData) {
762 pageData = DeepCopy($.mobile.pageData); 798 pageData = DeepCopy($.mobile.pageData);
763 799
764 GetResource('/series/' + pageData.uuid, function(series) { 800 GetResource('/series/' + pageData.uuid + '?full', function(series) {
765 GetResource('/studies/' + series.ParentStudy, function(study) { 801 GetResource('/studies/' + series.ParentStudy + '?full', function(study) {
766 GetResource('/patients/' + study.ParentPatient, function(patient) { 802 GetResource('/patients/' + study.ParentPatient + '?full', function(patient) {
767 GetResource('/series/' + pageData.uuid + '/instances', function(instances) { 803 GetResource('/series/' + pageData.uuid + '/instances?full', function(instances) {
768 Sort(instances, function(x) { return x.IndexInSeries; }, true, false); 804 Sort(instances, function(x) { return x.IndexInSeries; }, true, false);
769 805
770 $('#series .patient-link').attr('href', '#patient?uuid=' + patient.ID); 806 $('#series .patient-link').attr('href', '#patient?uuid=' + patient.ID);
771 $('#series .study-link').attr('href', '#study?uuid=' + study.ID); 807 $('#series .study-link').attr('href', '#study?uuid=' + study.ID);
772 808
778 .append(FormatStudy(study, '#study?uuid=' + study.ID, true)) 814 .append(FormatStudy(study, '#study?uuid=' + study.ID, true))
779 .append('<li data-role="list-divider">Series</li>') 815 .append('<li data-role="list-divider">Series</li>')
780 .append(FormatSeries(series)) 816 .append(FormatSeries(series))
781 .listview('refresh'); 817 .listview('refresh');
782 818
783 SetupAnonymizedOrModifiedFrom('#series-anonymized-from', series, 'series', 'AnonymizedFrom'); 819 SetupAnonymizedOrModifiedFrom('#series-anonymized-from', series, 'series', ANONYMIZED_FROM);
784 SetupAnonymizedOrModifiedFrom('#series-modified-from', series, 'series', 'ModifiedFrom'); 820 SetupAnonymizedOrModifiedFrom('#series-modified-from', series, 'series', MODIFIED_FROM);
785 821
786 target = $('#list-instances'); 822 target = $('#list-instances');
787 $('li', target).remove(); 823 $('li', target).remove();
788 for (var i = 0; i < instances.length; i++) { 824 for (var i = 0; i < instances.length; i++) {
789 target.append(FormatInstance(instances[i], '#instance?uuid=' + instances[i].ID)); 825 target.append(FormatInstance(instances[i], '#instance?uuid=' + instances[i].ID));
878 var pageData; 914 var pageData;
879 915
880 if ($.mobile.pageData) { 916 if ($.mobile.pageData) {
881 pageData = DeepCopy($.mobile.pageData); 917 pageData = DeepCopy($.mobile.pageData);
882 918
883 GetResource('/instances/' + pageData.uuid, function(instance) { 919 GetResource('/instances/' + pageData.uuid + '?full', function(instance) {
884 GetResource('/series/' + instance.ParentSeries, function(series) { 920 GetResource('/series/' + instance.ParentSeries + '?full', function(series) {
885 GetResource('/studies/' + series.ParentStudy, function(study) { 921 GetResource('/studies/' + series.ParentStudy + '?full', function(study) {
886 GetResource('/patients/' + study.ParentPatient, function(patient) { 922 GetResource('/patients/' + study.ParentPatient + '?full', function(patient) {
887 923
888 $('#instance .patient-link').attr('href', '#patient?uuid=' + patient.ID); 924 $('#instance .patient-link').attr('href', '#patient?uuid=' + patient.ID);
889 $('#instance .study-link').attr('href', '#study?uuid=' + study.ID); 925 $('#instance .study-link').attr('href', '#study?uuid=' + study.ID);
890 $('#instance .series-link').attr('href', '#series?uuid=' + series.ID); 926 $('#instance .series-link').attr('href', '#series?uuid=' + series.ID);
891 927
916 $('#transfer-syntax').show(); 952 $('#transfer-syntax').show();
917 $('#transfer-syntax-text').text(transferSyntax); 953 $('#transfer-syntax-text').text(transferSyntax);
918 } 954 }
919 }); 955 });
920 956
921 SetupAnonymizedOrModifiedFrom('#instance-anonymized-from', instance, 'instance', 'AnonymizedFrom'); 957 SetupAnonymizedOrModifiedFrom('#instance-anonymized-from', instance, 'instance', ANONYMIZED_FROM);
922 SetupAnonymizedOrModifiedFrom('#instance-modified-from', instance, 'instance', 'ModifiedFrom'); 958 SetupAnonymizedOrModifiedFrom('#instance-modified-from', instance, 'instance', MODIFIED_FROM);
923 959
924 currentPage = 'instance'; 960 currentPage = 'instance';
925 currentUuid = pageData.uuid; 961 currentUuid = pageData.uuid;
926 }); 962 });
927 }); 963 });