@cornerstonejs/adapters 4.0.0-beta.3 → 4.0.0-beta.5
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/README.md +7 -7
- package/dist/esm/adapters/Cornerstone/Bidirectional.js +1 -0
- package/dist/esm/adapters/Cornerstone/MeasurementReport.js +8 -6
- package/dist/esm/adapters/Cornerstone/ParametricMap.js +2 -2
- package/dist/esm/adapters/Cornerstone/Segmentation_4X.js +14 -11
- package/dist/esm/adapters/Cornerstone3D/Angle.d.ts +25 -62
- package/dist/esm/adapters/Cornerstone3D/Angle.js +29 -146
- package/dist/esm/adapters/Cornerstone3D/ArrowAnnotate.d.ts +15 -27
- package/dist/esm/adapters/Cornerstone3D/ArrowAnnotate.js +31 -161
- package/dist/esm/adapters/Cornerstone3D/BaseAdapter3D.d.ts +12 -21
- package/dist/esm/adapters/Cornerstone3D/BaseAdapter3D.js +58 -43
- package/dist/esm/adapters/Cornerstone3D/Bidirectional.d.ts +25 -80
- package/dist/esm/adapters/Cornerstone3D/Bidirectional.js +36 -173
- package/dist/esm/adapters/Cornerstone3D/CircleROI.d.ts +18 -33
- package/dist/esm/adapters/Cornerstone3D/CircleROI.js +27 -133
- package/dist/esm/adapters/Cornerstone3D/CobbAngle.d.ts +25 -62
- package/dist/esm/adapters/Cornerstone3D/CobbAngle.js +24 -149
- package/dist/esm/adapters/Cornerstone3D/EllipticalROI.d.ts +18 -30
- package/dist/esm/adapters/Cornerstone3D/EllipticalROI.js +27 -241
- package/dist/esm/adapters/Cornerstone3D/KeyImage.d.ts +17 -11
- package/dist/esm/adapters/Cornerstone3D/KeyImage.js +4 -4
- package/dist/esm/adapters/Cornerstone3D/LabelData.d.ts +11 -0
- package/dist/esm/adapters/Cornerstone3D/LabelData.js +102 -0
- package/dist/esm/adapters/Cornerstone3D/Length.d.ts +17 -45
- package/dist/esm/adapters/Cornerstone3D/Length.js +27 -125
- package/dist/esm/adapters/Cornerstone3D/MeasurementReport.d.ts +77 -37
- package/dist/esm/adapters/Cornerstone3D/MeasurementReport.js +176 -51
- package/dist/esm/adapters/Cornerstone3D/PlanarFreehandROI.d.ts +18 -41
- package/dist/esm/adapters/Cornerstone3D/PlanarFreehandROI.js +26 -138
- package/dist/esm/adapters/Cornerstone3D/Probe.d.ts +17 -32
- package/dist/esm/adapters/Cornerstone3D/Probe.js +34 -106
- package/dist/esm/adapters/Cornerstone3D/RectangleROI.d.ts +19 -33
- package/dist/esm/adapters/Cornerstone3D/RectangleROI.js +28 -115
- package/dist/esm/adapters/Cornerstone3D/UltrasoundDirectional.d.ts +9 -15
- package/dist/esm/adapters/Cornerstone3D/UltrasoundDirectional.js +12 -21
- package/dist/esm/adapters/Cornerstone3D/constants/index.d.ts +11 -0
- package/dist/esm/adapters/Cornerstone3D/constants/index.js +12 -1
- package/dist/esm/adapters/Cornerstone3D/index.d.ts +11 -0
- package/dist/esm/adapters/Cornerstone3D/index.js +6 -2
- package/dist/esm/adapters/helpers/checkOrientation.js +2 -2
- package/dist/esm/adapters/helpers/index.d.ts +3 -0
- package/dist/esm/adapters/helpers/index.js +3 -0
- package/dist/esm/adapters/helpers/scoordToWorld.d.ts +5 -0
- package/dist/esm/adapters/helpers/scoordToWorld.js +32 -0
- package/dist/esm/adapters/helpers/toArray.js +1 -1
- package/dist/esm/adapters/helpers/toPoint3.d.ts +3 -0
- package/dist/esm/adapters/helpers/toPoint3.js +18 -0
- package/dist/esm/adapters/helpers/toScoordType.d.ts +23 -0
- package/dist/esm/adapters/helpers/toScoordType.js +33 -0
- package/dist/esm/adapters/index.d.ts +12 -1
- package/dist/esm/adapters/index.js +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/package.json +6 -7
- package/dist/esm/adapters/helpers/compareArrays.d.ts +0 -1
- package/dist/esm/adapters/helpers/compareArrays.js +0 -18
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { utilities, derivations, normalizers, data } from 'dcmjs';
|
|
2
|
-
import { cache } from '@cornerstonejs/core';
|
|
1
|
+
import { utilities as utilities$1, derivations, normalizers, data } from 'dcmjs';
|
|
2
|
+
import { utilities, cache } from '@cornerstonejs/core';
|
|
3
3
|
import CORNERSTONE_3D_TAG from './cornerstone3DTag.js';
|
|
4
4
|
import { toArray } from '../helpers/toArray.js';
|
|
5
5
|
import { codeMeaningEquals } from '../helpers/codeMeaningEquals.js';
|
|
6
6
|
import 'buffer';
|
|
7
7
|
import { copyStudyTags } from '../helpers/copyStudyTags.js';
|
|
8
8
|
import { copySeriesTags } from '../helpers/copySeriesTags.js';
|
|
9
|
+
import { scoordToWorld } from '../helpers/scoordToWorld.js';
|
|
10
|
+
import { toPoint3 } from '../helpers/toPoint3.js';
|
|
9
11
|
import CodingScheme from './CodingScheme.js';
|
|
10
|
-
import { NO_IMAGE_ID } from './constants/index.js';
|
|
12
|
+
import { COMMENT_CODE, TEXT_ANNOTATION_POSITION, NO_IMAGE_ID } from './constants/index.js';
|
|
13
|
+
import LabelData from './LabelData.js';
|
|
11
14
|
|
|
12
15
|
var _MeasurementReport;
|
|
13
16
|
const {
|
|
14
17
|
TID1500,
|
|
15
18
|
addAccessors
|
|
16
|
-
} = utilities;
|
|
19
|
+
} = utilities$1;
|
|
17
20
|
const {
|
|
18
21
|
StructuredReport
|
|
19
22
|
} = derivations;
|
|
@@ -31,6 +34,14 @@ const FINDING = {
|
|
|
31
34
|
CodingSchemeDesignator: "DCM",
|
|
32
35
|
CodeValue: "121071"
|
|
33
36
|
};
|
|
37
|
+
const COMMENT = {
|
|
38
|
+
CodingSchemeDesignator: COMMENT_CODE.schemeDesignator,
|
|
39
|
+
CodeValue: COMMENT_CODE.value
|
|
40
|
+
};
|
|
41
|
+
const COMMENT_POSITION = {
|
|
42
|
+
CodingSchemeDesignator: TEXT_ANNOTATION_POSITION.schemeDesignator,
|
|
43
|
+
CodeValue: TEXT_ANNOTATION_POSITION.value
|
|
44
|
+
};
|
|
34
45
|
const FINDING_SITE = {
|
|
35
46
|
CodingSchemeDesignator: "SCT",
|
|
36
47
|
CodeValue: "363698007"
|
|
@@ -40,28 +51,36 @@ const FINDING_SITE_OLD = {
|
|
|
40
51
|
CodeValue: "G-C0E3"
|
|
41
52
|
};
|
|
42
53
|
class MeasurementReport {
|
|
43
|
-
static getTID300ContentItem(tool, ReferencedSOPSequence, toolClass,
|
|
44
|
-
const args = toolClass.getTID300RepresentationArguments(tool,
|
|
54
|
+
static getTID300ContentItem(tool, ReferencedSOPSequence, toolClass, is3DMeasurement) {
|
|
55
|
+
const args = toolClass.getTID300RepresentationArguments(tool, is3DMeasurement);
|
|
45
56
|
args.ReferencedSOPSequence = ReferencedSOPSequence;
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
if (args.use3DSpatialCoordinates) {
|
|
58
|
+
args.ReferencedFrameOfReferenceUID = tool.metadata.FrameOfReferenceUID;
|
|
59
|
+
}
|
|
60
|
+
const tid300Measurement = new toolClass.TID300Representation(args);
|
|
61
|
+
const labelMeasurement = new LabelData(tid300Measurement, tool);
|
|
62
|
+
return labelMeasurement;
|
|
48
63
|
}
|
|
49
|
-
static getMeasurementGroup(toolType, toolData, ReferencedSOPSequence,
|
|
64
|
+
static getMeasurementGroup(toolType, toolData, ReferencedSOPSequence, is3DMeasurement) {
|
|
50
65
|
const toolTypeData = toolData[toolType];
|
|
51
66
|
const toolClass = this.measurementAdapterByToolType.get(toolType);
|
|
52
67
|
if (!toolTypeData || !toolTypeData.data || !toolTypeData.data.length || !toolClass) {
|
|
53
68
|
return;
|
|
54
69
|
}
|
|
55
70
|
const Measurements = toolTypeData.data.map(tool => {
|
|
56
|
-
return this.getTID300ContentItem(tool, ReferencedSOPSequence, toolClass,
|
|
71
|
+
return this.getTID300ContentItem(tool, ReferencedSOPSequence, toolClass, is3DMeasurement);
|
|
57
72
|
});
|
|
58
73
|
return new TID1501MeasurementGroup(Measurements);
|
|
59
74
|
}
|
|
60
75
|
static getCornerstoneLabelFromDefaultState(defaultState) {
|
|
61
76
|
const {
|
|
62
77
|
findingSites = [],
|
|
63
|
-
finding
|
|
78
|
+
finding,
|
|
79
|
+
commentGroup
|
|
64
80
|
} = defaultState;
|
|
81
|
+
if (commentGroup?.TextValue) {
|
|
82
|
+
return commentGroup.TextValue;
|
|
83
|
+
}
|
|
65
84
|
const cornersoneFreeTextCodingValue = CodingScheme.codeValues.CORNERSTONEFREETEXT;
|
|
66
85
|
const freeTextLabel = findingSites.find(fs => fs.CodeValue === cornersoneFreeTextCodingValue);
|
|
67
86
|
if (freeTextLabel) {
|
|
@@ -110,21 +129,32 @@ class MeasurementReport {
|
|
|
110
129
|
} = ReferencedSOPSequence;
|
|
111
130
|
const referencedImageId = sopInstanceUIDToImageIdMap[ReferencedSOPInstanceUID];
|
|
112
131
|
const imagePlaneModule = metadata.get("imagePlaneModule", referencedImageId);
|
|
132
|
+
const annotationUID = DicomMetaDictionary.uid();
|
|
113
133
|
return {
|
|
114
134
|
SCOORDGroup,
|
|
115
135
|
ReferencedSOPSequence,
|
|
116
136
|
ReferencedSOPInstanceUID,
|
|
117
137
|
ReferencedFrameNumber,
|
|
138
|
+
referencedImageId,
|
|
118
139
|
state: {
|
|
119
140
|
description: undefined,
|
|
120
141
|
sopInstanceUid: ReferencedSOPInstanceUID,
|
|
121
142
|
annotation: {
|
|
122
|
-
|
|
143
|
+
data: {
|
|
144
|
+
annotationUID,
|
|
145
|
+
cachedStats: {},
|
|
146
|
+
handles: {
|
|
147
|
+
activeHandleIndex: 0,
|
|
148
|
+
textBox: {
|
|
149
|
+
hasMoved: false
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
annotationUID,
|
|
123
154
|
metadata: {
|
|
124
155
|
toolName: toolType,
|
|
125
156
|
referencedImageId,
|
|
126
|
-
FrameOfReferenceUID: imagePlaneModule.frameOfReferenceUID
|
|
127
|
-
label: ""
|
|
157
|
+
FrameOfReferenceUID: imagePlaneModule.frameOfReferenceUID
|
|
128
158
|
}
|
|
129
159
|
}
|
|
130
160
|
}
|
|
@@ -135,21 +165,33 @@ class MeasurementReport {
|
|
|
135
165
|
SCOORD3DGroup,
|
|
136
166
|
toolType
|
|
137
167
|
} = _ref2;
|
|
138
|
-
|
|
168
|
+
const annotationUID = DicomMetaDictionary.uid();
|
|
169
|
+
const toolData = {
|
|
139
170
|
SCOORD3DGroup,
|
|
140
171
|
FrameOfReferenceUID: SCOORD3DGroup.ReferencedFrameOfReferenceUID,
|
|
141
172
|
state: {
|
|
142
173
|
description: undefined,
|
|
143
174
|
annotation: {
|
|
144
|
-
annotationUID
|
|
175
|
+
annotationUID,
|
|
176
|
+
data: {
|
|
177
|
+
annotationUID,
|
|
178
|
+
cachedStats: {},
|
|
179
|
+
handles: {
|
|
180
|
+
activeHandleIndex: 0,
|
|
181
|
+
textBox: {
|
|
182
|
+
hasMoved: false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
145
186
|
metadata: {
|
|
146
187
|
toolName: toolType,
|
|
147
|
-
FrameOfReferenceUID: SCOORD3DGroup.ReferencedFrameOfReferenceUID
|
|
148
|
-
label: ""
|
|
188
|
+
FrameOfReferenceUID: SCOORD3DGroup.ReferencedFrameOfReferenceUID
|
|
149
189
|
}
|
|
150
190
|
}
|
|
151
191
|
}
|
|
152
192
|
};
|
|
193
|
+
utilities.updatePlaneRestriction(toPoint3(SCOORD3DGroup.GraphicData), toolData.state.annotation.metadata);
|
|
194
|
+
return toolData;
|
|
153
195
|
}
|
|
154
196
|
static getSpatialCoordinatesState(_ref3) {
|
|
155
197
|
let {
|
|
@@ -158,23 +200,22 @@ class MeasurementReport {
|
|
|
158
200
|
metadata,
|
|
159
201
|
toolType
|
|
160
202
|
} = _ref3;
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
});
|
|
175
|
-
} else {
|
|
203
|
+
const contentSequenceArr = toArray(NUMGroup.ContentSequence);
|
|
204
|
+
const SCOORDGroup = contentSequenceArr.find(group => group.ValueType === "SCOORD");
|
|
205
|
+
const SCOORD3DGroup = contentSequenceArr.find(group => group.ValueType === "SCOORD3D");
|
|
206
|
+
const result = SCOORD3DGroup && this.processSCOORD3DGroup({
|
|
207
|
+
SCOORD3DGroup,
|
|
208
|
+
toolType
|
|
209
|
+
}) || SCOORDGroup && this.processSCOORDGroup({
|
|
210
|
+
SCOORDGroup,
|
|
211
|
+
toolType,
|
|
212
|
+
metadata,
|
|
213
|
+
sopInstanceUIDToImageIdMap
|
|
214
|
+
});
|
|
215
|
+
if (!result) {
|
|
176
216
|
throw new Error("No spatial coordinates group found.");
|
|
177
217
|
}
|
|
218
|
+
return result;
|
|
178
219
|
}
|
|
179
220
|
static processSpatialCoordinatesGroup(_ref4) {
|
|
180
221
|
let {
|
|
@@ -183,6 +224,8 @@ class MeasurementReport {
|
|
|
183
224
|
metadata,
|
|
184
225
|
findingGroup,
|
|
185
226
|
findingSiteGroups,
|
|
227
|
+
commentGroup,
|
|
228
|
+
commentPositionGroup,
|
|
186
229
|
toolType
|
|
187
230
|
} = _ref4;
|
|
188
231
|
const {
|
|
@@ -192,7 +235,9 @@ class MeasurementReport {
|
|
|
192
235
|
ReferencedSOPInstanceUID,
|
|
193
236
|
ReferencedFrameNumber,
|
|
194
237
|
SCOORD3DGroup,
|
|
195
|
-
FrameOfReferenceUID
|
|
238
|
+
FrameOfReferenceUID,
|
|
239
|
+
referencedImageId,
|
|
240
|
+
textBoxPosition
|
|
196
241
|
} = this.getSpatialCoordinatesState({
|
|
197
242
|
NUMGroup,
|
|
198
243
|
sopInstanceUIDToImageIdMap,
|
|
@@ -203,21 +248,35 @@ class MeasurementReport {
|
|
|
203
248
|
const findingSites = findingSiteGroups.map(fsg => {
|
|
204
249
|
return addAccessors(fsg.ConceptCodeSequence);
|
|
205
250
|
});
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
251
|
+
if (commentPositionGroup) {
|
|
252
|
+
state.commentPositionGroup = commentPositionGroup;
|
|
253
|
+
const textBoxCoords = scoordToWorld({
|
|
254
|
+
is3DMeasurement: !referencedImageId,
|
|
255
|
+
referencedImageId
|
|
256
|
+
}, commentPositionGroup);
|
|
257
|
+
state.annotation.data.handles.textBox = {
|
|
258
|
+
hasMoved: true,
|
|
259
|
+
worldPosition: textBoxCoords[0]
|
|
260
|
+
};
|
|
213
261
|
}
|
|
214
|
-
|
|
262
|
+
state.finding = finding;
|
|
263
|
+
state.findingSites = findingSites;
|
|
264
|
+
state.commentGroup = commentGroup;
|
|
265
|
+
state.commentPositionGroup = commentPositionGroup;
|
|
266
|
+
if (finding) {
|
|
267
|
+
state.description = finding.CodeMeaning;
|
|
268
|
+
}
|
|
269
|
+
state.annotation.data.label = this.getCornerstoneLabelFromDefaultState(state);
|
|
215
270
|
return {
|
|
216
|
-
defaultState,
|
|
271
|
+
defaultState: state,
|
|
272
|
+
state,
|
|
217
273
|
NUMGroup,
|
|
274
|
+
scoord: SCOORD3DGroup || SCOORDGroup,
|
|
218
275
|
SCOORDGroup,
|
|
219
276
|
ReferencedSOPSequence,
|
|
220
277
|
ReferencedSOPInstanceUID,
|
|
278
|
+
referencedImageId,
|
|
279
|
+
textBoxPosition,
|
|
221
280
|
ReferencedFrameNumber,
|
|
222
281
|
SCOORD3DGroup,
|
|
223
282
|
FrameOfReferenceUID
|
|
@@ -229,16 +288,39 @@ class MeasurementReport {
|
|
|
229
288
|
} = MeasurementGroup;
|
|
230
289
|
const contentSequenceArr = toArray(ContentSequence);
|
|
231
290
|
const findingGroup = contentSequenceArr.find(group => this.codeValueMatch(group, FINDING));
|
|
291
|
+
const commentGroup = contentSequenceArr.find(group => this.codeValueMatch(group, COMMENT));
|
|
292
|
+
const commentPositionGroup = contentSequenceArr.find(group => this.codeValueMatch(group, COMMENT_POSITION));
|
|
232
293
|
const findingSiteGroups = contentSequenceArr.filter(group => this.codeValueMatch(group, FINDING_SITE, FINDING_SITE_OLD)) || [];
|
|
233
|
-
const NUMGroup = contentSequenceArr.find(group => group.ValueType === "NUM")
|
|
234
|
-
|
|
294
|
+
const NUMGroup = contentSequenceArr.find(group => group.ValueType === "NUM") || {
|
|
295
|
+
ContentSequence: contentSequenceArr.filter(group => group.ValueType === "SCOORD" || group.ValueType === "SCOORD3D")
|
|
296
|
+
};
|
|
297
|
+
const spatialGroup = this.processSpatialCoordinatesGroup({
|
|
235
298
|
NUMGroup,
|
|
236
299
|
sopInstanceUIDToImageIdMap,
|
|
237
300
|
metadata,
|
|
238
301
|
findingGroup,
|
|
239
302
|
findingSiteGroups,
|
|
303
|
+
commentGroup,
|
|
304
|
+
commentPositionGroup,
|
|
240
305
|
toolType
|
|
241
306
|
});
|
|
307
|
+
const {
|
|
308
|
+
referencedImageId
|
|
309
|
+
} = spatialGroup.state.annotation.metadata;
|
|
310
|
+
const is3DMeasurement = !!spatialGroup.SCOORD3DGroup;
|
|
311
|
+
const scoordArgs = {
|
|
312
|
+
referencedImageId,
|
|
313
|
+
is3DMeasurement
|
|
314
|
+
};
|
|
315
|
+
const scoord = spatialGroup.SCOORD3DGroup || spatialGroup.SCOORDGroup;
|
|
316
|
+
const worldCoords = scoordToWorld(scoordArgs, scoord);
|
|
317
|
+
return {
|
|
318
|
+
...spatialGroup,
|
|
319
|
+
is3DMeasurement,
|
|
320
|
+
scoordArgs,
|
|
321
|
+
scoord,
|
|
322
|
+
worldCoords
|
|
323
|
+
};
|
|
242
324
|
}
|
|
243
325
|
static generateReferencedSOPSequence(_ref5) {
|
|
244
326
|
let {
|
|
@@ -286,10 +368,13 @@ class MeasurementReport {
|
|
|
286
368
|
const referenceToolData = toolData?.[toolTypes?.[0]]?.data?.[0];
|
|
287
369
|
const volumeId = referenceToolData?.metadata?.volumeId;
|
|
288
370
|
const volume = cache.getVolume(volumeId);
|
|
371
|
+
if (!volume) {
|
|
372
|
+
throw new Error(`No volume found for ${volumeId}`);
|
|
373
|
+
}
|
|
289
374
|
const imageId = volume.imageIds[0];
|
|
290
375
|
return imageId;
|
|
291
376
|
}
|
|
292
|
-
static generateReport(toolState, metadataProvider,
|
|
377
|
+
static generateReport(toolState, metadataProvider, options) {
|
|
293
378
|
let allMeasurementGroups = [];
|
|
294
379
|
const sopInstanceUIDsToSeriesInstanceUIDMap = {};
|
|
295
380
|
const derivationSourceDatasets = [];
|
|
@@ -298,6 +383,7 @@ class MeasurementReport {
|
|
|
298
383
|
Object.keys(toolState).forEach(imageId => {
|
|
299
384
|
const toolData = toolState[imageId];
|
|
300
385
|
const toolTypes = Object.keys(toolData);
|
|
386
|
+
const is3DMeasurement = imageId === NO_IMAGE_ID;
|
|
301
387
|
const ReferencedSOPSequence = this.generateReferencedSOPSequence({
|
|
302
388
|
toolData,
|
|
303
389
|
toolTypes,
|
|
@@ -306,12 +392,12 @@ class MeasurementReport {
|
|
|
306
392
|
sopInstanceUIDsToSeriesInstanceUIDMap,
|
|
307
393
|
derivationSourceDatasets
|
|
308
394
|
});
|
|
309
|
-
if (
|
|
395
|
+
if (is3DMeasurement) {
|
|
310
396
|
is3DSR = true;
|
|
311
397
|
}
|
|
312
398
|
const measurementGroups = [];
|
|
313
399
|
toolTypes.forEach(toolType => {
|
|
314
|
-
const group = this.getMeasurementGroup(toolType, toolData, ReferencedSOPSequence,
|
|
400
|
+
const group = this.getMeasurementGroup(toolType, toolData, ReferencedSOPSequence, is3DMeasurement);
|
|
315
401
|
if (group) {
|
|
316
402
|
measurementGroups.push(group);
|
|
317
403
|
}
|
|
@@ -331,10 +417,13 @@ class MeasurementReport {
|
|
|
331
417
|
report.SpecificCharacterSet = "ISO_IR 192";
|
|
332
418
|
if (is3DSR) {
|
|
333
419
|
report.dataset.SOPClassUID = DicomMetaDictionary.sopClassUIDsByName.Comprehensive3DSR;
|
|
420
|
+
if (!report.dataset.SOPClassUID) {
|
|
421
|
+
throw new Error(`NO sop class defined for Comprehensive3DSR in ${JSON.stringify(DicomMetaDictionary.sopClassUIDsByName)}`);
|
|
422
|
+
}
|
|
334
423
|
}
|
|
335
424
|
return report;
|
|
336
425
|
}
|
|
337
|
-
static generateToolState(dataset, sopInstanceUIDToImageIdMap,
|
|
426
|
+
static generateToolState(dataset, sopInstanceUIDToImageIdMap, metadata, hooks) {
|
|
338
427
|
if (dataset.ContentTemplateSequence.TemplateIdentifier !== "1500") {
|
|
339
428
|
throw new Error("This package can currently only interpret DICOM SR TID 1500");
|
|
340
429
|
}
|
|
@@ -354,9 +443,9 @@ class MeasurementReport {
|
|
|
354
443
|
} = trackingIdentifierGroup;
|
|
355
444
|
const trackingUniqueIdentifierGroup = measurementGroupContentSequence.find(contentItem => contentItem.ConceptNameCodeSequence.CodeMeaning === TRACKING_UNIQUE_IDENTIFIER);
|
|
356
445
|
const trackingUniqueIdentifierValue = trackingUniqueIdentifierGroup?.UID;
|
|
357
|
-
const toolAdapter = hooks?.getToolClass?.(measurementGroup, dataset, this.measurementAdapterByToolType) || this.getAdapterForTrackingIdentifier(trackingIdentifierValue);
|
|
446
|
+
const toolAdapter = hooks?.getToolClass?.(measurementGroup, dataset, this.measurementAdapterByToolType) || this.getAdapterForTrackingIdentifier(trackingIdentifierValue) || this.getAdapterForCodeType(measurementGroup);
|
|
358
447
|
if (toolAdapter) {
|
|
359
|
-
const measurement = toolAdapter.getMeasurementData(measurementGroup, sopInstanceUIDToImageIdMap,
|
|
448
|
+
const measurement = toolAdapter.getMeasurementData(measurementGroup, sopInstanceUIDToImageIdMap, metadata, trackingIdentifierValue);
|
|
360
449
|
measurement.TrackingUniqueIdentifier = trackingUniqueIdentifierValue;
|
|
361
450
|
console.log(`=== ${toolAdapter.toolType} ===`);
|
|
362
451
|
console.log(measurement);
|
|
@@ -403,10 +492,40 @@ class MeasurementReport {
|
|
|
403
492
|
}
|
|
404
493
|
}
|
|
405
494
|
}
|
|
495
|
+
static getAdapterForCodeType(measurementGroup) {
|
|
496
|
+
for (const adapter of this.measurementAdapterByTrackingIdentifier.values()) {
|
|
497
|
+
if (adapter.isValidMeasurement(measurementGroup)) {
|
|
498
|
+
return adapter;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
static registerAdapterTypes(adapter) {
|
|
503
|
+
for (var _len2 = arguments.length, types = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
504
|
+
types[_key2 - 1] = arguments[_key2];
|
|
505
|
+
}
|
|
506
|
+
for (const type of types) {
|
|
507
|
+
if (!this.measurementAdaptersByType.has(type)) {
|
|
508
|
+
this.measurementAdaptersByType.set(type, []);
|
|
509
|
+
}
|
|
510
|
+
const adapters = this.measurementAdaptersByType.get(type);
|
|
511
|
+
if (adapters.indexOf(adapter) === -1) {
|
|
512
|
+
adapters.push(adapter);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
static getAdaptersForTypes(graphicCode, graphicType, pointCount) {
|
|
517
|
+
const adapters = [];
|
|
518
|
+
appendList(adapters, this.measurementAdaptersByType.get(`${graphicCode}-${graphicType}-${pointCount}`));
|
|
519
|
+
appendList(adapters, this.measurementAdaptersByType.get(`${graphicCode}-${graphicType}`));
|
|
520
|
+
appendList(adapters, this.measurementAdaptersByType.get(graphicCode));
|
|
521
|
+
appendList(adapters, this.measurementAdaptersByType.get(graphicType));
|
|
522
|
+
return adapters;
|
|
523
|
+
}
|
|
406
524
|
}
|
|
407
525
|
_MeasurementReport = MeasurementReport;
|
|
408
526
|
_MeasurementReport.CORNERSTONE_3D_TAG = CORNERSTONE_3D_TAG;
|
|
409
527
|
_MeasurementReport.measurementAdapterByToolType = new Map();
|
|
528
|
+
_MeasurementReport.measurementAdaptersByType = new Map();
|
|
410
529
|
_MeasurementReport.measurementAdapterByTrackingIdentifier = new Map();
|
|
411
530
|
_MeasurementReport.codeValueMatch = (group, code, oldCode) => {
|
|
412
531
|
const {
|
|
@@ -429,5 +548,11 @@ _MeasurementReport.generateDerivationSourceDataset = instance => {
|
|
|
429
548
|
...seriesTags
|
|
430
549
|
};
|
|
431
550
|
};
|
|
551
|
+
function appendList(list, appendList) {
|
|
552
|
+
if (!appendList?.length) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
list.push(...appendList);
|
|
556
|
+
}
|
|
432
557
|
|
|
433
558
|
export { MeasurementReport as default };
|
|
@@ -1,48 +1,25 @@
|
|
|
1
1
|
import BaseAdapter3D from "./BaseAdapter3D";
|
|
2
2
|
declare class PlanarFreehandROI extends BaseAdapter3D {
|
|
3
3
|
static closedContourThreshold: number;
|
|
4
|
-
static getMeasurementData(MeasurementGroup: any, sopInstanceUIDToImageIdMap: any,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
static getMeasurementDataFromScoord3D({ defaultState, SCOORD3DGroup }: {
|
|
13
|
-
defaultState: any;
|
|
14
|
-
SCOORD3DGroup: any;
|
|
15
|
-
}): any;
|
|
16
|
-
static getTID300RepresentationArguments(tool: any, worldToImageCoords: any): {
|
|
17
|
-
points: any;
|
|
18
|
-
area: any;
|
|
19
|
-
areaUnit: any;
|
|
20
|
-
perimeter: any;
|
|
21
|
-
modalityUnit: any;
|
|
22
|
-
mean: any;
|
|
23
|
-
max: any;
|
|
24
|
-
stdDev: any;
|
|
25
|
-
trackingIdentifierTextValue: string;
|
|
26
|
-
finding: any;
|
|
27
|
-
findingSites: any;
|
|
28
|
-
ReferencedFrameOfReferenceUID: any;
|
|
29
|
-
use3DSpatialCoordinates: boolean;
|
|
30
|
-
} | {
|
|
31
|
-
points: any;
|
|
32
|
-
area: any;
|
|
33
|
-
areaUnit: any;
|
|
34
|
-
perimeter: any;
|
|
35
|
-
modalityUnit: any;
|
|
36
|
-
mean: any;
|
|
37
|
-
max: any;
|
|
38
|
-
stdDev: any;
|
|
39
|
-
trackingIdentifierTextValue: string;
|
|
40
|
-
finding: any;
|
|
41
|
-
findingSites: any;
|
|
42
|
-
use3DSpatialCoordinates: boolean;
|
|
4
|
+
static getMeasurementData(MeasurementGroup: any, sopInstanceUIDToImageIdMap: any, metadata: any): {
|
|
5
|
+
description?: string;
|
|
6
|
+
sopInstanceUid?: string;
|
|
7
|
+
annotation: import("packages/tools/dist/esm/types").Annotation;
|
|
8
|
+
finding?: unknown;
|
|
9
|
+
findingSites?: unknown;
|
|
10
|
+
commentGroup?: any;
|
|
11
|
+
commentPositionGroup?: any;
|
|
43
12
|
};
|
|
44
|
-
static
|
|
45
|
-
points:
|
|
13
|
+
static getTID300RepresentationArguments(tool: any, is3DMeasurement?: boolean): {
|
|
14
|
+
points: ({
|
|
15
|
+
x: any;
|
|
16
|
+
y: any;
|
|
17
|
+
z: any;
|
|
18
|
+
} | {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z?: undefined;
|
|
22
|
+
})[];
|
|
46
23
|
area: any;
|
|
47
24
|
areaUnit: any;
|
|
48
25
|
perimeter: any;
|