OHIF-285/OHIF-274: Fix default hanging of display sets into the ViewportGrid (#1917)

* OHIF-285/OHIF-274: Fix default hanging of display sets into the ViewportGrid

Co-authored-by: James A. Petts <jamesapetts@gmail.com>
This commit is contained in:
Erik ZieglerandJames A. Petts authored and GitHub committed 2020-07-24 12:51:57 +02:00
1 parent 9df57e7f7f
commit 55cf9f2306
33 files changed
+548 -208

No files matched your search

+3
View File
@@ -34,6 +34,7 @@ import {
ToolBarSerivce, // TODO: Typo
MeasurementService,
ViewportGridService,
HangingProtocolService,
} from './services';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
@@ -80,6 +81,7 @@ const OHIF = {
MeasurementService,
ToolBarSerivce, // TODO: TYPO
ViewportGridService,
HangingProtocolService,
IWebApiDataSource,
DicomMetadataStore,
//
@@ -123,6 +125,7 @@ export {
MeasurementService,
ToolBarSerivce,
ViewportGridService,
HangingProtocolService,
IWebApiDataSource,
DicomMetadataStore,
ViewModelProvider,
@@ -72,7 +72,7 @@ const BaseImplementation = {
study = _model.studies[_model.studies.length - 1];
}
study.addSeries(instances);
study.addInstancesToSeries(instances);
// Broadcast an event even if we used cached data.
// This is because the mode needs to listen to instances that are added to build up its active displaySets.
@@ -83,6 +83,24 @@ const BaseImplementation = {
SeriesInstanceUID,
});
},
addSeriesMetadata(seriesSummaryMetadata) {
const { StudyInstanceUID } = seriesSummaryMetadata[0];
let study = _getStudy(StudyInstanceUID);
if (!study) {
study = createStudyMetadata(StudyInstanceUID);
_model.studies.push(study);
}
seriesSummaryMetadata.forEach(series => {
const { SeriesInstanceUID } = series;
study.setSeriesMetadata(SeriesInstanceUID, series);
});
this._broadcastEvent(EVENTS.SERIES_ADDED, {
StudyInstanceUID,
});
},
addStudy(study) {
const { StudyInstanceUID } = study;
@@ -1,5 +1,6 @@
const EVENTS = {
INSTANCES_ADDED: 'event::dicomMetadataStore:instancesAdded',
SERIES_ADDED: 'event::dicomMetadataStore:seriesAdded',
};
export default EVENTS;
@@ -10,19 +10,31 @@ function createStudyMetadata(StudyInstanceUID) {
* @param {string} instances[].SeriesInstanceUID
* @returns {bool} true if series were added; false if series already exist
*/
addSeries: function(instances) {
addInstancesToSeries: function(instances) {
const { SeriesInstanceUID } = instances[0];
const seriesExists = this.series.some(
const existingSeries = this.series.find(
s => s.SeriesInstanceUID === SeriesInstanceUID
);
if (!seriesExists) {
if (existingSeries) {
existingSeries.instances.push(...instances);
} else {
const series = createSeriesMetadata(instances);
this.series.push(series);
}
return !seriesExists;
},
setSeriesMetadata: function (SeriesInstanceUID, seriesMetadata) {
let existingSeries = this.series.find(
s => s.SeriesInstanceUID === SeriesInstanceUID
);
if (existingSeries) {
existingSeries = Object.assign(existingSeries, seriesMetadata);
} else {
this.series.push(Object.assign({ instances: [] }, seriesMetadata));
}
}
};
}
@@ -0,0 +1,74 @@
const name = 'HangingProtocolService';
const publicAPI = {
name,
getState: _getState,
setHangingProtocol: _setHangingProtocol,
setHangingProtocolAppliedForViewport: _setHangingProtocolAppliedForViewport,
setServiceImplementation,
reset: _reset,
set: _set,
};
const serviceImplementation = {
_getState: () => console.warn('getState() NOT IMPLEMENTED'),
_setHangingProtocol: () =>
console.warn('_setHangingProtocol() NOT IMPLEMENTED'),
_setHangingProtocolAppliedForViewport: () =>
console.warn('_setHangingProtocolAppliedForViewport() NOT IMPLEMENTED'),
_reset: () => console.warn('reset() NOT IMPLEMENTED'),
_set: () => console.warn('set() NOT IMPLEMENTED'),
};
function _getState() {
return serviceImplementation._getState();
}
function _setHangingProtocol(hangingProtocol) {
return serviceImplementation._setHangingProtocol(hangingProtocol);
}
function _setHangingProtocolAppliedForViewport(hpAlreadyApplied) {
return serviceImplementation._setHangingProtocolAppliedForViewport(
hpAlreadyApplied
);
}
function _set(state) {
return serviceImplementation._set(state);
}
function _reset() {
return serviceImplementation._reset({});
}
function setServiceImplementation({
getState: getStateImplementation,
setHangingProtocol: setHangingProtocolImplementation,
setHangingProtocolAppliedForViewport: setHangingProtocolAppliedForViewportImplementation,
reset: resetImplementation,
set: setImplementation,
}) {
if (getStateImplementation) {
serviceImplementation._getState = getStateImplementation;
}
if (setHangingProtocolImplementation) {
serviceImplementation._setHangingProtocol = setHangingProtocolImplementation;
}
if (setHangingProtocolAppliedForViewportImplementation) {
serviceImplementation._setHangingProtocolAppliedForViewport = setHangingProtocolAppliedForViewportImplementation;
}
if (resetImplementation) {
serviceImplementation._reset = resetImplementation;
}
if (setImplementation) {
serviceImplementation._set = setImplementation;
}
}
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
@@ -0,0 +1,3 @@
import HangingProtocolService from './HangingProtocolService';
export default HangingProtocolService;
@@ -42,7 +42,6 @@ export default class ToolBarService {
}
_buttonTypes() {
console.log(this.extensionManager.modules);
const buttonTypes = {};
const registeredToolbarModules = this.extensionManager.modules[
'toolbarModule'
+2
View File
@@ -8,6 +8,7 @@ import DicomMetadataStore from './DicomMetadataStore';
import DisplaySetService from './DisplaySetService';
import ToolBarSerivce from './ToolBarService';
import ViewportGridService from './ViewportGridService';
import HangingProtocolService from './HangingProtocolService';
export {
MeasurementService,
@@ -20,4 +21,5 @@ export {
DisplaySetService,
ToolBarSerivce,
ViewportGridService,
HangingProtocolService,
};
@@ -1,25 +0,0 @@
import DICOMWeb from '../DICOMWeb/';
import isLowPriorityModality from '../utils/isLowPriorityModality';
const INFO = Symbol('INFO');
/**
* Creates an object with processed series information and saves its reference
* inside the series object itself.
* @param {Object} series The raw series object
* @returns {Object} object containing some useful info from given series
*/
export default function getSeriesInfo(series) {
let info = series[INFO];
if (!info) {
const Modality = DICOMWeb.getString(series['00080060'], '').toUpperCase();
info = Object.freeze({
Modality,
isLowPriority: isLowPriorityModality(Modality),
SeriesInstanceUID: DICOMWeb.getString(series['0020000E']),
SeriesNumber: DICOMWeb.getNumber(series['00200011'], 0) || 0,
});
series[INFO] = info;
}
return info;
}
+4 -1
View File
@@ -7,7 +7,7 @@ import {
import getStudyBoxData from './getStudyBoxData';
import retrieveStudiesMetadata from './retrieveStudiesMetadata.js';
import searchStudies from './searchStudies';
import sortStudy from './sortStudy';
import { sortStudy, sortStudySeries, sortStudyInstances, sortingCriteria } from './sortStudy';
const studies = {
services: {
@@ -21,6 +21,9 @@ const studies = {
getStudyBoxData,
searchStudies,
sortStudy,
sortStudySeries,
sortStudyInstances,
sortingCriteria,
};
export default studies;
@@ -3,7 +3,6 @@ import dcmjs from 'dcmjs';
import DICOMWeb from '../../../DICOMWeb/';
import RetrieveMetadataLoader from './retrieveMetadataLoader';
import { sortStudySeries, sortingCriteria } from '../../sortStudy';
import getSeriesInfo from '../../getSeriesInfo';
import {
createStudyFromSOPInstanceList,
addInstancesToStudy,
+8 -7
View File
@@ -1,4 +1,4 @@
import getSeriesInfo from './getSeriesInfo';
import isLowPriorityModality from '../utils/isLowPriorityModality';
/**
* Series sorting criteria: series considered low priority are moved to the end
@@ -7,15 +7,16 @@ import getSeriesInfo from './getSeriesInfo';
* @param {Object} secondSeries
*/
function seriesInfoSortingCriteria(firstSeries, secondSeries) {
const a = getSeriesInfo(firstSeries);
const b = getSeriesInfo(secondSeries);
if (!a.isLowPriority && b.isLowPriority) {
const aLowPriority = isLowPriorityModality(firstSeries.Modality);
const bLowPriority = isLowPriorityModality(secondSeries.Modality);
if (!aLowPriority && bLowPriority) {
return -1;
}
if (a.isLowPriority && !b.isLowPriority) {
if (aLowPriority && !bLowPriority) {
return 1;
}
return a.SeriesNumber - b.SeriesNumber;
return firstSeries.SeriesNumber - secondSeries.SeriesNumber;
}
const seriesSortCriteria = {
@@ -93,4 +94,4 @@ export default function sortStudy(
return study;
}
export { sortStudySeries, sortStudyInstances, sortingCriteria };
export { sortStudy, sortStudySeries, sortStudyInstances, sortingCriteria };
+3
View File
@@ -20,6 +20,7 @@ import formatPN from './formatPN';
import resolveObjectPath from './resolveObjectPath';
import * as hierarchicalListUtils from './hierarchicalListUtils';
import * as progressTrackingUtils from './progressTrackingUtils';
import isLowPriorityModality from './isLowPriorityModality';
const utils = {
guid,
@@ -44,6 +45,7 @@ const utils = {
resolveObjectPath,
hierarchicalListUtils,
progressTrackingUtils,
isLowPriorityModality
};
export {
@@ -68,6 +70,7 @@ export {
resolveObjectPath,
hierarchicalListUtils,
progressTrackingUtils,
isLowPriorityModality
};
export default utils;
@@ -1,4 +1,4 @@
const LOW_PRIORITY_MODALITIES = Object.freeze(['SEG', 'KO', 'PR']);
const LOW_PRIORITY_MODALITIES = Object.freeze(['SEG', 'KO', 'PR', 'SR', 'RTSTRUCT']);
export default function isLowPriorityModality(Modality) {
return LOW_PRIORITY_MODALITIES.includes(Modality);