feat: Add White Labelling, Hanging Protocols, and tons of Extensions / Mode fixes

* modified

* new files in existing extensions/libraries/modes

* fixed bugs and tests

* Clean up

* fix: viewport display fixed

* Fixed configs for deployment

* Removed unnecessary files and functions

* Fixed default HP module

* Added white labelling

* Fixed hash routing

* Removed unnecessary routers

Co-authored-by: Alireza Sedghi <ar.sedghi@gmail.com>
This commit is contained in:
Erik ZieglerandAlireza Sedghi authored and GitHub committed 2021-05-28 14:32:48 -04:00
1 parent 0db81b30f3
commit 99b8dc4759
93 files changed
+3825 -1293

No files matched your search

@@ -63,10 +63,22 @@ function createDicomWebApi(dicomWebConfig) {
const wadoDicomWebClient = new api.DICOMwebClient(wadoConfig);
const implementation = {
parseRouteParams: ({ params, query }) => {
const { StudyInstanceUIDs: paramsStudyInstanceUIDs } = params;
const queryStudyInstanceUIDs = query.get('StudyInstanceUIDs');
const StudyInstanceUIDs =
queryStudyInstanceUIDs || paramsStudyInstanceUIDs;
const StudyInstanceUIDsAsArray =
StudyInstanceUIDs && Array.isArray(StudyInstanceUIDs)
? StudyInstanceUIDs
: [StudyInstanceUIDs];
return StudyInstanceUIDsAsArray;
},
query: {
studies: {
mapParams: mapParams.bind(),
search: async function (origParams) {
search: async function(origParams) {
const { studyInstanceUid, seriesInstanceUid, ...mappedParams } =
mapParams(origParams, {
supportsFuzzyMatching,
@@ -86,7 +98,7 @@ function createDicomWebApi(dicomWebConfig) {
},
series: {
// mapParams: mapParams.bind(),
search: async function (studyInstanceUid) {
search: async function(studyInstanceUid) {
const results = await seriesInStudy(
qidoDicomWebClient,
studyInstanceUid
@@ -129,7 +141,6 @@ function createDicomWebApi(dicomWebConfig) {
DicomMetadataStore.addInstances(naturalizedInstances);
callback(naturalizedInstances);
};
const studyPromises = StudyInstanceUIDs.map(StudyInstanceUID =>
retrieveStudyMetadata(
wadoDicomWebClient,
@@ -177,7 +188,14 @@ function createDicomWebApi(dicomWebConfig) {
await wadoDicomWebClient.storeInstances(options);
},
},
retrieveSeriesMetadata: async ({ StudyInstanceUID } = {}) => {
// TODO: Rename this it makes no sense at all
retrieveSeriesMetadata: async ({
StudyInstanceUID,
filters,
sortCriteria,
sortFunction,
madeInClient = false,
} = {}) => {
if (!StudyInstanceUID) {
throw new Error(
'Unable to query for SeriesMetadata without StudyInstanceUID'
@@ -191,21 +209,34 @@ function createDicomWebApi(dicomWebConfig) {
} = await retrieveStudyMetadata(
wadoDicomWebClient,
StudyInstanceUID,
enableStudyLazyLoad
enableStudyLazyLoad,
filters,
sortCriteria,
sortFunction
);
// Async load series, store as retrieved
function storeInstances(instances) {
const naturalizedInstances = instances.map(naturalizeDataset);
DicomMetadataStore.addInstances(naturalizedInstances);
DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
}
DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata);
function setSuccessFlag() {
const study = DicomMetadataStore.getStudy(
StudyInstanceUID,
madeInClient
);
study.isLoaded = true;
}
seriesPromises.forEach(async seriesPromise => {
DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata, madeInClient);
const numberOfSeries = seriesPromises.length;
seriesPromises.forEach(async (seriesPromise, index) => {
const instances = await seriesPromise;
storeInstances(instances);
if (index === numberOfSeries - 1) setSuccessFlag();
});
},
deleteStudyMetadataPromise,
@@ -222,21 +253,28 @@ function createDicomWebApi(dicomWebConfig) {
if (NumberOfFrames > 1) {
for (let i = 0; i < NumberOfFrames; i++) {
const imageId = getImageId({
const imageId = this.getImageIdsForInstance({
instance,
frame: i,
config: dicomWebConfig,
});
imageIds.push(imageId);
}
} else {
const imageId = getImageId({ instance, config: dicomWebConfig });
const imageId = this.getImageIdsForInstance({ instance });
imageIds.push(imageId);
}
});
return imageIds;
},
getImageIdsForInstance({ instance, frame }) {
const imageIds = getImageId({
instance,
frame,
config: dicomWebConfig,
});
return imageIds;
},
};
if (supportsReject) {
@@ -19,7 +19,9 @@ export function retrieveStudyMetadata(
dicomWebClient,
StudyInstanceUID,
enableStudyLazyLoad,
filters
filters,
sortCriteria,
sortFunction
) {
// @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all
// and further requests for that metadata will always fail. On failure, we probably need to remove the
@@ -47,7 +49,9 @@ export function retrieveStudyMetadata(
dicomWebClient,
StudyInstanceUID,
enableStudyLazyLoad,
filters
filters,
sortCriteria,
sortFunction
).then(function(data) {
resolve(data);
}, reject);
@@ -34,6 +34,10 @@ export default function getImageId({
return;
}
if (instance.url) {
return instance.url;
}
const renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering';
if (!config[renderingAttr] || config[renderingAttr] === 'wadouri') {
@@ -43,9 +43,11 @@ const sortingCriteria = {
*/
const sortStudySeries = (
series,
seriesSortingCriteria = seriesSortCriteria.default
seriesSortingCriteria = seriesSortCriteria.default,
sortFunction
) => {
return series.sort(seriesSortingCriteria);
if (typeof sortFunction === 'function') return sortFunction(series);
else return series.sort(seriesSortingCriteria);
};
/**
@@ -15,7 +15,9 @@ async function RetrieveMetadata(
dicomWebClient,
studyInstanceUid,
enableStudyLazyLoad,
filters = {}
filters = {},
sortCriteria,
sortFunction
) {
// const RetrieveMetadataLoader =
// enableStudyLazyLoad !== false
@@ -27,7 +29,9 @@ async function RetrieveMetadata(
const retrieveMetadataLoader = new RetrieveMetadataLoader(
dicomWebClient,
studyInstanceUid,
filters
filters,
sortCriteria,
sortFunction
);
const { preLoadData, promises } = await retrieveMetadataLoader.execLoad();
@@ -12,11 +12,20 @@ export default class RetrieveMetadataLoader {
* @param {Array} studyInstanceUID Study instance ui to be retrieved
* @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process
* @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against
* @param {Function} [sortSeries] - Custom sort function for series
*/
constructor(client, studyInstanceUID, filters = {}) {
constructor(
client,
studyInstanceUID,
filters = {},
sortCriteria,
sortFunction
) {
this.client = client;
this.studyInstanceUID = studyInstanceUID;
this.filters = filters;
this.sortCriteria = sortCriteria;
this.sortFunction = sortFunction;
}
async execLoad() {
@@ -2,6 +2,7 @@ import dcmjs from 'dcmjs';
import { sortStudySeries, sortingCriteria } from '../utils/sortStudy';
import RetrieveMetadataLoader from './retrieveMetadataLoader';
/**
* Creates an immutable series loader object which loads each series sequentially using the iterator interface
* @param {DICOMWebClient} dicomWebClient The DICOMWebClient instance to be used for series load
@@ -62,13 +63,17 @@ export default class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader
async preLoad() {
const preLoaders = this.getPreLoaders();
const result = await this.runLoaders(preLoaders);
const sortCriteria = this.sortCriteria;
const sortFunction = this.sortFunction;
const { naturalizeDataset } = dcmjs.data.DicomMetaDictionary;
const naturalized = result.map(naturalizeDataset);
return sortStudySeries(
naturalized,
sortingCriteria.seriesSortCriteria.seriesInfoSortingCriteria
sortCriteria ||
sortingCriteria.seriesSortCriteria.seriesInfoSortingCriteria,
sortFunction
);
}