Skip to content

Commit 00c2b39

Browse files
authored
fix: 🐛 ignore frames without SourceImageSequence information when loading a segmentation (#198)
1 parent fe78b57 commit 00c2b39

File tree

1 file changed

+88
-60
lines changed

1 file changed

+88
-60
lines changed

src/adapters/Cornerstone/Segmentation_4X.js

Lines changed: 88 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,6 @@ function generateToolState(
291291

292292
const SeriesInstanceUID = generalSeriesModule.seriesInstanceUID;
293293

294-
console.warn(
295-
"Note the cornerstoneTools 4.0 currently assumes the labelmaps are non-overlapping. Overlapping segments will allocate incorrectly. Feel free to submit a PR to improve this behaviour!"
296-
);
297-
298294
if (!imagePlaneModule) {
299295
console.warn("Insufficient metadata, imagePlaneModule missing.");
300296
}
@@ -636,16 +632,18 @@ function checkSEGsOverlapping(
636632
: undefined;
637633
const sliceLength = Columns * Rows;
638634

639-
var firstSegIndex = -1;
640-
var previousimageIdIndex = -1;
641-
var temp2DArray = new Uint16Array(sliceLength).fill(0);
642-
var groupsLen = PerFrameFunctionalGroupsSequence.length;
643-
var numberOfSegs = multiframe.SegmentSequence.length;
644-
var numberOfFrames = imageIds.length;
635+
let firstSegIndex = -1;
636+
let previousimageIdIndex = -1;
637+
let temp2DArray = new Uint16Array(sliceLength).fill(0);
638+
const groupsLen = PerFrameFunctionalGroupsSequence.length;
639+
const numberOfSegs = multiframe.SegmentSequence.length;
640+
const numberOfFrames = imageIds.length;
645641

646642
if (numberOfSegs * numberOfFrames !== groupsLen) {
647643
console.warn(
648-
"Failed to check for overlap of segments: missing frames in PerFrameFunctionalGroupsSequence."
644+
"Failed to check for overlap of segments: " +
645+
"missing frames in PerFrameFunctionalGroupsSequence " +
646+
"or the segmentation has different geometry respect to the source image."
649647
);
650648
return false;
651649
}
@@ -663,7 +661,7 @@ function checkSEGsOverlapping(
663661
return false;
664662
}
665663

666-
var i = 0;
664+
let i = 0;
667665
while (i < groupsLen) {
668666
const PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[i];
669667

@@ -684,34 +682,18 @@ function checkSEGsOverlapping(
684682
);
685683

686684
if (!alignedPixelDataI) {
687-
// Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported
688-
i = i + numberOfFrames;
689-
if (i >= groupsLen) {
690-
i = i - numberOfFrames * numberOfSegs + 1;
691-
if (i >= numberOfFrames) {
692-
break;
693-
}
694-
}
695-
696-
continue;
685+
console.warn(
686+
"Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame."
687+
);
688+
return false;
697689
}
698690

699691
const segmentIndex = getSegmentIndex(multiframe, i);
700-
701692
if (segmentIndex === undefined) {
702693
console.warn(
703-
"Could not retrieve the segment index, skipping this frame. "
694+
"Could not retrieve the segment index, skipping this frame."
704695
);
705-
706-
i = i + numberOfFrames;
707-
if (i >= groupsLen) {
708-
i = i - numberOfFrames * numberOfSegs + 1;
709-
if (i >= numberOfFrames) {
710-
break;
711-
}
712-
}
713-
714-
continue;
696+
return false;
715697
}
716698

717699
let SourceImageSequence;
@@ -724,6 +706,13 @@ function checkSEGsOverlapping(
724706
.SourceImageSequence;
725707
}
726708

709+
if (!SourceImageSequence) {
710+
console.warn(
711+
"Source Image Sequence information missing: individual SEG frames are out of plane, this is not yet supported, skipping this frame."
712+
);
713+
return false;
714+
}
715+
727716
const imageId = getImageIdOfSourceImage(
728717
SourceImageSequence,
729718
imageIds,
@@ -805,16 +794,16 @@ function insertOverlappingPixelDataPlanar(
805794
const arrayBufferLength = sliceLength * imageIds.length * 2; // 2 bytes per label voxel in cst4.
806795

807796
// indicate the number of labelMaps
808-
var M = 1;
797+
let M = 1;
809798

810799
// indicate the current labelMap array index;
811-
var m = 0;
800+
let m = 0;
812801

813802
// temp array for checking overlaps
814-
var tempBuffer = labelmapBufferArray[m].slice(0);
803+
let tempBuffer = labelmapBufferArray[m].slice(0);
815804

816805
// temp list for checking overlaps
817-
var tempSegmentsOnFrame = cloneDeep(segmentsOnFrameArray[m]);
806+
let tempSegmentsOnFrame = cloneDeep(segmentsOnFrameArray[m]);
818807

819808
/* split overlapping SEGs algorithm for each segment:
820809
A) copy the labelmapBuffer in the array with index 0
@@ -823,7 +812,7 @@ function insertOverlappingPixelDataPlanar(
823812
D) if overlap, repeat increasing the index m up to M (if out of memory, add new buffer in the array and M++);
824813
*/
825814

826-
var numberOfSegs = multiframe.SegmentSequence.length;
815+
let numberOfSegs = multiframe.SegmentSequence.length;
827816
for (
828817
let segmentIndexToProcess = 1;
829818
segmentIndexToProcess <= numberOfSegs;
@@ -839,10 +828,9 @@ function insertOverlappingPixelDataPlanar(
839828

840829
const segmentIndex = getSegmentIndex(multiframe, i);
841830
if (segmentIndex === undefined) {
842-
console.warn(
843-
"Could not retrieve the segment index, skipping this frame. "
831+
throw new Error(
832+
"Could not retrieve the segment index. Aborting segmentation loading."
844833
);
845-
continue;
846834
}
847835

848836
if (segmentIndex !== segmentIndexToProcess) {
@@ -866,15 +854,14 @@ function insertOverlappingPixelDataPlanar(
866854
);
867855

868856
if (!alignedPixelDataI) {
869-
console.warn(
870-
"Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame."
857+
throw new Error(
858+
"Individual SEG frames are out of plane with respect to the first SEG frame. " +
859+
"This is not yet supported. Aborting segmentation loading."
871860
);
872-
873-
inPlane = false;
874-
break;
875861
}
876862

877-
let SourceImageSequence;
863+
let imageId = undefined;
864+
let SourceImageSequence = undefined;
878865

879866
if (multiframe.SourceImageSequence) {
880867
SourceImageSequence = multiframe.SourceImageSequence[i];
@@ -884,7 +871,14 @@ function insertOverlappingPixelDataPlanar(
884871
.SourceImageSequence;
885872
}
886873

887-
const imageId = getImageIdOfSourceImage(
874+
if (!SourceImageSequence) {
875+
throw new Error(
876+
"Source Image Sequence information missing: individual SEG frames are out of plane. " +
877+
"This is not yet supported. Aborting segmentation loading."
878+
);
879+
}
880+
881+
imageId = getImageIdOfSourceImage(
888882
SourceImageSequence,
889883
imageIds,
890884
metadataProvider
@@ -895,6 +889,21 @@ function insertOverlappingPixelDataPlanar(
895889
continue;
896890
}
897891

892+
const sourceImageMetadata = cornerstone.metaData.get(
893+
"instance",
894+
imageId
895+
);
896+
if (
897+
Rows !== sourceImageMetadata.Rows ||
898+
Columns !== sourceImageMetadata.Columns
899+
) {
900+
throw new Error(
901+
"Individual SEG frames have different geometry dimensions (Rows and Columns) " +
902+
"respect to the source image reference frame. This is not yet supported. " +
903+
"Aborting segmentation loading. "
904+
);
905+
}
906+
898907
const imageIdIndex = imageIds.findIndex(
899908
element => element === imageId
900909
);
@@ -1022,24 +1031,21 @@ function insertPixelDataPlanar(
10221031
);
10231032

10241033
if (!alignedPixelDataI) {
1025-
console.warn(
1026-
"Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame."
1034+
throw new Error(
1035+
"Individual SEG frames are out of plane with respect to the first SEG frame. " +
1036+
"This is not yet supported. Aborting segmentation loading."
10271037
);
1028-
1029-
inPlane = false;
1030-
break;
10311038
}
10321039

10331040
const segmentIndex = getSegmentIndex(multiframe, i);
10341041
if (segmentIndex === undefined) {
1035-
console.warn(
1036-
"Could not retrieve the segment index, skipping this frame. "
1042+
throw new Error(
1043+
"Could not retrieve the segment index. Aborting segmentation loading."
10371044
);
1038-
break;
10391045
}
10401046

1041-
let SourceImageSequence;
1042-
1047+
let imageId = undefined;
1048+
let SourceImageSequence = undefined;
10431049
if (multiframe.SourceImageSequence) {
10441050
SourceImageSequence = multiframe.SourceImageSequence[i];
10451051
} else {
@@ -1048,7 +1054,14 @@ function insertPixelDataPlanar(
10481054
.SourceImageSequence;
10491055
}
10501056

1051-
const imageId = getImageIdOfSourceImage(
1057+
if (!SourceImageSequence) {
1058+
throw new Error(
1059+
"Source Image Sequence information missing: individual SEG frames are out of plane. " +
1060+
"This is not yet supported. Aborting segmentation loading."
1061+
);
1062+
}
1063+
1064+
imageId = getImageIdOfSourceImage(
10521065
SourceImageSequence,
10531066
imageIds,
10541067
metadataProvider
@@ -1059,6 +1072,21 @@ function insertPixelDataPlanar(
10591072
continue;
10601073
}
10611074

1075+
const sourceImageMetadata = cornerstone.metaData.get(
1076+
"instance",
1077+
imageId
1078+
);
1079+
if (
1080+
Rows !== sourceImageMetadata.Rows ||
1081+
Columns !== sourceImageMetadata.Columns
1082+
) {
1083+
throw new Error(
1084+
"Individual SEG frames have different geometry dimensions (Rows and Columns) " +
1085+
"respect to the source image reference frame. This is not yet supported. " +
1086+
"Aborting segmentation loading. "
1087+
);
1088+
}
1089+
10621090
const imageIdIndex = imageIds.findIndex(element => element === imageId);
10631091
const byteOffset = sliceLength * 2 * imageIdIndex; // 2 bytes/pixel
10641092

0 commit comments

Comments
 (0)