fix: retrieveSeriesMetadata (#2703)
This commit is contained in:
1 parent
0e2c31939c
commit
509c41fbab
10 files changed
+455
-443
No files matched your search
@@ -134,8 +134,68 @@ function createDicomJSONApi(dicomJsonConfig) {
|
||||
},
|
||||
retrieve: {
|
||||
series: {
|
||||
metaData: () => {
|
||||
console.debug(' DICOMJson retrieve series metadata');
|
||||
metaData: ({
|
||||
StudyInstanceUID,
|
||||
madeInClient = false,
|
||||
customSort,
|
||||
} = {}) => {
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
);
|
||||
}
|
||||
|
||||
const study = findStudies('StudyInstanceUID', StudyInstanceUID)[0];
|
||||
let series;
|
||||
|
||||
if (customSort) {
|
||||
series = customSort(study.series);
|
||||
} else {
|
||||
series = study.series;
|
||||
}
|
||||
|
||||
const seriesSummaryMetadata = series.map(series => {
|
||||
const seriesSummary = {
|
||||
StudyInstanceUID: study.StudyInstanceUID,
|
||||
...series,
|
||||
};
|
||||
delete seriesSummary.instances;
|
||||
return seriesSummary;
|
||||
});
|
||||
|
||||
// Async load series, store as retrieved
|
||||
function storeInstances(naturalizedInstances) {
|
||||
DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
||||
}
|
||||
|
||||
DicomMetadataStore.addSeriesMetadata(
|
||||
seriesSummaryMetadata,
|
||||
madeInClient
|
||||
);
|
||||
|
||||
function setSuccessFlag() {
|
||||
const study = DicomMetadataStore.getStudy(
|
||||
StudyInstanceUID,
|
||||
madeInClient
|
||||
);
|
||||
study.isLoaded = true;
|
||||
}
|
||||
|
||||
const numberOfSeries = series.length;
|
||||
series.forEach((series, index) => {
|
||||
const instances = series.instances.map(instance => {
|
||||
const obj = {
|
||||
...instance.metadata,
|
||||
url: instance.url,
|
||||
imageId: instance.url,
|
||||
...series,
|
||||
};
|
||||
delete obj.instances;
|
||||
return obj;
|
||||
});
|
||||
storeInstances(instances);
|
||||
if (index === numberOfSeries - 1) setSuccessFlag();
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -144,66 +204,6 @@ function createDicomJSONApi(dicomJsonConfig) {
|
||||
console.debug(' DICOMJson store dicom');
|
||||
},
|
||||
},
|
||||
retrieveSeriesMetadata: ({
|
||||
StudyInstanceUID,
|
||||
madeInClient = false,
|
||||
customSort,
|
||||
} = {}) => {
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
);
|
||||
}
|
||||
|
||||
const study = findStudies('StudyInstanceUID', StudyInstanceUID)[0];
|
||||
let series;
|
||||
|
||||
if (customSort) {
|
||||
series = customSort(study.series);
|
||||
} else {
|
||||
series = study.series;
|
||||
}
|
||||
|
||||
const seriesSummaryMetadata = series.map(series => {
|
||||
const seriesSummary = {
|
||||
StudyInstanceUID: study.StudyInstanceUID,
|
||||
...series,
|
||||
};
|
||||
delete seriesSummary.instances;
|
||||
return seriesSummary;
|
||||
});
|
||||
|
||||
// Async load series, store as retrieved
|
||||
function storeInstances(naturalizedInstances) {
|
||||
DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
||||
}
|
||||
|
||||
DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata, madeInClient);
|
||||
|
||||
function setSuccessFlag() {
|
||||
const study = DicomMetadataStore.getStudy(
|
||||
StudyInstanceUID,
|
||||
madeInClient
|
||||
);
|
||||
study.isLoaded = true;
|
||||
}
|
||||
|
||||
const numberOfSeries = series.length;
|
||||
series.forEach((series, index) => {
|
||||
const instances = series.instances.map(instance => {
|
||||
const obj = {
|
||||
...instance.metadata,
|
||||
url: instance.url,
|
||||
imageId: instance.url,
|
||||
...series,
|
||||
};
|
||||
delete obj.instances;
|
||||
return obj;
|
||||
});
|
||||
storeInstances(instances);
|
||||
if (index === numberOfSeries - 1) setSuccessFlag();
|
||||
});
|
||||
},
|
||||
getImageIdsForDisplaySet(displaySet) {
|
||||
const images = displaySet.images;
|
||||
const imageIds = [];
|
||||
|
||||
@@ -1,69 +1,67 @@
|
||||
import { DicomMetadataStore, IWebApiDataSource } from '@ohif/core'
|
||||
import OHIF from '@ohif/core'
|
||||
import { DicomMetadataStore, IWebApiDataSource } from '@ohif/core';
|
||||
import OHIF from '@ohif/core';
|
||||
import dcmjs from 'dcmjs';
|
||||
|
||||
const metadataProvider = OHIF.classes.MetadataProvider
|
||||
const { EVENTS } = DicomMetadataStore
|
||||
const metadataProvider = OHIF.classes.MetadataProvider;
|
||||
const { EVENTS } = DicomMetadataStore;
|
||||
|
||||
// Sorting SR modalities to be at the end of series list
|
||||
function customSort(seriesA, seriesB) {
|
||||
const modalityA = seriesA.instances[0].Modality
|
||||
const modalityB = seriesB.instances[0].Modality
|
||||
const modalityA = seriesA.instances[0].Modality;
|
||||
const modalityB = seriesB.instances[0].Modality;
|
||||
|
||||
if (modalityA === "SR") {
|
||||
if (modalityA === 'SR') {
|
||||
return +1;
|
||||
}
|
||||
if (modalityB === "SR") {
|
||||
if (modalityB === 'SR') {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
function createDicomLocalApi(dicomLocalConfig) {
|
||||
const { name } = dicomLocalConfig
|
||||
const { name } = dicomLocalConfig;
|
||||
|
||||
const implementation = {
|
||||
initialize: ({ params, query }) => {
|
||||
const { StudyInstanceUIDs: paramsStudyInstanceUIDs } = params
|
||||
const queryStudyInstanceUIDs = query.get('StudyInstanceUIDs')
|
||||
const { StudyInstanceUIDs: paramsStudyInstanceUIDs } = params;
|
||||
const queryStudyInstanceUIDs = query.get('StudyInstanceUIDs');
|
||||
|
||||
const StudyInstanceUIDs =
|
||||
queryStudyInstanceUIDs || paramsStudyInstanceUIDs
|
||||
queryStudyInstanceUIDs || paramsStudyInstanceUIDs;
|
||||
const StudyInstanceUIDsAsArray =
|
||||
StudyInstanceUIDs && Array.isArray(StudyInstanceUIDs)
|
||||
? StudyInstanceUIDs
|
||||
: [StudyInstanceUIDs]
|
||||
|
||||
: [StudyInstanceUIDs];
|
||||
|
||||
// Put SRs at the end of series list to make sure images are loaded first
|
||||
StudyInstanceUIDsAsArray.forEach(StudyInstanceUID => {
|
||||
const study = DicomMetadataStore.getStudy(StudyInstanceUID)
|
||||
study.series = study.series.sort(customSort)
|
||||
})
|
||||
const study = DicomMetadataStore.getStudy(StudyInstanceUID);
|
||||
study.series = study.series.sort(customSort);
|
||||
});
|
||||
|
||||
return StudyInstanceUIDsAsArray
|
||||
return StudyInstanceUIDsAsArray;
|
||||
},
|
||||
query: {
|
||||
studies: {
|
||||
mapParams: () => { },
|
||||
search: (params) => {
|
||||
const studyUIDs = DicomMetadataStore.getStudyInstanceUIDs()
|
||||
mapParams: () => {},
|
||||
search: params => {
|
||||
const studyUIDs = DicomMetadataStore.getStudyInstanceUIDs();
|
||||
|
||||
return studyUIDs.map(StudyInstanceUID => {
|
||||
let numInstances = 0
|
||||
const modalities = new Set()
|
||||
let numInstances = 0;
|
||||
const modalities = new Set();
|
||||
|
||||
// Calculating the number of instances in the study and modalities
|
||||
// present in the study
|
||||
const study = DicomMetadataStore.getStudy(StudyInstanceUID)
|
||||
const study = DicomMetadataStore.getStudy(StudyInstanceUID);
|
||||
study.series.forEach(aSeries => {
|
||||
numInstances += aSeries.instances.length
|
||||
numInstances += aSeries.instances.length;
|
||||
modalities.add(aSeries.Modality);
|
||||
})
|
||||
});
|
||||
|
||||
// first instance in the first series
|
||||
const firstInstance = study?.series[0]?.instances[0]
|
||||
const firstInstance = study?.series[0]?.instances[0];
|
||||
|
||||
if (firstInstance) {
|
||||
return {
|
||||
@@ -80,33 +78,75 @@ function createDicomLocalApi(dicomLocalConfig) {
|
||||
NumInstances: numInstances,
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
processResults: () => {
|
||||
console.debug(' DICOMLocal QUERY processResults')
|
||||
console.debug(' DICOMLocal QUERY processResults');
|
||||
},
|
||||
},
|
||||
series: {
|
||||
// mapParams: mapParams.bind(),
|
||||
search: () => {
|
||||
console.debug(' DICOMLocal QUERY SERIES SEARCH')
|
||||
console.debug(' DICOMLocal QUERY SERIES SEARCH');
|
||||
},
|
||||
},
|
||||
instances: {
|
||||
search: () => {
|
||||
console.debug(' DICOMLocal QUERY instances SEARCH')
|
||||
console.debug(' DICOMLocal QUERY instances SEARCH');
|
||||
},
|
||||
},
|
||||
},
|
||||
retrieve: {
|
||||
series: {
|
||||
metaData: () => {
|
||||
console.debug(' DICOMLocal retrieve series metadata')
|
||||
metaData: async ({ StudyInstanceUID, madeInClient = false } = {}) => {
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
);
|
||||
}
|
||||
|
||||
// Instances metadata already added via local upload
|
||||
const study = DicomMetadataStore.getStudy(
|
||||
StudyInstanceUID,
|
||||
madeInClient
|
||||
);
|
||||
|
||||
// Series metadata already added via local upload
|
||||
DicomMetadataStore._broadcastEvent(EVENTS.SERIES_ADDED, {
|
||||
StudyInstanceUID,
|
||||
madeInClient,
|
||||
});
|
||||
|
||||
study.series.forEach(aSeries => {
|
||||
const { SeriesInstanceUID } = aSeries;
|
||||
|
||||
aSeries.instances.forEach(instance => {
|
||||
const {
|
||||
url: imageId,
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
SOPInstanceUID,
|
||||
} = instance;
|
||||
|
||||
// Add imageId specific mapping to this data as the URL isn't necessarily WADO-URI.
|
||||
metadataProvider.addImageIdToUIDs(imageId, {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
SOPInstanceUID,
|
||||
});
|
||||
});
|
||||
|
||||
DicomMetadataStore._broadcastEvent(EVENTS.INSTANCES_ADDED, {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
madeInClient,
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
store: {
|
||||
dicom: (naturalizedReport) => {
|
||||
dicom: naturalizedReport => {
|
||||
const reportBlob = dcmjs.data.datasetToBlob(naturalizedReport);
|
||||
|
||||
//Create a URL for the binary.
|
||||
@@ -114,91 +154,49 @@ function createDicomLocalApi(dicomLocalConfig) {
|
||||
window.location.assign(objectUrl);
|
||||
},
|
||||
},
|
||||
retrieveSeriesMetadata: async ({
|
||||
StudyInstanceUID,
|
||||
madeInClient = false,
|
||||
} = {}) => {
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
)
|
||||
}
|
||||
|
||||
// Instances metadata already added via local upload
|
||||
const study = DicomMetadataStore.getStudy(StudyInstanceUID, madeInClient)
|
||||
|
||||
// Series metadata already added via local upload
|
||||
DicomMetadataStore._broadcastEvent(EVENTS.SERIES_ADDED, {
|
||||
StudyInstanceUID,
|
||||
madeInClient,
|
||||
})
|
||||
|
||||
study.series.forEach((aSeries) => {
|
||||
const { SeriesInstanceUID } = aSeries
|
||||
|
||||
aSeries.instances.forEach((instance) => {
|
||||
const {
|
||||
url: imageId,
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
SOPInstanceUID,
|
||||
} = instance
|
||||
|
||||
// Add imageId specific mapping to this data as the URL isn't necessarily WADO-URI.
|
||||
metadataProvider.addImageIdToUIDs(imageId, {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
SOPInstanceUID,
|
||||
})
|
||||
})
|
||||
|
||||
DicomMetadataStore._broadcastEvent(EVENTS.INSTANCES_ADDED, {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
madeInClient,
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
getImageIdsForDisplaySet(displaySet) {
|
||||
const images = displaySet.images
|
||||
const imageIds = []
|
||||
const images = displaySet.images;
|
||||
const imageIds = [];
|
||||
|
||||
if (!images) {
|
||||
return imageIds
|
||||
return imageIds;
|
||||
}
|
||||
|
||||
displaySet.images.forEach((instance) => {
|
||||
const NumberOfFrames = instance.NumberOfFrames
|
||||
displaySet.images.forEach(instance => {
|
||||
const NumberOfFrames = instance.NumberOfFrames;
|
||||
|
||||
if (NumberOfFrames > 1) {
|
||||
for (let i = 0; i < NumberOfFrames; i++) {
|
||||
const imageId = this.getImageIdsForInstance({
|
||||
instance,
|
||||
frame: i,
|
||||
})
|
||||
imageIds.push(imageId)
|
||||
});
|
||||
imageIds.push(imageId);
|
||||
}
|
||||
} else {
|
||||
const imageId = this.getImageIdsForInstance({ instance })
|
||||
imageIds.push(imageId)
|
||||
const imageId = this.getImageIdsForInstance({ instance });
|
||||
imageIds.push(imageId);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return imageIds
|
||||
return imageIds;
|
||||
},
|
||||
getImageIdsForInstance({ instance, frame }) {
|
||||
const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance
|
||||
const storedInstance = DicomMetadataStore.getInstance(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID)
|
||||
const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance;
|
||||
const storedInstance = DicomMetadataStore.getInstance(
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
SOPInstanceUID
|
||||
);
|
||||
if (storedInstance.url) {
|
||||
return storedInstance.url
|
||||
return storedInstance.url;
|
||||
}
|
||||
},
|
||||
deleteStudyMetadataPromise() {
|
||||
console.log("deleteStudyMetadataPromise not implemented")
|
||||
}
|
||||
}
|
||||
return IWebApiDataSource.create(implementation)
|
||||
console.log('deleteStudyMetadataPromise not implemented');
|
||||
},
|
||||
};
|
||||
return IWebApiDataSource.create(implementation);
|
||||
}
|
||||
|
||||
export { createDicomLocalApi }
|
||||
export { createDicomLocalApi };
|
||||
@@ -7,7 +7,12 @@ import {
|
||||
processSeriesResults,
|
||||
} from './qido.js';
|
||||
import dcm4cheeReject from './dcm4cheeReject';
|
||||
import { DicomMetadataStore, IWebApiDataSource, utils, errorHandler } from '@ohif/core';
|
||||
import {
|
||||
DicomMetadataStore,
|
||||
IWebApiDataSource,
|
||||
utils,
|
||||
errorHandler,
|
||||
} from '@ohif/core';
|
||||
|
||||
import getImageId from './utils/getImageId';
|
||||
import dcmjs from 'dcmjs';
|
||||
@@ -65,7 +70,9 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
|
||||
// TODO -> Two clients sucks, but its better than 1000.
|
||||
// TODO -> We'll need to merge auth later.
|
||||
const qidoDicomWebClient = staticWado ? new StaticWadoClient(qidoConfig) : new api.DICOMwebClient(qidoConfig);
|
||||
const qidoDicomWebClient = staticWado
|
||||
? new StaticWadoClient(qidoConfig)
|
||||
: new api.DICOMwebClient(qidoConfig);
|
||||
const wadoDicomWebClient = new api.DICOMwebClient(wadoConfig);
|
||||
|
||||
const implementation = {
|
||||
@@ -84,7 +91,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
query: {
|
||||
studies: {
|
||||
mapParams: mapParams.bind(),
|
||||
search: async function (origParams) {
|
||||
search: async function(origParams) {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
@@ -109,7 +116,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
},
|
||||
series: {
|
||||
// mapParams: mapParams.bind(),
|
||||
search: async function (studyInstanceUid) {
|
||||
search: async function(studyInstanceUid) {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
@@ -143,48 +150,108 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
},
|
||||
retrieve: {
|
||||
series: {
|
||||
// TODO: change queryParams to `StudyInstanceUID` for now?
|
||||
// Conduct query, return a promise like others
|
||||
// Await this call and add to DicomMetadataStore after receiving result
|
||||
metadata: (queryParams, callback) => {
|
||||
metadata: async ({
|
||||
StudyInstanceUID,
|
||||
filters,
|
||||
sortCriteria,
|
||||
sortFunction,
|
||||
madeInClient = false,
|
||||
} = {}) => {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
wadoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
let { StudyInstanceUIDs } = urlUtil.parse(queryParams, true);
|
||||
|
||||
StudyInstanceUIDs = urlUtil.paramString.parseParam(StudyInstanceUIDs);
|
||||
|
||||
if (!StudyInstanceUIDs) {
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Incomplete queryParams, missing StudyInstanceUIDs'
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const storeInstances = instances => {
|
||||
const naturalizedInstances = instances.map(naturalizeDataset);
|
||||
DicomMetadataStore.addInstances(naturalizedInstances);
|
||||
callback(naturalizedInstances);
|
||||
};
|
||||
const studyPromises = StudyInstanceUIDs.map(StudyInstanceUID =>
|
||||
retrieveStudyMetadata(
|
||||
wadoDicomWebClient,
|
||||
StudyInstanceUID,
|
||||
enableStudyLazyLoad
|
||||
)
|
||||
// Get Series
|
||||
const {
|
||||
seriesSummaryMetadata,
|
||||
seriesPromises,
|
||||
} = await retrieveStudyMetadata(
|
||||
wadoDicomWebClient,
|
||||
StudyInstanceUID,
|
||||
enableStudyLazyLoad,
|
||||
filters,
|
||||
sortCriteria,
|
||||
sortFunction
|
||||
);
|
||||
|
||||
studyPromises.forEach(studyPromise => {
|
||||
studyPromise.then(data => {
|
||||
const { seriesPromises } = data;
|
||||
seriesPromises.forEach(seriesPromise => {
|
||||
seriesPromise.then(instances => {
|
||||
storeInstances(instances);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* naturalizes the dataset, and adds a retrieve bulkdata method
|
||||
* to any values containing BulkDataURI.
|
||||
* @param {*} instance
|
||||
* @returns naturalized dataset, with retrieveBulkData methods
|
||||
*/
|
||||
const addRetrieveBulkData = instance => {
|
||||
const naturalized = naturalizeDataset(instance);
|
||||
Object.keys(naturalized).forEach(key => {
|
||||
const value = naturalized[key];
|
||||
// The value.Value will be set with the bulkdata read value
|
||||
// in which case it isn't necessary to re-read this.
|
||||
if (value && value.BulkDataURI && !value.Value) {
|
||||
// Provide a method to fetch bulkdata
|
||||
value.retrieveBulkData = () => {
|
||||
const options = {
|
||||
// The bulkdata fetches work with either multipart or
|
||||
// singlepart, so set multipart to false to let the server
|
||||
// decide which type to respond with.
|
||||
multipart: false,
|
||||
BulkDataURI: value.BulkDataURI,
|
||||
// The study instance UID is required if the bulkdata uri
|
||||
// is relative - that isn't disallowed by DICOMweb, but
|
||||
// isn't well specified in the standard, but is needed in
|
||||
// any implementation that stores static copies of the metadata
|
||||
StudyInstanceUID: naturalized.StudyInstanceUID,
|
||||
};
|
||||
return qidoDicomWebClient
|
||||
.retrieveBulkData(options)
|
||||
.then(val => {
|
||||
const ret = (val && val[0]) || undefined;
|
||||
value.Value = ret;
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
return naturalized;
|
||||
};
|
||||
|
||||
// Async load series, store as retrieved
|
||||
function storeInstances(instances) {
|
||||
const naturalizedInstances = instances.map(addRetrieveBulkData);
|
||||
|
||||
DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
||||
}
|
||||
|
||||
function setSuccessFlag() {
|
||||
const study = DicomMetadataStore.getStudy(
|
||||
StudyInstanceUID,
|
||||
madeInClient
|
||||
);
|
||||
study.isLoaded = true;
|
||||
}
|
||||
|
||||
// Google Cloud Healthcare doesn't return StudyInstanceUID, so we need to add
|
||||
// it manually here
|
||||
seriesSummaryMetadata.forEach(aSeries => {
|
||||
aSeries.StudyInstanceUID = StudyInstanceUID;
|
||||
});
|
||||
|
||||
DicomMetadataStore.addSeriesMetadata(
|
||||
seriesSummaryMetadata,
|
||||
madeInClient
|
||||
);
|
||||
|
||||
const numberOfSeries = seriesPromises.length;
|
||||
seriesPromises.forEach(async (seriesPromise, index) => {
|
||||
const instances = await seriesPromise;
|
||||
storeInstances(instances);
|
||||
if (index === numberOfSeries - 1) setSuccessFlag();
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -220,104 +287,6 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
await wadoDicomWebClient.storeInstances(options);
|
||||
},
|
||||
},
|
||||
// TODO: Rename this it makes no sense at all
|
||||
retrieveSeriesMetadata: async ({
|
||||
StudyInstanceUID,
|
||||
filters,
|
||||
sortCriteria,
|
||||
sortFunction,
|
||||
madeInClient = false,
|
||||
} = {}) => {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
wadoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
);
|
||||
}
|
||||
|
||||
// Get Series
|
||||
const {
|
||||
seriesSummaryMetadata,
|
||||
seriesPromises,
|
||||
} = await retrieveStudyMetadata(
|
||||
wadoDicomWebClient,
|
||||
StudyInstanceUID,
|
||||
enableStudyLazyLoad,
|
||||
filters,
|
||||
sortCriteria,
|
||||
sortFunction
|
||||
);
|
||||
|
||||
/**
|
||||
* naturalizes the dataset, and adds a retrieve bulkdata method
|
||||
* to any values containing BulkDataURI.
|
||||
* @param {*} instance
|
||||
* @returns naturalized dataset, with retrieveBulkData methods
|
||||
*/
|
||||
const addRetrieveBulkData = instance => {
|
||||
const naturalized = naturalizeDataset(instance);
|
||||
Object.keys(naturalized).forEach(key => {
|
||||
const value = naturalized[key];
|
||||
// The value.Value will be set with the bulkdata read value
|
||||
// in which case it isn't necessary to re-read this.
|
||||
if (value && value.BulkDataURI && !value.Value) {
|
||||
// Provide a method to fetch bulkdata
|
||||
value.retrieveBulkData = () => {
|
||||
const options = {
|
||||
// The bulkdata fetches work with either multipart or
|
||||
// singlepart, so set multipart to false to let the server
|
||||
// decide which type to respond with.
|
||||
multipart: false,
|
||||
BulkDataURI: value.BulkDataURI,
|
||||
// The study instance UID is required if the bulkdata uri
|
||||
// is relative - that isn't disallowed by DICOMweb, but
|
||||
// isn't well specified in the standard, but is needed in
|
||||
// any implementation that stores static copies of the metadata
|
||||
StudyInstanceUID: naturalized.StudyInstanceUID,
|
||||
};
|
||||
return qidoDicomWebClient.retrieveBulkData(options).then(val => {
|
||||
const ret = val && val[0] || undefined;
|
||||
value.Value = ret;
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
return naturalized
|
||||
};
|
||||
|
||||
// Async load series, store as retrieved
|
||||
function storeInstances(instances) {
|
||||
const naturalizedInstances = instances.map(addRetrieveBulkData);
|
||||
|
||||
DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
||||
}
|
||||
|
||||
function setSuccessFlag() {
|
||||
const study = DicomMetadataStore.getStudy(
|
||||
StudyInstanceUID,
|
||||
madeInClient
|
||||
);
|
||||
study.isLoaded = true;
|
||||
}
|
||||
|
||||
// Google Cloud Healthcare doesn't return StudyInstanceUID, so we need to add
|
||||
// it manually here
|
||||
seriesSummaryMetadata.forEach(aSeries => { aSeries.StudyInstanceUID = StudyInstanceUID })
|
||||
|
||||
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,
|
||||
getImageIdsForDisplaySet(displaySet) {
|
||||
const images = displaySet.images;
|
||||
|
||||
@@ -2,7 +2,7 @@ function requestDisplaySetCreationForStudy(
|
||||
dataSource,
|
||||
DisplaySetService,
|
||||
StudyInstanceUID,
|
||||
madeInClient,
|
||||
madeInClient
|
||||
) {
|
||||
// TODO: is this already short-circuited by the map of Retrieve promises?
|
||||
if (
|
||||
@@ -13,7 +13,7 @@ function requestDisplaySetCreationForStudy(
|
||||
return;
|
||||
}
|
||||
|
||||
dataSource.retrieveSeriesMetadata({ StudyInstanceUID, madeInClient });
|
||||
dataSource.retrieve.series.metadata({ StudyInstanceUID, madeInClient });
|
||||
}
|
||||
|
||||
export default requestDisplaySetCreationForStudy;
|
||||
Reference in new issue
Block a user