fix(multiframe): handling proxies properly (#4693)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com> Co-authored-by: Chao Sui <chao.sui@curvebeamai.com>
This commit is contained in:
parent
9f8df95f3e
commit
ec4b5a6876
@ -142,7 +142,9 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|||||||
study.series.forEach(aSeries => {
|
study.series.forEach(aSeries => {
|
||||||
const { SeriesInstanceUID } = aSeries;
|
const { SeriesInstanceUID } = aSeries;
|
||||||
|
|
||||||
aSeries.instances.forEach(instance => {
|
const isMultiframe = aSeries.instances[0].NumberOfFrames > 1;
|
||||||
|
|
||||||
|
aSeries.instances.forEach((instance, index) => {
|
||||||
const {
|
const {
|
||||||
url: imageId,
|
url: imageId,
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
@ -151,22 +153,14 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|||||||
} = instance;
|
} = instance;
|
||||||
|
|
||||||
instance.imageId = imageId;
|
instance.imageId = imageId;
|
||||||
const numberOfFrames = instance.NumberOfFrames || 1;
|
|
||||||
// Process all frames consistently, whether single or multiframe
|
// Add imageId specific mapping to this data as the URL isn't necessarily WADO-URI.
|
||||||
for (let i = 0; i < numberOfFrames; i++) {
|
metadataProvider.addImageIdToUIDs(imageId, {
|
||||||
const frameNumber = i + 1;
|
StudyInstanceUID,
|
||||||
const frameImageId = implementation.getImageIdsForInstance({
|
SeriesInstanceUID,
|
||||||
instance,
|
SOPInstanceUID,
|
||||||
frame: frameNumber,
|
frameIndex: isMultiframe ? index : 1,
|
||||||
});
|
});
|
||||||
// Add imageId specific mapping to this data as the URL isn't necessarily WADO-URI.
|
|
||||||
metadataProvider.addImageIdToUIDs(frameImageId, {
|
|
||||||
StudyInstanceUID,
|
|
||||||
SeriesInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameNumber: numberOfFrames > 1 ? frameNumber : undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DicomMetadataStore._broadcastEvent(EVENTS.INSTANCES_ADDED, {
|
DicomMetadataStore._broadcastEvent(EVENTS.INSTANCES_ADDED, {
|
||||||
|
|||||||
@ -478,7 +478,6 @@ function createDicomWebApi(dicomWebConfig: DicomWebConfig, servicesManager) {
|
|||||||
instance.wadoUri = dicomWebConfig.wadoUri;
|
instance.wadoUri = dicomWebConfig.wadoUri;
|
||||||
|
|
||||||
const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance;
|
const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance;
|
||||||
|
|
||||||
const numberOfFrames = instance.NumberOfFrames || 1;
|
const numberOfFrames = instance.NumberOfFrames || 1;
|
||||||
// Process all frames consistently, whether single or multiframe
|
// Process all frames consistently, whether single or multiframe
|
||||||
for (let i = 0; i < numberOfFrames; i++) {
|
for (let i = 0; i < numberOfFrames; i++) {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ window.config = {
|
|||||||
showLoadingIndicator: true,
|
showLoadingIndicator: true,
|
||||||
showWarningMessageForCrossOrigin: true,
|
showWarningMessageForCrossOrigin: true,
|
||||||
showCPUFallbackMessage: true,
|
showCPUFallbackMessage: true,
|
||||||
strictZSpacingForVolumeViewport: false,
|
strictZSpacingForVolumeViewport: true,
|
||||||
// filterQueryParam: false,
|
// filterQueryParam: false,
|
||||||
defaultDataSourceName: 'orthanc',
|
defaultDataSourceName: 'orthanc',
|
||||||
dataSources: [
|
dataSources: [
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import combineFrameInstance from '../utils/combineFrameInstance';
|
|||||||
|
|
||||||
class MetadataProvider {
|
class MetadataProvider {
|
||||||
private readonly imageURIToUIDs: Map<string, any> = new Map();
|
private readonly imageURIToUIDs: Map<string, any> = new Map();
|
||||||
private readonly imageUIDsByImageId: Map<string, any> = new Map();
|
|
||||||
// Can be used to store custom metadata for a specific type.
|
// Can be used to store custom metadata for a specific type.
|
||||||
// For instance, the scaling metadata for PET can be stored here
|
// For instance, the scaling metadata for PET can be stored here
|
||||||
// as type "scalingModule"
|
// as type "scalingModule"
|
||||||
@ -25,7 +24,6 @@ class MetadataProvider {
|
|||||||
// An example would be dicom hosted at some random site.
|
// An example would be dicom hosted at some random site.
|
||||||
const imageURI = imageIdToURI(imageId);
|
const imageURI = imageIdToURI(imageId);
|
||||||
this.imageURIToUIDs.set(imageURI, uids);
|
this.imageURIToUIDs.set(imageURI, uids);
|
||||||
this.imageUIDsByImageId.set(imageId, uids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addCustomMetadata(imageId, type, metadata) {
|
addCustomMetadata(imageId, type, metadata) {
|
||||||
@ -462,11 +460,6 @@ class MetadataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUIDsFromImageID(imageId) {
|
getUIDsFromImageID(imageId) {
|
||||||
const cachedUIDs = this.imageUIDsByImageId.get(imageId);
|
|
||||||
if (cachedUIDs) {
|
|
||||||
return cachedUIDs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageId.startsWith('wadors:')) {
|
if (imageId.startsWith('wadors:')) {
|
||||||
const strippedImageId = imageId.split('/studies/')[1];
|
const strippedImageId = imageId.split('/studies/')[1];
|
||||||
const splitImageId = strippedImageId.split('/');
|
const splitImageId = strippedImageId.split('/');
|
||||||
|
|||||||
@ -67,18 +67,27 @@ const combineFrameInstance = (frame, instance) => {
|
|||||||
ImagePositionPatientToUse = [position[0], position[1], position[2]];
|
ImagePositionPatientToUse = [position[0], position[1], position[2]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const sharedInstance = createCombinedValue(instance, SharedFunctionalGroupsSequence?.[0]);
|
|
||||||
|
// Cache the _parentInstance at the top level as a full copy to prevent
|
||||||
|
// setting values hard.
|
||||||
|
if (!instance._parentInstance) {
|
||||||
|
Object.defineProperty(instance, '_parentInstance', {
|
||||||
|
value: { ...instance },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const sharedInstance = createCombinedValue(
|
||||||
|
instance._parentInstance,
|
||||||
|
SharedFunctionalGroupsSequence?.[0],
|
||||||
|
'_shared'
|
||||||
|
);
|
||||||
const newInstance = createCombinedValue(
|
const newInstance = createCombinedValue(
|
||||||
sharedInstance,
|
sharedInstance,
|
||||||
PerFrameFunctionalGroupsSequence?.[frameNumber]
|
PerFrameFunctionalGroupsSequence?.[frameNumber - 1],
|
||||||
|
frameNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.defineProperty(newInstance, 'ImagePositionPatient', {
|
newInstance.ImagePositionPatient = ImagePositionPatientToUse ??
|
||||||
value: ImagePositionPatientToUse ?? newInstance.ImagePositionPatient ?? [0, 0, frameNumber],
|
newInstance.ImagePositionPatient ?? [0, 0, frameNumber];
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(newInstance, 'frameNumber', {
|
Object.defineProperty(newInstance, 'frameNumber', {
|
||||||
value: frameNumber,
|
value: frameNumber,
|
||||||
@ -92,14 +101,25 @@ const combineFrameInstance = (frame, instance) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function createCombinedValue(parent, functionalGroups) {
|
/**
|
||||||
|
* Creates a combined instance stored in the parent object which
|
||||||
|
* inherits from the parent instance the attributes in the functional groups.
|
||||||
|
* The storage key in the parent is in key
|
||||||
|
*/
|
||||||
|
function createCombinedValue(parent, functionalGroups, key) {
|
||||||
|
if (parent[key]) {
|
||||||
|
return parent[key];
|
||||||
|
}
|
||||||
|
// Exclude any proxying values
|
||||||
const newInstance = Object.create(parent);
|
const newInstance = Object.create(parent);
|
||||||
|
Object.defineProperty(parent, key, {
|
||||||
|
value: newInstance,
|
||||||
|
writable: false,
|
||||||
|
enumerable: false,
|
||||||
|
});
|
||||||
if (!functionalGroups) {
|
if (!functionalGroups) {
|
||||||
return newInstance;
|
return newInstance;
|
||||||
}
|
}
|
||||||
if (functionalGroups._sharedValue) {
|
|
||||||
return functionalGroups._sharedValue;
|
|
||||||
}
|
|
||||||
const shared = functionalGroups
|
const shared = functionalGroups
|
||||||
? Object.values(functionalGroups)
|
? Object.values(functionalGroups)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
@ -117,11 +137,6 @@ function createCombinedValue(parent, functionalGroups) {
|
|||||||
newInstance[key] = value;
|
newInstance[key] = value;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Object.defineProperty(functionalGroups, '_sharedValue', {
|
|
||||||
value: newInstance,
|
|
||||||
writable: false,
|
|
||||||
enumerable: false,
|
|
||||||
});
|
|
||||||
return newInstance;
|
return newInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user