@cornerstonejs/adapters 4.11.1 → 4.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/adapters/Cornerstone/Bidirectional.js +0 -1
- package/dist/esm/adapters/Cornerstone/MeasurementReport.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/Angle.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/ArrowAnnotate.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/BaseAdapter3D.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/Bidirectional.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/CircleROI.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/CobbAngle.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/EllipticalROI.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/LabelData.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/Length.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/MeasurementReport.d.ts +23 -10
- package/dist/esm/adapters/Cornerstone3D/MeasurementReport.js +38 -48
- package/dist/esm/adapters/Cornerstone3D/PlanarFreehandROI.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/Probe.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/RTStruct/RTSS.d.ts +10 -67
- package/dist/esm/adapters/Cornerstone3D/RTStruct/RTSS.js +111 -119
- package/dist/esm/adapters/Cornerstone3D/RTStruct/index.d.ts +2 -2
- package/dist/esm/adapters/Cornerstone3D/RTStruct/index.js +1 -1
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTROIObservationsSequence.d.ts +3 -3
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTROIObservationsSequence.js +4 -4
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedFrameOfReferenceSequence.d.ts +1 -11
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedFrameOfReferenceSequence.js +10 -20
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedSeriesSequence.d.ts +1 -4
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedSeriesSequence.js +27 -26
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getStructureSetModule.d.ts +4 -3
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getStructureSetModule.js +5 -5
- package/dist/esm/adapters/Cornerstone3D/RectangleROI.js +0 -1
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.d.ts +7 -1
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.js +47 -10
- package/dist/esm/adapters/Cornerstone3D/constants/index.d.ts +44 -0
- package/dist/esm/adapters/Cornerstone3D/constants/index.js +41 -8
- package/dist/esm/adapters/Cornerstone3D/index.d.ts +18 -18
- package/dist/esm/adapters/helpers/copySeriesTags.d.ts +2 -4
- package/dist/esm/adapters/helpers/copySeriesTags.js +4 -7
- package/dist/esm/adapters/helpers/copyStudyTags.js +2 -2
- package/dist/esm/adapters/helpers/downloadDICOMData.js +6 -9
- package/dist/esm/adapters/index.js +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +6 -4
- package/dist/esm/utilities/createInstance.d.ts +2 -0
- package/dist/esm/utilities/createInstance.js +39 -0
- package/dist/esm/utilities/index.d.ts +3 -0
- package/dist/esm/utilities/index.js +2 -0
- package/dist/esm/utilities/referencedMetadataProvider.d.ts +65 -0
- package/dist/esm/utilities/referencedMetadataProvider.js +114 -0
- package/dist/esm/version.d.ts +1 -1
- package/package.json +86 -86
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getPatientModule.d.ts +0 -13
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getPatientModule.js +0 -22
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTSeriesModule.d.ts +0 -4
- package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTSeriesModule.js +0 -9
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import getPatientModule from './utilities/getPatientModule.js';
|
|
1
|
+
import { metaData, Enums } from '@cornerstonejs/core';
|
|
2
|
+
import { utilities, annotation } from '@cornerstonejs/tools';
|
|
4
3
|
import getReferencedFrameOfReferenceSequence from './utilities/getReferencedFrameOfReferenceSequence.js';
|
|
5
4
|
import getReferencedSeriesSequence from './utilities/getReferencedSeriesSequence.js';
|
|
6
5
|
import getRTROIObservationsSequence from './utilities/getRTROIObservationsSequence.js';
|
|
7
|
-
import getRTSeriesModule from './utilities/getRTSeriesModule.js';
|
|
8
6
|
import getStructureSetModule from './utilities/getStructureSetModule.js';
|
|
7
|
+
import '../../../utilities/referencedMetadataProvider.js';
|
|
8
|
+
import { createInstance } from '../../../utilities/createInstance.js';
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
11
|
generateContourSetsFromLabelmap,
|
|
12
12
|
AnnotationToPointData
|
|
13
13
|
} = utilities.contours;
|
|
14
14
|
const {
|
|
15
|
-
|
|
16
|
-
} =
|
|
17
|
-
|
|
15
|
+
MetadataModules
|
|
16
|
+
} = Enums;
|
|
17
|
+
function generateRTSSFromSegmentations(segmentation, metadataProvider, _DicomMetadataStore) {
|
|
18
|
+
return generateRTSSFromLabelmap(segmentation, {
|
|
19
|
+
metadataProvider,
|
|
20
|
+
_DicomMetadataStore
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function generateRTSSFromLabelmap(segmentations, options) {
|
|
24
|
+
const {
|
|
25
|
+
metadataProvider = metaData
|
|
26
|
+
} = options;
|
|
18
27
|
const roiContours = [];
|
|
19
28
|
const contourSets = await generateContourSetsFromLabelmap({
|
|
20
29
|
segmentations
|
|
@@ -23,26 +32,17 @@ async function generateRTSSFromSegmentations(segmentations, metadataProvider, Di
|
|
|
23
32
|
if (contourSet) {
|
|
24
33
|
const contourSequence = [];
|
|
25
34
|
contourSet.sliceContours.forEach(sliceContour => {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
ReferencedSOPClassUID,
|
|
31
|
-
ReferencedSOPInstanceUID
|
|
32
|
-
}];
|
|
33
|
-
const sliceContourPolyData = sliceContour.polyData;
|
|
35
|
+
const ContourImageSequence = metadataProvider.get('ImageSopInstanceReference', sliceContour.referencedImageId);
|
|
36
|
+
const {
|
|
37
|
+
points: polyDataPoints
|
|
38
|
+
} = sliceContour.polyData;
|
|
34
39
|
sliceContour.contours.forEach((contour, index) => {
|
|
35
40
|
const ContourGeometricType = contour.type;
|
|
36
41
|
const NumberOfContourPoints = contour.contourPoints.length;
|
|
37
42
|
const ContourData = [];
|
|
38
43
|
contour.contourPoints.forEach(point => {
|
|
39
|
-
const pointData =
|
|
40
|
-
pointData
|
|
41
|
-
pointData[1] = +pointData[1].toFixed(2);
|
|
42
|
-
pointData[2] = +pointData[2].toFixed(2);
|
|
43
|
-
ContourData.push(pointData[0]);
|
|
44
|
-
ContourData.push(pointData[1]);
|
|
45
|
-
ContourData.push(pointData[2]);
|
|
44
|
+
const pointData = polyDataPoints[point];
|
|
45
|
+
ContourData.push(...pointData.map(v => v.toFixed(2)));
|
|
46
46
|
});
|
|
47
47
|
contourSequence.push({
|
|
48
48
|
ContourImageSequence,
|
|
@@ -58,124 +58,116 @@ async function generateRTSSFromSegmentations(segmentations, metadataProvider, Di
|
|
|
58
58
|
name: segLabel,
|
|
59
59
|
description: segLabel,
|
|
60
60
|
contourSequence,
|
|
61
|
-
color: contourSet.color,
|
|
61
|
+
color: contourSet.color.slice(0, 3),
|
|
62
62
|
metadata: contourSet.metadata
|
|
63
63
|
};
|
|
64
64
|
roiContours.push(ROIContour);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
|
-
const
|
|
68
|
-
name: segmentations.label,
|
|
69
|
-
label: segmentations.label
|
|
70
|
-
};
|
|
71
|
-
const dataset = _initializeDataset(rtMetadata, roiContours[0].metadata, metadataProvider);
|
|
67
|
+
const dataset = _initializeDataset(segmentations, roiContours[0].metadata, options);
|
|
72
68
|
roiContours.forEach((contour, index) => {
|
|
73
69
|
const roiContour = {
|
|
74
70
|
ROIDisplayColor: contour.color || [255, 0, 0],
|
|
75
71
|
ContourSequence: contour.contourSequence,
|
|
76
72
|
ReferencedROINumber: index + 1
|
|
77
73
|
};
|
|
78
|
-
|
|
74
|
+
const segment = segmentations.segments[index + 1];
|
|
75
|
+
dataset.StructureSetROISequence.push(getStructureSetModule(contour, segment));
|
|
76
|
+
dataset.RTROIObservationsSequence.push(getRTROIObservationsSequence(segment, index, options));
|
|
79
77
|
dataset.ROIContourSequence.push(roiContour);
|
|
80
|
-
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(contour.metadata,
|
|
81
|
-
dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(contour.metadata
|
|
78
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(dataset.ReferencedSeriesSequence, contour.metadata, options);
|
|
79
|
+
dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(dataset.ReferencedFrameOfReferenceSequence, contour.metadata);
|
|
82
80
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
FileMetaInformationVersion: {
|
|
87
|
-
Value: [fileMetaInformationVersionArray.buffer],
|
|
88
|
-
vr: "OB"
|
|
89
|
-
},
|
|
90
|
-
TransferSyntaxUID: {
|
|
91
|
-
Value: ["1.2.840.10008.1.2.1"],
|
|
92
|
-
vr: "UI"
|
|
93
|
-
},
|
|
94
|
-
ImplementationClassUID: {
|
|
95
|
-
Value: [DicomMetaDictionary.uid()],
|
|
96
|
-
vr: "UI"
|
|
97
|
-
},
|
|
98
|
-
ImplementationVersionName: {
|
|
99
|
-
Value: ["dcmjs"],
|
|
100
|
-
vr: "SH"
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
dataset._meta = _meta;
|
|
104
|
-
dataset.SpecificCharacterSet = "ISO_IR 192";
|
|
81
|
+
if (dataset.ReferencedFrameOfReferenceSequence?.length === 1) {
|
|
82
|
+
dataset.FrameOfReferenceUID = dataset.ReferencedFrameOfReferenceSequence[0].FrameOfReferenceUID;
|
|
83
|
+
}
|
|
105
84
|
return dataset;
|
|
106
85
|
}
|
|
107
|
-
function generateRTSSFromAnnotations(
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
label: "RTSS from Annotations"
|
|
111
|
-
};
|
|
112
|
-
const dataset = _initializeDataset(rtMetadata, annotations[0].metadata, metadataProvider);
|
|
86
|
+
function generateRTSSFromAnnotations(segmentations, annotations, options) {
|
|
87
|
+
const dataset = _initializeDataset(segmentations, annotations[0].metadata, options);
|
|
88
|
+
const segmentsContour = new Map();
|
|
113
89
|
annotations.forEach((annotation, index) => {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
90
|
+
const {
|
|
91
|
+
data: {
|
|
92
|
+
segmentation
|
|
93
|
+
}
|
|
94
|
+
} = annotation;
|
|
95
|
+
if (!segmentation) {
|
|
96
|
+
console.warn('Annotation is not a segmentation:', annotation);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const {
|
|
100
|
+
segmentationId,
|
|
101
|
+
segmentIndex
|
|
102
|
+
} = segmentation;
|
|
103
|
+
const key = `${segmentationId}:${segmentIndex}`;
|
|
104
|
+
let segmentAnnotation = segmentsContour.get(key);
|
|
105
|
+
if (!segmentAnnotation) {
|
|
106
|
+
const segment = segmentations.segments[segmentIndex];
|
|
107
|
+
const structureSetModule = getStructureSetModule(annotation, segment);
|
|
108
|
+
dataset.StructureSetROISequence.push(structureSetModule);
|
|
109
|
+
dataset.RTROIObservationsSequence.push(getRTROIObservationsSequence(segment, index, options));
|
|
110
|
+
segmentAnnotation = {
|
|
111
|
+
...segmentation,
|
|
112
|
+
annotations: [],
|
|
113
|
+
structureSetModule,
|
|
114
|
+
segment,
|
|
115
|
+
roiContourSequence: null
|
|
116
|
+
};
|
|
117
|
+
segmentsContour.set(key, segmentAnnotation);
|
|
118
|
+
}
|
|
119
|
+
const roiContourSequence = AnnotationToPointData.convert(annotation, segmentAnnotation.segment, metaData);
|
|
120
|
+
if (segmentAnnotation.roiContourSequence) {
|
|
121
|
+
segmentAnnotation.roiContourSequence.ContourSequence.push(...roiContourSequence.ContourSequence);
|
|
122
|
+
} else {
|
|
123
|
+
dataset.ROIContourSequence.push(roiContourSequence);
|
|
124
|
+
segmentAnnotation.roiContourSequence = roiContourSequence;
|
|
139
125
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
126
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(dataset.ReferencedSeriesSequence, annotation.metadata, options);
|
|
127
|
+
dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(dataset.ReferencedFrameOfReferenceSequence, annotation.metadata);
|
|
128
|
+
});
|
|
129
|
+
if (dataset.ReferencedFrameOfReferenceSequence?.length === 1) {
|
|
130
|
+
dataset.FrameOfReferenceUID = dataset.ReferencedFrameOfReferenceSequence[0].FrameOfReferenceUID;
|
|
131
|
+
}
|
|
143
132
|
return dataset;
|
|
144
133
|
}
|
|
145
|
-
function _initializeDataset(
|
|
146
|
-
const rtSOPInstanceUID = DicomMetaDictionary.uid();
|
|
134
|
+
function _initializeDataset(segmentation, imgMetadata, options) {
|
|
147
135
|
const {
|
|
148
|
-
referencedImageId:
|
|
149
|
-
FrameOfReferenceUID
|
|
136
|
+
referencedImageId: studyExemplarImageId
|
|
150
137
|
} = imgMetadata;
|
|
138
|
+
return createInstance(MetadataModules.RTSS_INSTANCE_DATA, studyExemplarImageId, {
|
|
139
|
+
StructureSetLabel: segmentation.label,
|
|
140
|
+
StructureSetName: segmentation.label,
|
|
141
|
+
SeriesDescription: segmentation.label,
|
|
142
|
+
_meta: metaData.get(MetadataModules.RTSS_CONTOUR, studyExemplarImageId)
|
|
143
|
+
}, options);
|
|
144
|
+
}
|
|
145
|
+
function generateRTSSFromContour(segmentations, options) {
|
|
151
146
|
const {
|
|
152
|
-
|
|
153
|
-
} =
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
StructureSetTime: DicomMetaDictionary.time(),
|
|
177
|
-
_meta: null
|
|
178
|
-
};
|
|
147
|
+
annotationUIDsMap
|
|
148
|
+
} = segmentations.representationData.Contour;
|
|
149
|
+
const annotations = [];
|
|
150
|
+
for (const annotationSet of annotationUIDsMap.values()) {
|
|
151
|
+
for (const annotationUID of annotationSet.values()) {
|
|
152
|
+
const annotation$1 = annotation.state.getAnnotation(annotationUID);
|
|
153
|
+
if (!annotation$1) {
|
|
154
|
+
console.error('Unable to find an annotation for UID', annotationUID);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
annotations.push(annotation$1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return generateRTSSFromAnnotations(segmentations, annotations, options);
|
|
161
|
+
}
|
|
162
|
+
function generateRTSSFromRepresentation(segmentations) {
|
|
163
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
164
|
+
if (segmentations.representationData.Labelmap) {
|
|
165
|
+
return generateRTSSFromLabelmap(segmentations, options);
|
|
166
|
+
}
|
|
167
|
+
if (segmentations.representationData.Contour) {
|
|
168
|
+
return generateRTSSFromContour(segmentations, options);
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`No representation available to save to RTSS: ${Object.keys(segmentations.representationData)}`);
|
|
179
171
|
}
|
|
180
172
|
|
|
181
|
-
export { generateRTSSFromAnnotations, generateRTSSFromSegmentations };
|
|
173
|
+
export { generateRTSSFromAnnotations, generateRTSSFromContour, generateRTSSFromLabelmap, generateRTSSFromRepresentation, generateRTSSFromSegmentations };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { utilities } from "@cornerstonejs/tools";
|
|
2
|
-
|
|
2
|
+
export * from "./RTSS";
|
|
3
3
|
declare const generateContourSetsFromLabelmap: typeof utilities.contours.generateContourSetsFromLabelmap;
|
|
4
|
-
export { generateContourSetsFromLabelmap
|
|
4
|
+
export { generateContourSetsFromLabelmap };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { utilities } from '@cornerstonejs/tools';
|
|
2
|
-
export { generateRTSSFromAnnotations, generateRTSSFromSegmentations } from './RTSS.js';
|
|
2
|
+
export { generateRTSSFromAnnotations, generateRTSSFromContour, generateRTSSFromLabelmap, generateRTSSFromRepresentation, generateRTSSFromSegmentations } from './RTSS.js';
|
|
3
3
|
|
|
4
4
|
const {
|
|
5
5
|
generateContourSetsFromLabelmap
|
package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTROIObservationsSequence.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export default function getRTROIObservationsSequence(
|
|
1
|
+
export default function getRTROIObservationsSequence(segment: any, index: any, options?: any): {
|
|
2
2
|
ObservationNumber: any;
|
|
3
3
|
ReferencedROINumber: any;
|
|
4
|
-
RTROIInterpretedType:
|
|
5
|
-
ROIInterpreter:
|
|
4
|
+
RTROIInterpretedType: any;
|
|
5
|
+
ROIInterpreter: any;
|
|
6
6
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
function getRTROIObservationsSequence(
|
|
1
|
+
function getRTROIObservationsSequence(segment, index, options) {
|
|
2
2
|
return {
|
|
3
3
|
ObservationNumber: index + 1,
|
|
4
|
-
ReferencedROINumber: index + 1,
|
|
5
|
-
RTROIInterpretedType:
|
|
6
|
-
ROIInterpreter:
|
|
4
|
+
ReferencedROINumber: segment.segmentIndex ?? index + 1,
|
|
5
|
+
RTROIInterpretedType: options?.interpretedType || 'ORGAN',
|
|
6
|
+
ROIInterpreter: options?.observerName || ''
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -1,11 +1 @@
|
|
|
1
|
-
export default function getReferencedFrameOfReferenceSequence(
|
|
2
|
-
FrameOfReferenceUID: any;
|
|
3
|
-
RTReferencedStudySequence: {
|
|
4
|
-
ReferencedSOPClassUID: any;
|
|
5
|
-
ReferencedSOPInstanceUID: any;
|
|
6
|
-
RTReferencedSeriesSequence: {
|
|
7
|
-
SeriesInstanceUID: any;
|
|
8
|
-
ContourImageSequence: any[];
|
|
9
|
-
}[];
|
|
10
|
-
}[];
|
|
11
|
-
}[];
|
|
1
|
+
export default function getReferencedFrameOfReferenceSequence(referencedFrameOfReferenceSequence: any, metadata: any, _options: any): any;
|
package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedFrameOfReferenceSequence.js
CHANGED
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
function getReferencedFrameOfReferenceSequence(
|
|
1
|
+
function getReferencedFrameOfReferenceSequence(referencedFrameOfReferenceSequence, metadata, _options) {
|
|
2
2
|
const {
|
|
3
|
-
referencedImageId: imageId,
|
|
4
3
|
FrameOfReferenceUID
|
|
5
4
|
} = metadata;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
RTReferencedStudySequence: [{
|
|
16
|
-
ReferencedSOPClassUID: dataset.SOPClassUID,
|
|
17
|
-
ReferencedSOPInstanceUID: dataset.SOPInstanceUID,
|
|
18
|
-
RTReferencedSeriesSequence: [{
|
|
19
|
-
SeriesInstanceUID,
|
|
20
|
-
ContourImageSequence: [...ReferencedSeriesSequence[0].ReferencedInstanceSequence]
|
|
21
|
-
}]
|
|
22
|
-
}]
|
|
23
|
-
}];
|
|
5
|
+
referencedFrameOfReferenceSequence ||= [];
|
|
6
|
+
let referencedItem = referencedFrameOfReferenceSequence.find(it => it.FrameOfReferenceUID === FrameOfReferenceUID);
|
|
7
|
+
if (!referencedItem) {
|
|
8
|
+
referencedItem = {
|
|
9
|
+
FrameOfReferenceUID
|
|
10
|
+
};
|
|
11
|
+
referencedFrameOfReferenceSequence.push(referencedItem);
|
|
12
|
+
}
|
|
13
|
+
return referencedFrameOfReferenceSequence;
|
|
24
14
|
}
|
|
25
15
|
|
|
26
16
|
export { getReferencedFrameOfReferenceSequence as default };
|
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export default function getReferencedSeriesSequence(
|
|
2
|
-
SeriesInstanceUID: any;
|
|
3
|
-
ReferencedInstanceSequence: any[];
|
|
4
|
-
}[];
|
|
1
|
+
export default function getReferencedSeriesSequence(referencedSeriesSequence: any, metadata: any, options?: any): any;
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { metaData, Enums } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
MetadataModules
|
|
5
|
+
} = Enums;
|
|
6
|
+
function getReferencedSeriesSequence(referencedSeriesSequence, metadata, options) {
|
|
7
|
+
const metadataProvider = options?.metadataProvider || metaData;
|
|
3
8
|
const {
|
|
4
9
|
referencedImageId: imageId
|
|
5
10
|
} = metadata;
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
ReferencedSOPInstanceUID: SOPInstanceUID
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
ReferencedSeriesSequence.push(ReferencedSeries);
|
|
11
|
+
const newReferenceSeq = metadataProvider.get(MetadataModules.REFERENCED_SERIES_REFERENCE, imageId);
|
|
12
|
+
referencedSeriesSequence ||= [];
|
|
13
|
+
if (newReferenceSeq) {
|
|
14
|
+
const {
|
|
15
|
+
ReferencedSeriesInstanceUID: newSeriesUid,
|
|
16
|
+
ReferencedInstanceSequence: [{
|
|
17
|
+
ReferencedSOPInstanceUID: newSopUID
|
|
18
|
+
}]
|
|
19
|
+
} = newReferenceSeq;
|
|
20
|
+
const existingSeries = referencedSeriesSequence.find(it => it.ReferencedSeriesInstanceUID === newSeriesUid);
|
|
21
|
+
if (!existingSeries) {
|
|
22
|
+
referencedSeriesSequence.push(newReferenceSeq);
|
|
23
|
+
return referencedSeriesSequence;
|
|
24
|
+
}
|
|
25
|
+
if (existingSeries.ReferencedInstanceSequence.find(it => it.ReferencedSOPInstanceUID === newSopUID)) {
|
|
26
|
+
return referencedSeriesSequence;
|
|
27
|
+
}
|
|
28
|
+
const referencedInstanceSeq = newReferenceSeq.ReferencedInstanceSequence;
|
|
29
|
+
existingSeries.ReferencedInstanceSequence.push(Array.isArray(referencedInstanceSeq) ? referencedInstanceSeq[0] : referencedInstanceSeq);
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return referencedSeriesSequence;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export { getReferencedSeriesSequence as default };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Types as ToolTypes } from '@cornerstonejs/tools';
|
|
2
|
+
export default function getStructureSetModule(contour: ToolTypes.Annotation, segment: any): {
|
|
2
3
|
ROINumber: any;
|
|
3
4
|
ROIName: any;
|
|
4
|
-
ROIDescription:
|
|
5
|
+
ROIDescription: any;
|
|
5
6
|
ROIGenerationAlgorithm: string;
|
|
6
|
-
ReferencedFrameOfReferenceUID:
|
|
7
|
+
ReferencedFrameOfReferenceUID: string;
|
|
7
8
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
function getStructureSetModule(contour,
|
|
1
|
+
function getStructureSetModule(contour, segment) {
|
|
2
2
|
const {
|
|
3
3
|
FrameOfReferenceUID
|
|
4
4
|
} = contour.metadata;
|
|
5
5
|
return {
|
|
6
|
-
ROINumber:
|
|
7
|
-
ROIName:
|
|
8
|
-
ROIDescription:
|
|
9
|
-
ROIGenerationAlgorithm:
|
|
6
|
+
ROINumber: segment.segmentIndex,
|
|
7
|
+
ROIName: segment.label,
|
|
8
|
+
ROIDescription: segment.label,
|
|
9
|
+
ROIGenerationAlgorithm: 'MANUAL',
|
|
10
10
|
ReferencedFrameOfReferenceUID: FrameOfReferenceUID
|
|
11
11
|
};
|
|
12
12
|
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
interface IOptions {
|
|
2
|
+
predecessorImageId?: string;
|
|
3
|
+
}
|
|
4
|
+
type Options = IOptions & {
|
|
5
|
+
[key: string]: number | boolean | unknown | string;
|
|
6
|
+
};
|
|
7
|
+
declare function generateSegmentation(images: any, labelmaps: any, metadata: any, options?: Options): any;
|
|
2
8
|
export { generateSegmentation };
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { normalizers, derivations } from 'dcmjs';
|
|
2
|
+
import { Enums } from '@cornerstonejs/core';
|
|
2
3
|
import { fillSegmentation } from '../../Cornerstone/Segmentation_4X.js';
|
|
3
4
|
|
|
4
5
|
const {
|
|
5
|
-
|
|
6
|
+
MetadataModules
|
|
7
|
+
} = Enums;
|
|
8
|
+
const {
|
|
9
|
+
SEGImageNormalizer
|
|
6
10
|
} = normalizers;
|
|
7
11
|
const {
|
|
8
12
|
Segmentation: SegmentationDerivation
|
|
@@ -10,26 +14,59 @@ const {
|
|
|
10
14
|
function generateSegmentation(images, labelmaps, metadata) {
|
|
11
15
|
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
12
16
|
const segmentation = _createMultiframeSegmentationFromReferencedImages(images, metadata, options);
|
|
13
|
-
|
|
17
|
+
const segmentationResult = fillSegmentation(segmentation, labelmaps, options);
|
|
18
|
+
const predecessorImageId = options?.predecessorImageId;
|
|
19
|
+
if (predecessorImageId) {
|
|
20
|
+
const predecessor = metadata.get(MetadataModules.PREDECESSOR_SEQUENCE, predecessorImageId);
|
|
21
|
+
Object.assign(segmentationResult, predecessor);
|
|
22
|
+
}
|
|
23
|
+
return segmentationResult;
|
|
14
24
|
}
|
|
15
25
|
function _createMultiframeSegmentationFromReferencedImages(images, metadata, options) {
|
|
26
|
+
const studyImageId = options?.predecessorImageId || images[0].imageId;
|
|
27
|
+
const studyData = metadata.get(MetadataModules.STUDY_DATA, studyImageId);
|
|
16
28
|
const datasets = images.map(image => {
|
|
17
|
-
const
|
|
29
|
+
const {
|
|
30
|
+
imageId
|
|
31
|
+
} = image;
|
|
32
|
+
const seriesData = metadata.get(MetadataModules.SERIES_DATA, imageId);
|
|
33
|
+
const imageData = metadata.get(MetadataModules.IMAGE_DATA, imageId);
|
|
18
34
|
return {
|
|
19
|
-
...
|
|
20
|
-
...
|
|
21
|
-
|
|
22
|
-
SOPInstanceUID: instance.SopInstanceUID || instance.SOPInstanceUID,
|
|
35
|
+
...studyData,
|
|
36
|
+
...seriesData,
|
|
37
|
+
...imageData,
|
|
23
38
|
PixelData: image.voxelManager.getScalarData(),
|
|
39
|
+
BitsAllocated: 16,
|
|
24
40
|
_vrMap: {
|
|
25
|
-
PixelData:
|
|
41
|
+
PixelData: 'OW'
|
|
26
42
|
},
|
|
27
43
|
_meta: {}
|
|
28
44
|
};
|
|
29
45
|
});
|
|
30
|
-
const
|
|
46
|
+
const isSingleNonMultiFrame = datasets.length === 1 && !(datasets[0].NumberOfFrames > 1);
|
|
47
|
+
if (isSingleNonMultiFrame) {
|
|
48
|
+
datasets.push(datasets[0]);
|
|
49
|
+
}
|
|
50
|
+
const normalizer = new SEGImageNormalizer(datasets);
|
|
51
|
+
normalizer.normalize();
|
|
52
|
+
const {
|
|
53
|
+
dataset: multiframe
|
|
54
|
+
} = normalizer;
|
|
31
55
|
if (!multiframe) {
|
|
32
|
-
throw new Error(
|
|
56
|
+
throw new Error('Failed to normalize the multiframe dataset, the data is not multi-frame.');
|
|
57
|
+
}
|
|
58
|
+
multiframe.SharedFunctionalGroupsSequence ||= {};
|
|
59
|
+
multiframe.SharedFunctionalGroupsSequence.PixelMeasuresSequence = {};
|
|
60
|
+
multiframe.PerFrameFunctionalGroupsSequence ||= [];
|
|
61
|
+
for (let index = 0; index < images.length; index++) {
|
|
62
|
+
multiframe.PerFrameFunctionalGroupsSequence[index] ||= {
|
|
63
|
+
PlanePositionSequence: {},
|
|
64
|
+
PlaneOrientationSequence: {}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (isSingleNonMultiFrame) {
|
|
68
|
+
multiframe.PerFrameFunctionalGroupsSequence = [multiframe.PerFrameFunctionalGroupsSequence[0]];
|
|
69
|
+
multiframe.NumberOfFrames = 1;
|
|
33
70
|
}
|
|
34
71
|
return new SegmentationDerivation([multiframe], options);
|
|
35
72
|
}
|
|
@@ -10,3 +10,47 @@ export declare const COMMENT_CODE: {
|
|
|
10
10
|
meaning: string;
|
|
11
11
|
value: string;
|
|
12
12
|
};
|
|
13
|
+
export declare const fileMetaInformationVersionArray1: Uint8Array;
|
|
14
|
+
export declare const fileMetaInformationVersionArray2: Uint8Array;
|
|
15
|
+
export declare const ImplementationClassUidSRAnnotation = "2.25.2470123695996825859949881583571202391.1.0.1";
|
|
16
|
+
export declare const ImplementationClassRtssContours = "2.25.2470123695996825859949881583571202391.2.0.1";
|
|
17
|
+
export declare const ImplementationVersionName: {
|
|
18
|
+
Value: string[];
|
|
19
|
+
vr: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const metaSRAnnotation: {
|
|
22
|
+
FileMetaInformationVersion: {
|
|
23
|
+
Value: ArrayBufferLike[];
|
|
24
|
+
vr: string;
|
|
25
|
+
};
|
|
26
|
+
TransferSyntaxUID: {
|
|
27
|
+
Value: string[];
|
|
28
|
+
vr: string;
|
|
29
|
+
};
|
|
30
|
+
ImplementationClassUID: {
|
|
31
|
+
Value: string[];
|
|
32
|
+
vr: string;
|
|
33
|
+
};
|
|
34
|
+
ImplementationVersionName: {
|
|
35
|
+
Value: string[];
|
|
36
|
+
vr: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const metaRTSSContour: {
|
|
40
|
+
ImplementationClassUID: {
|
|
41
|
+
Value: string[];
|
|
42
|
+
vr: string;
|
|
43
|
+
};
|
|
44
|
+
FileMetaInformationVersion: {
|
|
45
|
+
Value: ArrayBufferLike[];
|
|
46
|
+
vr: string;
|
|
47
|
+
};
|
|
48
|
+
TransferSyntaxUID: {
|
|
49
|
+
Value: string[];
|
|
50
|
+
vr: string;
|
|
51
|
+
};
|
|
52
|
+
ImplementationVersionName: {
|
|
53
|
+
Value: string[];
|
|
54
|
+
vr: string;
|
|
55
|
+
};
|
|
56
|
+
};
|