fix(multiframe): metadata handling of NM studies and loading order (#4554)

This commit is contained in:
Alireza authored and GitHub committed 2024-11-28 13:22:40 -05:00
1 parent 6729534a1a
commit 7624ccb5e4
57 files changed
+482 -662

No files matched your search

+55 -18
View File
@@ -1,3 +1,5 @@
import { vec3 } from 'gl-matrix';
/**
* Combine the Per instance frame data, the shared frame data
* and the root data objects.
@@ -9,25 +11,28 @@
* single frame data. (eg frame is undefined is the same as frame===1).
*/
const combineFrameInstance = (frame, instance) => {
const { PerFrameFunctionalGroupsSequence, SharedFunctionalGroupsSequence, NumberOfFrames } =
instance;
const {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
NumberOfFrames,
SpacingBetweenSlices,
} = instance;
if (PerFrameFunctionalGroupsSequence || NumberOfFrames > 1) {
const frameNumber = Number.parseInt(frame || 1);
const shared = (
SharedFunctionalGroupsSequence ? Object.values(SharedFunctionalGroupsSequence[0]) : []
)
.filter(it => !!it)
.map(it => it[0])
.filter(it => it !== undefined && typeof it === 'object');
const perFrame = (
PerFrameFunctionalGroupsSequence
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
: []
)
.filter(it => !!it)
.map(it => it[0])
.filter(it => it !== undefined && typeof it === 'object');
const shared = SharedFunctionalGroupsSequence
? Object.values(SharedFunctionalGroupsSequence[0])
.filter(Boolean)
.map(it => it[0])
.filter(it => typeof it === 'object')
: [];
const perFrame = PerFrameFunctionalGroupsSequence
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
.filter(Boolean)
.map(it => it[0])
.filter(it => typeof it === 'object')
: [];
// this is to fix NM multiframe datasets with position and orientation
// information inside DetectorInformationSequence
@@ -35,9 +40,40 @@ const combineFrameInstance = (frame, instance) => {
instance.ImageOrientationPatient =
instance.DetectorInformationSequence[0].ImageOrientationPatient;
}
let ImagePositionPatientToUse = instance.ImagePositionPatient;
if (!instance.ImagePositionPatient && instance.DetectorInformationSequence) {
instance.ImagePositionPatient = instance.DetectorInformationSequence[0].ImagePositionPatient;
const imagePositionPatient = instance.DetectorInformationSequence[0].ImagePositionPatient;
const imageOrientationPatient = instance.ImageOrientationPatient;
// Calculate the position for the current frame
if (imageOrientationPatient && SpacingBetweenSlices) {
const rowOrientation = vec3.fromValues(
imageOrientationPatient[0],
imageOrientationPatient[1],
imageOrientationPatient[2]
);
const colOrientation = vec3.fromValues(
imageOrientationPatient[3],
imageOrientationPatient[4],
imageOrientationPatient[5]
);
const normalVector = vec3.cross(vec3.create(), rowOrientation, colOrientation);
const position = vec3.scaleAndAdd(
vec3.create(),
imagePositionPatient,
normalVector,
SpacingBetweenSlices * (frameNumber - 1)
);
ImagePositionPatientToUse = [position[0], position[1], position[2]];
}
}
console.debug('🚀 ~ ImagePositionPatientToUse:', ImagePositionPatientToUse);
const newInstance = Object.assign(instance, { frameNumber: frameNumber });
@@ -52,7 +88,8 @@ const combineFrameInstance = (frame, instance) => {
// back to the dicomMetaStore so we don't have to do this again.
return {
...newInstance,
ImagePositionPatient: newInstance.ImagePositionPatient ?? [0, 0, frameNumber],
ImagePositionPatient: ImagePositionPatientToUse ??
newInstance.ImagePositionPatient ?? [0, 0, frameNumber],
};
} else {
return instance;