From 18686c2caf13ede3e881303100bd4cc34b8b135f Mon Sep 17 00:00:00 2001
From: Ibrahim <93064150+IbrahimCSAE@users.noreply.github.com>
Date: Wed, 29 May 2024 09:12:39 -0400
Subject: [PATCH] feat(measurements): show untracked measurements in
measurement panel under additional findings (#4160)
---
extensions/cornerstone-dicom-seg/package.json | 4 +--
extensions/cornerstone-dicom-sr/package.json | 6 ++--
.../cornerstone-dynamic-volume/package.json | 6 ++--
extensions/cornerstone/package.json | 10 +++---
.../utils/measurementServiceMappings/Angle.ts | 26 ++++++--------
.../ArrowAnnotate.ts | 20 +++++------
.../Bidirectional.ts | 24 ++++++-------
.../measurementServiceMappings/CircleROI.ts | 33 ++++++++---------
.../measurementServiceMappings/CobbAngle.ts | 26 ++++++--------
.../EllipticalROI.ts | 25 ++++++-------
.../measurementServiceMappings/Length.ts | 24 ++++++-------
.../PlanarFreehandROI.ts | 35 +++++++++++--------
.../utils/measurementServiceMappings/Probe.ts | 29 ++++++++-------
.../RectangleROI.ts | 33 ++++++++---------
.../utils/getSOPInstanceAttributes.js | 16 +++++++--
extensions/measurement-tracking/package.json | 4 +--
.../promptSaveReport.js | 8 +++--
.../PanelMeasurementTableTracking/index.tsx | 23 +++++++++---
platform/app/package.json | 2 +-
platform/core/package.json | 2 +-
.../MeasurementService/MeasurementService.ts | 1 +
21 files changed, 181 insertions(+), 176 deletions(-)
diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json
index 8e7b062c0..38156a40b 100644
--- a/extensions/cornerstone-dicom-seg/package.json
+++ b/extensions/cornerstone-dicom-seg/package.json
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^1.74.7",
- "@cornerstonejs/core": "^1.74.7",
+ "@cornerstonejs/adapters": "^1.74.8",
+ "@cornerstonejs/core": "^1.74.8",
"@kitware/vtk.js": "30.4.1",
"react-color": "^2.19.3"
}
diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json
index cf6d09eb8..798aadcc7 100644
--- a/extensions/cornerstone-dicom-sr/package.json
+++ b/extensions/cornerstone-dicom-sr/package.json
@@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^1.74.7",
- "@cornerstonejs/core": "^1.74.7",
- "@cornerstonejs/tools": "^1.74.7",
+ "@cornerstonejs/adapters": "^1.74.8",
+ "@cornerstonejs/core": "^1.74.8",
+ "@cornerstonejs/tools": "^1.74.8",
"classnames": "^2.3.2"
}
}
diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json
index de60d3e89..7d12031e4 100644
--- a/extensions/cornerstone-dynamic-volume/package.json
+++ b/extensions/cornerstone-dynamic-volume/package.json
@@ -42,9 +42,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/core": "^1.74.7",
- "@cornerstonejs/streaming-image-volume-loader": "^1.74.7",
- "@cornerstonejs/tools": "^1.74.7",
+ "@cornerstonejs/core": "^1.74.8",
+ "@cornerstonejs/streaming-image-volume-loader": "^1.74.8",
+ "@cornerstonejs/tools": "^1.74.8",
"classnames": "^2.3.2"
}
}
diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json
index 4acf33832..6ea25abff 100644
--- a/extensions/cornerstone/package.json
+++ b/extensions/cornerstone/package.json
@@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.2",
"@cornerstonejs/codec-openjph": "^2.4.2",
- "@cornerstonejs/dicom-image-loader": "^1.74.7",
+ "@cornerstonejs/dicom-image-loader": "^1.74.8",
"@icr/polyseg-wasm": "^0.4.0",
"@ohif/core": "3.9.0-beta.23",
"@ohif/ui": "3.9.0-beta.23",
@@ -55,10 +55,10 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^1.74.7",
- "@cornerstonejs/core": "^1.74.7",
- "@cornerstonejs/streaming-image-volume-loader": "^1.74.7",
- "@cornerstonejs/tools": "^1.74.7",
+ "@cornerstonejs/adapters": "^1.74.8",
+ "@cornerstonejs/core": "^1.74.8",
+ "@cornerstonejs/streaming-image-volume-loader": "^1.74.8",
+ "@cornerstonejs/tools": "^1.74.8",
"@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "30.4.1",
"html2canvas": "^1.4.1",
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
index 2e178f2d5..1ef0ecf49 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
@@ -36,8 +36,8 @@ const Angle = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- CornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -48,7 +48,7 @@ const Angle = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -76,11 +76,12 @@ const Angle = {
data: data.cachedStats,
type: getValueTypeFromToolType(toolName),
getReport,
+ referencedImageId,
};
},
};
-function getMappedAnnotations(annotation, DisplaySetService) {
+function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
@@ -94,19 +95,14 @@ function getMappedAnnotations(annotation, DisplaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { angle } = targetStats;
const unit = '\u00B0';
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
index 373bd115c..18aee0c23 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
@@ -34,8 +34,8 @@ const Length = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- cornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -46,7 +46,7 @@ const Length = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -64,6 +64,7 @@ const Length = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -85,15 +86,14 @@ function getMappedAnnotations(annotation, displaySetService) {
const annotations = [];
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
annotations.push({
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
index 6517445d2..d2b1f81f9 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
@@ -31,8 +31,8 @@ const Bidirectional = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- cornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -43,7 +43,7 @@ const Bidirectional = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -63,6 +63,7 @@ const Bidirectional = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -89,19 +90,14 @@ function getMappedAnnotations(annotation, displaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { length, width, unit } = targetStats;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
index 88ca76862..1e2e85a3f 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
@@ -8,7 +8,7 @@ const CircleROI = {
toAnnotation: measurement => {},
toMeasurement: (
csToolsEventDetail,
- DisplaySetService,
+ displaySetService,
CornerstoneViewportService,
getValueTypeFromToolType,
customizationService
@@ -30,24 +30,24 @@ const CircleROI = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- CornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
if (SOPInstanceUID) {
- displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
+ displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
SeriesInstanceUID
);
} else {
- displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
- const mappedAnnotations = getMappedAnnotations(annotation, DisplaySetService);
+ const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
const getReport = () =>
@@ -62,6 +62,7 @@ const CircleROI = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -74,7 +75,7 @@ const CircleROI = {
},
};
-function getMappedAnnotations(annotation, DisplaySetService) {
+function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
@@ -88,20 +89,14 @@ function getMappedAnnotations(annotation, DisplaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- // Todo: Non-acquisition plane measurement mapping not supported yet
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, areaUnit, modalityUnit } = targetStats;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
index 631f0d029..91f2c1576 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
@@ -36,8 +36,8 @@ const CobbAngle = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- CornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -48,7 +48,7 @@ const CobbAngle = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -68,6 +68,7 @@ const CobbAngle = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations?.[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -80,7 +81,7 @@ const CobbAngle = {
},
};
-function getMappedAnnotations(annotation, DisplaySetService) {
+function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
@@ -94,19 +95,14 @@ function getMappedAnnotations(annotation, DisplaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { angle } = targetStats;
const unit = '\u00B0';
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
index c406b9972..54f156abb 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
@@ -30,8 +30,8 @@ const EllipticalROI = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- cornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -42,7 +42,7 @@ const EllipticalROI = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -62,6 +62,7 @@ const EllipticalROI = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -88,20 +89,14 @@ function getMappedAnnotations(annotation, displaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- // Todo: Non-acquisition plane measurement mapping not supported yet
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, areaUnit, modalityUnit } = targetStats;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
index bb1319b24..9ebad2b48 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
@@ -35,8 +35,8 @@ const Length = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- cornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
@@ -47,7 +47,7 @@ const Length = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
@@ -67,6 +67,7 @@ const Length = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -93,19 +94,14 @@ function getMappedAnnotations(annotation, displaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { length, unit = 'mm' } = targetStats;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
index d3c837c2a..10c6b9467 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
@@ -20,7 +20,7 @@ const PlanarFreehandROI = {
*/
toMeasurement: (
csToolsEventDetail,
- DisplaySetService,
+ displaySetService,
CornerstoneViewportService,
getValueTypeFromToolType,
customizationService
@@ -40,16 +40,16 @@ const PlanarFreehandROI = {
}
const { SOPInstanceUID, SeriesInstanceUID, frameNumber, StudyInstanceUID } =
- getSOPInstanceAttributes(referencedImageId);
+ getSOPInstanceAttributes(referencedImageId, displaySetService, annotation);
let displaySet;
if (SOPInstanceUID) {
- displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
+ displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
SeriesInstanceUID
);
} else {
- displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
return {
@@ -62,10 +62,11 @@ const PlanarFreehandROI = {
frameNumber,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
label: data.label,
- displayText: getDisplayText(annotation, displaySet, customizationService),
+ displayText: getDisplayText(annotation, displaySet, customizationService, displaySetService),
data: data.cachedStats,
type: getValueTypeFromToolType(toolName),
getReport: () => getColumnValueReport(annotation, customizationService),
@@ -122,17 +123,17 @@ function getColumnValueReport(annotation, customizationService) {
* @param {Object} displaySet - The display set object.
* @returns {string[]} - An array of display text.
*/
-function getDisplayText(annotation, displaySet, customizationService) {
+function getDisplayText(annotation, displaySet, customizationService, displaySetService) {
const { PlanarFreehandROI } = customizationService.get('cornerstone.measurements');
const { displayText } = PlanarFreehandROI;
const { metadata, data } = annotation;
- if (!data.cachedStats || !data.cachedStats[`imageId:${metadata.referencedImageId}`]) {
- return [];
- }
-
- const { SOPInstanceUID, frameNumber } = getSOPInstanceAttributes(metadata.referencedImageId);
+ const { SOPInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ metadata.referencedImageId,
+ displaySetService,
+ annotation
+ );
const displayTextArray = [];
@@ -150,7 +151,13 @@ function getDisplayText(annotation, displaySet, customizationService) {
displayTextArray.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
}
- const stats = data.cachedStats[`imageId:${metadata.referencedImageId}`];
+ const stats =
+ data.cachedStats[`imageId:${metadata.referencedImageId}`] ||
+ Array.from(Object.values(data.cachedStats))[0];
+
+ if (!stats) {
+ return displayTextArray;
+ }
const roundValues = values => {
if (Array.isArray(values)) {
@@ -158,10 +165,10 @@ function getDisplayText(annotation, displaySet, customizationService) {
if (isNaN(value)) {
return value;
}
- return utils.roundNumber(value);
+ return utils.roundNumber(value, 2);
});
}
- return isNaN(values) ? values : utils.roundNumber(values);
+ return isNaN(values) ? values : utils.roundNumber(values, 2);
};
const findUnitForValue = (displayTextItems, value) =>
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Probe.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Probe.ts
index 554df1842..7d0c89c29 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Probe.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Probe.ts
@@ -34,8 +34,11 @@ const Probe = {
throw new Error('Tool not supported');
}
- const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } =
- getSOPInstanceAttributes(referencedImageId);
+ const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
+ );
let displaySet;
@@ -45,7 +48,7 @@ const Probe = {
SeriesInstanceUID
);
} else {
- displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points } = data.handles;
@@ -64,6 +67,7 @@ const Probe = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations?.[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -76,7 +80,7 @@ const Probe = {
},
};
-function getMappedAnnotations(annotation, DisplaySetService) {
+function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
@@ -90,19 +94,14 @@ function getMappedAnnotations(annotation, DisplaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { value } = targetStats;
const unit = 'HU';
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
index fe94bfa27..61b2e1c47 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
@@ -8,7 +8,7 @@ const RectangleROI = {
toAnnotation: measurement => {},
toMeasurement: (
csToolsEventDetail,
- DisplaySetService,
+ displaySetService,
CornerstoneViewportService,
getValueTypeFromToolType,
customizationService
@@ -30,24 +30,24 @@ const RectangleROI = {
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
- CornerstoneViewportService,
- viewportId
+ displaySetService,
+ annotation
);
let displaySet;
if (SOPInstanceUID) {
- displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
+ displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
SeriesInstanceUID
);
} else {
- displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
}
const { points, textBox } = data.handles;
- const mappedAnnotations = getMappedAnnotations(annotation, DisplaySetService);
+ const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
const getReport = () =>
@@ -62,6 +62,7 @@ const RectangleROI = {
metadata,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
+ referencedImageId,
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -74,7 +75,7 @@ const RectangleROI = {
},
};
-function getMappedAnnotations(annotation, DisplaySetService) {
+function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
@@ -88,20 +89,14 @@ function getMappedAnnotations(annotation, DisplaySetService) {
Object.keys(cachedStats).forEach(targetId => {
const targetStats = cachedStats[targetId];
- if (!referencedImageId) {
- // Todo: Non-acquisition plane measurement mapping not supported yet
- throw new Error('Non-acquisition plane measurement mapping not supported');
- }
-
- const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
- getSOPInstanceAttributes(referencedImageId);
-
- const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } = getSOPInstanceAttributes(
+ referencedImageId,
+ displaySetService,
+ annotation
);
+ const displaySet = displaySetService.getDisplaySetsForSeries(SeriesInstanceUID)[0];
+
const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, modalityUnit, areaUnit } = targetStats;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js b/extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
index dd6992b83..101ef2117 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
@@ -7,12 +7,24 @@ import * as cornerstone from '@cornerstonejs/core';
* @param {string} imageId The image id of the referenced image
* @returns
*/
-export default function getSOPInstanceAttributes(imageId) {
+export default function getSOPInstanceAttributes(imageId, displaySetService, annotation) {
if (imageId) {
return _getUIDFromImageID(imageId);
}
- // Todo: implement for volume viewports and use the referencedSeriesInstanceUID
+ const { metadata } = annotation;
+ const { volumeId } = metadata;
+
+ const displaySet = displaySetService.getDisplaySetsBy(displaySet =>
+ volumeId.includes(displaySet.uid)
+ )[0];
+ const { StudyInstanceUID, SeriesInstanceUID } = displaySet;
+
+ return {
+ SOPInstanceUID: undefined,
+ SeriesInstanceUID,
+ StudyInstanceUID,
+ };
}
function _getUIDFromImageID(imageId) {
diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json
index bf67815b4..3fafcae08 100644
--- a/extensions/measurement-tracking/package.json
+++ b/extensions/measurement-tracking/package.json
@@ -32,8 +32,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
- "@cornerstonejs/core": "^1.74.7",
- "@cornerstonejs/tools": "^1.74.7",
+ "@cornerstonejs/core": "^1.74.8",
+ "@cornerstonejs/tools": "^1.74.8",
"@ohif/core": "3.9.0-beta.23",
"@ohif/extension-cornerstone-dicom-sr": "3.9.0-beta.23",
"@ohif/ui": "3.9.0-beta.23",
diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptSaveReport.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptSaveReport.js
index fd2d69872..3e98bcb2b 100644
--- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptSaveReport.js
+++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptSaveReport.js
@@ -21,9 +21,11 @@ async function promptSaveReport({ servicesManager, commandsManager, extensionMan
const dataSources = extensionManager.getDataSources();
const dataSource = dataSources[0];
const measurements = measurementService.getMeasurements();
- const trackedMeasurements = measurements.filter(
- m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID)
- );
+ const trackedMeasurements = measurements
+ .filter(
+ m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID)
+ )
+ .filter(m => m.referencedImageId != null);
const SeriesDescription =
// isUndefinedOrEmpty
diff --git a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
index ee7b65405..6ab9b4134 100644
--- a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
+++ b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
@@ -161,14 +161,18 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }: wi
};
const displayMeasurementsWithoutFindings = displayMeasurements.filter(
- dm => dm.measurementType !== measurementService.VALUE_TYPES.POINT
+ dm => dm.measurementType !== measurementService.VALUE_TYPES.POINT && dm.referencedImageId
);
const additionalFindings = displayMeasurements.filter(
- dm => dm.measurementType === measurementService.VALUE_TYPES.POINT
+ dm => dm.measurementType === measurementService.VALUE_TYPES.POINT && dm.referencedImageId
);
+ const nonAcquisitionMeasurements = displayMeasurements.filter(dm => dm.referencedImageId == null);
+
const disabled =
- additionalFindings.length === 0 && displayMeasurementsWithoutFindings.length === 0;
+ additionalFindings.length === 0 &&
+ displayMeasurementsWithoutFindings.length === 0 &&
+ nonAcquisitionMeasurements.length === 0;
return (
<>
@@ -200,6 +204,15 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }: wi
onEdit={onMeasurementItemEditHandler}
/>
)}
+ {nonAcquisitionMeasurements.length !== 0 && (
+