@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.
Files changed (52) hide show
  1. package/dist/esm/adapters/Cornerstone/Bidirectional.js +0 -1
  2. package/dist/esm/adapters/Cornerstone/MeasurementReport.js +0 -1
  3. package/dist/esm/adapters/Cornerstone3D/Angle.js +0 -1
  4. package/dist/esm/adapters/Cornerstone3D/ArrowAnnotate.js +0 -1
  5. package/dist/esm/adapters/Cornerstone3D/BaseAdapter3D.js +0 -1
  6. package/dist/esm/adapters/Cornerstone3D/Bidirectional.js +0 -1
  7. package/dist/esm/adapters/Cornerstone3D/CircleROI.js +0 -1
  8. package/dist/esm/adapters/Cornerstone3D/CobbAngle.js +0 -1
  9. package/dist/esm/adapters/Cornerstone3D/EllipticalROI.js +0 -1
  10. package/dist/esm/adapters/Cornerstone3D/LabelData.js +0 -1
  11. package/dist/esm/adapters/Cornerstone3D/Length.js +0 -1
  12. package/dist/esm/adapters/Cornerstone3D/MeasurementReport.d.ts +23 -10
  13. package/dist/esm/adapters/Cornerstone3D/MeasurementReport.js +38 -48
  14. package/dist/esm/adapters/Cornerstone3D/PlanarFreehandROI.js +0 -1
  15. package/dist/esm/adapters/Cornerstone3D/Probe.js +0 -1
  16. package/dist/esm/adapters/Cornerstone3D/RTStruct/RTSS.d.ts +10 -67
  17. package/dist/esm/adapters/Cornerstone3D/RTStruct/RTSS.js +111 -119
  18. package/dist/esm/adapters/Cornerstone3D/RTStruct/index.d.ts +2 -2
  19. package/dist/esm/adapters/Cornerstone3D/RTStruct/index.js +1 -1
  20. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTROIObservationsSequence.d.ts +3 -3
  21. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTROIObservationsSequence.js +4 -4
  22. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedFrameOfReferenceSequence.d.ts +1 -11
  23. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedFrameOfReferenceSequence.js +10 -20
  24. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedSeriesSequence.d.ts +1 -4
  25. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getReferencedSeriesSequence.js +27 -26
  26. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getStructureSetModule.d.ts +4 -3
  27. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getStructureSetModule.js +5 -5
  28. package/dist/esm/adapters/Cornerstone3D/RectangleROI.js +0 -1
  29. package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.d.ts +7 -1
  30. package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.js +47 -10
  31. package/dist/esm/adapters/Cornerstone3D/constants/index.d.ts +44 -0
  32. package/dist/esm/adapters/Cornerstone3D/constants/index.js +41 -8
  33. package/dist/esm/adapters/Cornerstone3D/index.d.ts +18 -18
  34. package/dist/esm/adapters/helpers/copySeriesTags.d.ts +2 -4
  35. package/dist/esm/adapters/helpers/copySeriesTags.js +4 -7
  36. package/dist/esm/adapters/helpers/copyStudyTags.js +2 -2
  37. package/dist/esm/adapters/helpers/downloadDICOMData.js +6 -9
  38. package/dist/esm/adapters/index.js +1 -1
  39. package/dist/esm/index.d.ts +2 -1
  40. package/dist/esm/index.js +6 -4
  41. package/dist/esm/utilities/createInstance.d.ts +2 -0
  42. package/dist/esm/utilities/createInstance.js +39 -0
  43. package/dist/esm/utilities/index.d.ts +3 -0
  44. package/dist/esm/utilities/index.js +2 -0
  45. package/dist/esm/utilities/referencedMetadataProvider.d.ts +65 -0
  46. package/dist/esm/utilities/referencedMetadataProvider.js +114 -0
  47. package/dist/esm/version.d.ts +1 -1
  48. package/package.json +86 -86
  49. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getPatientModule.d.ts +0 -13
  50. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getPatientModule.js +0 -22
  51. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTSeriesModule.d.ts +0 -4
  52. package/dist/esm/adapters/Cornerstone3D/RTStruct/utilities/getRTSeriesModule.js +0 -9
@@ -1,20 +1,29 @@
1
- import { utilities } from '@cornerstonejs/tools';
2
- import dcmjs from 'dcmjs';
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
- DicomMetaDictionary
16
- } = dcmjs.data;
17
- async function generateRTSSFromSegmentations(segmentations, metadataProvider, DicomMetadataStore) {
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 sopCommon = metadataProvider.get("sopCommonModule", sliceContour.referencedImageId);
27
- const ReferencedSOPClassUID = sopCommon.sopClassUID;
28
- const ReferencedSOPInstanceUID = sopCommon.sopInstanceUID;
29
- const ContourImageSequence = [{
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 = sliceContourPolyData.points[point];
40
- pointData[0] = +pointData[0].toFixed(2);
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 rtMetadata = {
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
- dataset.StructureSetROISequence.push(getStructureSetModule(contour, index));
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, index, metadataProvider, DicomMetadataStore);
81
- dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(contour.metadata, metadataProvider, dataset);
78
+ dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(dataset.ReferencedSeriesSequence, contour.metadata, options);
79
+ dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(dataset.ReferencedFrameOfReferenceSequence, contour.metadata);
82
80
  });
83
- const fileMetaInformationVersionArray = new Uint8Array(2);
84
- fileMetaInformationVersionArray[1] = 1;
85
- const _meta = {
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(annotations, metadataProvider, DicomMetadataStore) {
108
- const rtMetadata = {
109
- name: "RTSS from Annotations",
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 ContourSequence = AnnotationToPointData.convert(annotation, index, metadataProvider);
115
- dataset.StructureSetROISequence.push(getStructureSetModule(annotation, index));
116
- dataset.ROIContourSequence.push(ContourSequence);
117
- dataset.RTROIObservationsSequence.push(getRTROIObservationsSequence(annotation, index));
118
- dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(annotation.metadata, index, metadataProvider, DicomMetadataStore);
119
- dataset.ReferencedFrameOfReferenceSequence = getReferencedFrameOfReferenceSequence(annotation.metadata, metadataProvider, dataset);
120
- });
121
- const fileMetaInformationVersionArray = new Uint8Array(2);
122
- fileMetaInformationVersionArray[1] = 1;
123
- const _meta = {
124
- FileMetaInformationVersion: {
125
- Value: [fileMetaInformationVersionArray.buffer],
126
- vr: "OB"
127
- },
128
- TransferSyntaxUID: {
129
- Value: ["1.2.840.10008.1.2.1"],
130
- vr: "UI"
131
- },
132
- ImplementationClassUID: {
133
- Value: [DicomMetaDictionary.uid()],
134
- vr: "UI"
135
- },
136
- ImplementationVersionName: {
137
- Value: ["dcmjs"],
138
- vr: "SH"
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
- dataset._meta = _meta;
142
- dataset.SpecificCharacterSet = "ISO_IR 192";
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(rtMetadata, imgMetadata, metadataProvider) {
146
- const rtSOPInstanceUID = DicomMetaDictionary.uid();
134
+ function _initializeDataset(segmentation, imgMetadata, options) {
147
135
  const {
148
- referencedImageId: imageId,
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
- studyInstanceUID
153
- } = metadataProvider.get("generalSeriesModule", imageId);
154
- const patientModule = getPatientModule(imageId, metadataProvider);
155
- const rtSeriesModule = getRTSeriesModule(DicomMetaDictionary);
156
- return {
157
- StructureSetROISequence: [],
158
- ROIContourSequence: [],
159
- RTROIObservationsSequence: [],
160
- ReferencedSeriesSequence: [],
161
- ReferencedFrameOfReferenceSequence: [],
162
- ...patientModule,
163
- ...rtSeriesModule,
164
- StudyInstanceUID: studyInstanceUID,
165
- SOPClassUID: "1.2.840.10008.5.1.4.1.1.481.3",
166
- SOPInstanceUID: rtSOPInstanceUID,
167
- Manufacturer: "dcmjs",
168
- Modality: "RTSTRUCT",
169
- FrameOfReferenceUID,
170
- PositionReferenceIndicator: "",
171
- StructureSetLabel: rtMetadata.label || "",
172
- StructureSetName: rtMetadata.name || "",
173
- ReferringPhysicianName: "",
174
- OperatorsName: "",
175
- StructureSetDate: DicomMetaDictionary.date(),
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
- import { generateRTSSFromAnnotations, generateRTSSFromSegmentations } from "./RTSS";
2
+ export * from "./RTSS";
3
3
  declare const generateContourSetsFromLabelmap: typeof utilities.contours.generateContourSetsFromLabelmap;
4
- export { generateContourSetsFromLabelmap, generateRTSSFromAnnotations, generateRTSSFromSegmentations };
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
@@ -1,6 +1,6 @@
1
- export default function getRTROIObservationsSequence(toolData: any, index: any): {
1
+ export default function getRTROIObservationsSequence(segment: any, index: any, options?: any): {
2
2
  ObservationNumber: any;
3
3
  ReferencedROINumber: any;
4
- RTROIInterpretedType: string;
5
- ROIInterpreter: string;
4
+ RTROIInterpretedType: any;
5
+ ROIInterpreter: any;
6
6
  };
@@ -1,9 +1,9 @@
1
- function getRTROIObservationsSequence(toolData, index) {
1
+ function getRTROIObservationsSequence(segment, index, options) {
2
2
  return {
3
3
  ObservationNumber: index + 1,
4
- ReferencedROINumber: index + 1,
5
- RTROIInterpretedType: "Todo: type",
6
- ROIInterpreter: "Todo: interpreter"
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(metadata: any, metadataProvider: any, dataset: any): {
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;
@@ -1,26 +1,16 @@
1
- function getReferencedFrameOfReferenceSequence(metadata, metadataProvider, dataset) {
1
+ function getReferencedFrameOfReferenceSequence(referencedFrameOfReferenceSequence, metadata, _options) {
2
2
  const {
3
- referencedImageId: imageId,
4
3
  FrameOfReferenceUID
5
4
  } = metadata;
6
- const instance = metadataProvider.get("instance", imageId);
7
- const {
8
- SeriesInstanceUID
9
- } = instance;
10
- const {
11
- ReferencedSeriesSequence
12
- } = dataset;
13
- return [{
14
- FrameOfReferenceUID,
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(metadata: any, _index: any, metadataProvider: any, DicomMetadataStore: any): {
2
- SeriesInstanceUID: any;
3
- ReferencedInstanceSequence: any[];
4
- }[];
1
+ export default function getReferencedSeriesSequence(referencedSeriesSequence: any, metadata: any, options?: any): any;
@@ -1,33 +1,34 @@
1
- function getReferencedSeriesSequence(metadata, _index, metadataProvider, DicomMetadataStore) {
2
- // grab imageId from toolData
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 instance = metadataProvider.get("instance", imageId);
7
- const {
8
- SeriesInstanceUID,
9
- StudyInstanceUID
10
- } = instance;
11
- const ReferencedSeriesSequence = [];
12
- if (SeriesInstanceUID) {
13
- const series = DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
14
- const ReferencedSeries = {
15
- SeriesInstanceUID,
16
- ReferencedInstanceSequence: []
17
- };
18
- series.instances.forEach(instance => {
19
- const {
20
- SOPInstanceUID,
21
- SOPClassUID
22
- } = instance;
23
- ReferencedSeries.ReferencedInstanceSequence.push({
24
- ReferencedSOPClassUID: SOPClassUID,
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 ReferencedSeriesSequence;
31
+ return referencedSeriesSequence;
31
32
  }
32
33
 
33
34
  export { getReferencedSeriesSequence as default };
@@ -1,7 +1,8 @@
1
- export default function getStructureSetModule(contour: any, index: any): {
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: string;
5
+ ROIDescription: any;
5
6
  ROIGenerationAlgorithm: string;
6
- ReferencedFrameOfReferenceUID: any;
7
+ ReferencedFrameOfReferenceUID: string;
7
8
  };
@@ -1,12 +1,12 @@
1
- function getStructureSetModule(contour, index) {
1
+ function getStructureSetModule(contour, segment) {
2
2
  const {
3
3
  FrameOfReferenceUID
4
4
  } = contour.metadata;
5
5
  return {
6
- ROINumber: index + 1,
7
- ROIName: contour.name || `Todo: name ${index + 1}`,
8
- ROIDescription: `Todo: description ${index + 1}`,
9
- ROIGenerationAlgorithm: "Todo: algorithm",
6
+ ROINumber: segment.segmentIndex,
7
+ ROIName: segment.label,
8
+ ROIDescription: segment.label,
9
+ ROIGenerationAlgorithm: 'MANUAL',
10
10
  ReferencedFrameOfReferenceUID: FrameOfReferenceUID
11
11
  };
12
12
  }
@@ -1,5 +1,4 @@
1
1
  import { utilities } from 'dcmjs';
2
- import 'buffer';
3
2
  import { toScoords } from '../helpers/toScoordType.js';
4
3
  import '@cornerstonejs/core';
5
4
  import MeasurementReport from './MeasurementReport.js';
@@ -1,2 +1,8 @@
1
- declare function generateSegmentation(images: any, labelmaps: any, metadata: any, options?: {}): any;
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
- Normalizer
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
- return fillSegmentation(segmentation, labelmaps, options);
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 instance = metadata.get("instance", image.imageId);
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
- ...image,
20
- ...instance,
21
- SOPClassUID: instance.SopClassUID || instance.SOPClassUID,
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: "OW"
41
+ PixelData: 'OW'
26
42
  },
27
43
  _meta: {}
28
44
  };
29
45
  });
30
- const multiframe = Normalizer.normalizeToDataset(datasets);
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("Failed to normalize the multiframe dataset, the data is not multi-frame.");
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
+ };