2022-09-20 14:47:18 -04:00
|
|
|
/**
|
|
|
|
|
* Combine the Per instance frame data, the shared frame data
|
|
|
|
|
* and the root data objects.
|
|
|
|
|
* The data is combined by taking nested sequence objects within
|
|
|
|
|
* the functional group sequences. Data that is directly contained
|
|
|
|
|
* within the functional group sequences, such as private creators
|
|
|
|
|
* will be ignored.
|
|
|
|
|
* This can be safely called with an undefined frame in order to handle
|
|
|
|
|
* single frame data. (eg frame is undefined is the same as frame===1).
|
|
|
|
|
*/
|
|
|
|
|
const combineFrameInstance = (frame, instance) => {
|
2023-09-01 16:19:39 -04:00
|
|
|
const { PerFrameFunctionalGroupsSequence, SharedFunctionalGroupsSequence, NumberOfFrames } =
|
|
|
|
|
instance;
|
2022-10-13 11:07:56 -04:00
|
|
|
|
|
|
|
|
if (PerFrameFunctionalGroupsSequence || NumberOfFrames > 1) {
|
|
|
|
|
const frameNumber = Number.parseInt(frame || 1);
|
2023-09-01 16:19:39 -04:00
|
|
|
const shared = (
|
|
|
|
|
SharedFunctionalGroupsSequence ? Object.values(SharedFunctionalGroupsSequence[0]) : []
|
2022-10-13 11:07:56 -04:00
|
|
|
)
|
2023-07-04 08:57:14 -04:00
|
|
|
.filter(it => !!it)
|
2022-10-13 11:07:56 -04:00
|
|
|
.map(it => it[0])
|
|
|
|
|
.filter(it => it !== undefined && typeof it === 'object');
|
2023-09-01 16:19:39 -04:00
|
|
|
const perFrame = (
|
|
|
|
|
PerFrameFunctionalGroupsSequence
|
|
|
|
|
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
|
|
|
|
|
: []
|
2022-10-13 11:07:56 -04:00
|
|
|
)
|
2023-07-04 12:33:51 -04:00
|
|
|
.filter(it => !!it)
|
2022-10-13 11:07:56 -04:00
|
|
|
.map(it => it[0])
|
|
|
|
|
.filter(it => it !== undefined && typeof it === 'object');
|
|
|
|
|
|
2023-03-31 23:21:16 -03:00
|
|
|
// this is to fix NM multiframe datasets with position and orientation
|
|
|
|
|
// information inside DetectorInformationSequence
|
2023-09-01 16:19:39 -04:00
|
|
|
if (!instance.ImageOrientationPatient && instance.DetectorInformationSequence) {
|
2023-03-31 23:21:16 -03:00
|
|
|
instance.ImageOrientationPatient =
|
|
|
|
|
instance.DetectorInformationSequence[0].ImageOrientationPatient;
|
|
|
|
|
}
|
2023-09-01 16:19:39 -04:00
|
|
|
if (!instance.ImagePositionPatient && instance.DetectorInformationSequence) {
|
|
|
|
|
instance.ImagePositionPatient = instance.DetectorInformationSequence[0].ImagePositionPatient;
|
2023-03-31 23:21:16 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const newInstance = Object.assign(instance, { frameNumber: frameNumber });
|
|
|
|
|
|
|
|
|
|
// merge the shared first then the per frame to override
|
|
|
|
|
[...shared, ...perFrame].forEach(item => {
|
|
|
|
|
Object.entries(item).forEach(([key, value]) => {
|
|
|
|
|
newInstance[key] = value;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Todo: we should cache this combined instance somewhere, maybe add it
|
|
|
|
|
// back to the dicomMetaStore so we don't have to do this again.
|
|
|
|
|
return newInstance;
|
2022-10-13 11:07:56 -04:00
|
|
|
} else {
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
2022-09-20 14:47:18 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default combineFrameInstance;
|