feat(multiframe): enhanced support for multiframe dicom (#3164)

* Changes in cswil version and multiframe

* Minor changes

* wip

* Adding support for NM multiframe images

* Applying PR suggestions

* fixing package versions

* Restoring default.js config file

* Check if NM subtype is reconstructable

* Restore default.js values

* refactore code

* feat: add flag for strict zspacing

---------

Co-authored-by: Alireza <ar.sedghi@gmail.com>
This commit is contained in:
rodrigobasilio2022andAlireza authored and GitHub committed 2023-03-31 22:21:16 -04:00
1 parent 5e42a42b5f
commit 226244a26c
31 files changed
+268 -86

No files matched your search

@@ -30,62 +30,98 @@ export default function isDisplaySetReconstructable(instances) {
}
// Can't reconstruct if all instances don't have the ImagePositionPatient.
if (!instances.every(instance => !!instance.ImagePositionPatient)) {
if (
!isMultiframe &&
!instances.every(instance => instance.ImagePositionPatient)
) {
return { value: false };
}
const sortedInstances = sortInstancesByPosition(instances);
if (isMultiframe) {
return processMultiframe(sortedInstances[0]);
} else {
return processSingleframe(sortedInstances);
}
return isMultiframe
? processMultiframe(sortedInstances[0])
: processSingleframe(sortedInstances);
}
function hasPixelMeasurements(multiFrameInstance) {
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
const sharedSequence = multiFrameInstance.SharedFunctionalGroupsSequence;
return (
Boolean(perFrameSequence?.PixelMeasuresSequence) ||
Boolean(sharedSequence?.PixelMeasuresSequence) ||
Boolean(
multiFrameInstance.PixelSpacing &&
(multiFrameInstance.SliceThickness ||
multiFrameInstance.SpacingBetweenFrames)
)
);
}
function hasOrientation(multiFrameInstance) {
const sharedSequence = multiFrameInstance.SharedFunctionalGroupsSequence;
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
return (
Boolean(sharedSequence?.PlaneOrientationSequence) ||
Boolean(perFrameSequence?.PlaneOrientationSequence) ||
Boolean(
multiFrameInstance.ImageOrientationPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImageOrientationPatient
)
);
}
function hasPosition(multiFrameInstance) {
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
return (
Boolean(perFrameSequence?.PlanePositionSequence) ||
Boolean(perFrameSequence?.CTPositionSequence) ||
Boolean(
multiFrameInstance.ImagePositionPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImagePositionPatient
)
);
}
function isNMReconstructable(multiFrameInstance) {
const imageSubType = multiFrameInstance.ImageType?.[2];
return imageSubType === 'RECON TOMO' || imageSubType === 'RECON GATED TOMO';
}
function processMultiframe(multiFrameInstance) {
const {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
} = multiFrameInstance;
// If we don't have the PixelMeasuresSequence, then the pixel spacing and
// slice thickness isn't specified or is changing and we can't reconstruct
// the dataset.
if (!hasPixelMeasurements(multiFrameInstance)) {
return { value: false };
}
if (!hasOrientation(multiFrameInstance)) {
console.log('No image orientation information, not reconstructable');
return { value: false };
}
if (!hasPosition(multiFrameInstance)) {
console.log('No image position information, not reconstructable');
return { value: false };
}
if (
!SharedFunctionalGroupsSequence ||
!SharedFunctionalGroupsSequence[0].PixelMeasuresSequence
multiFrameInstance.Modality.includes('NM') &&
!isNMReconstructable(multiFrameInstance)
) {
return { value: false };
}
// Check that the orientation is either shared or with the allowed
// difference amount
const {
PlaneOrientationSequence: sharedOrientation,
} = SharedFunctionalGroupsSequence;
if (!sharedOrientation) {
const {
PlaneOrientationSequence: firstOrientation,
} = PerFrameFunctionalGroupsSequence[0];
if (!firstOrientation) {
console.log('No orientation information');
return { value: false };
}
// TODO - check orientation consistency
}
const frame0 = PerFrameFunctionalGroupsSequence[0];
const firstPosition =
frame0.PlanePositionSequence || frame0.CTPositionSequence;
if (!firstPosition) {
console.log('No image position information, not reconstructable');
return { value: false };
}
// TODO - check spacing consistency
return { value: true };
}