From 2b83393f91cb16ea06821d79d14ff60f80c29c90 Mon Sep 17 00:00:00 2001
From: Ibrahim <93064150+IbrahimCSAE@users.noreply.github.com>
Date: Wed, 10 Apr 2024 11:34:13 -0400
Subject: [PATCH] fix(general): enhancements and bug fixes (#4018)
---
.../src/Viewport/OHIFCornerstoneViewport.tsx | 1 +
.../cornerstone/src/getCustomizationModule.ts | 130 ++++++++++++
.../cornerstone/src/initMeasurementService.js | 35 +++-
.../cornerstone/src/utils/callInputDialog.tsx | 5 +-
.../utils/measurementServiceMappings/Angle.ts | 12 +-
.../ArrowAnnotate.ts | 7 +-
.../Bidirectional.ts | 12 +-
.../measurementServiceMappings/CircleROI.ts | 12 +-
.../measurementServiceMappings/CobbAngle.ts | 12 +-
.../EllipticalROI.ts | 12 +-
.../measurementServiceMappings/Length.ts | 37 ++--
.../LivewireContour.ts | 161 +++++++++++++++
.../PlanarFreehandROI.ts | 104 ++++------
.../RectangleROI.ts | 12 +-
.../measurementServiceMappings/SplineROI.ts | 188 ++++++++++++++++++
.../constants/supportedTools.js | 2 +
.../measurementServiceMappingsFactory.ts | 68 ++++++-
.../promptBeginTracking.js | 6 +
.../promptTrackNewStudy.js | 6 +
modes/basic-test-mode/src/initToolGroups.ts | 2 +
modes/basic-test-mode/src/moreTools.ts | 2 +-
modes/longitudinal/src/initToolGroups.js | 2 +
modes/longitudinal/src/moreTools.ts | 2 +-
modes/longitudinal/src/toolbarButtons.ts | 8 -
modes/segmentation/src/toolbarButtons.ts | 2 +-
platform/app/src/routes/WorkList/WorkList.tsx | 2 +-
.../services/UIViewportDialogService/index.js | 3 +-
platform/ui/src/assets/styles/styles.css | 4 +
.../components/Notification/Notification.tsx | 9 +-
.../ViewportDialogProvider.tsx | 3 +
30 files changed, 710 insertions(+), 151 deletions(-)
create mode 100644 extensions/cornerstone/src/utils/measurementServiceMappings/LivewireContour.ts
create mode 100644 extensions/cornerstone/src/utils/measurementServiceMappings/SplineROI.ts
diff --git a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
index 11b4fbe07..b9e58a71f 100644
--- a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
+++ b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
@@ -444,6 +444,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
actions={viewportDialogState.actions}
onSubmit={viewportDialogState.onSubmit}
onOutsideClick={viewportDialogState.onOutsideClick}
+ onKeyPress={viewportDialogState.onKeyPress}
/>
)}
diff --git a/extensions/cornerstone/src/getCustomizationModule.ts b/extensions/cornerstone/src/getCustomizationModule.ts
index 90bf67f6c..ea07e9694 100644
--- a/extensions/cornerstone/src/getCustomizationModule.ts
+++ b/extensions/cornerstone/src/getCustomizationModule.ts
@@ -64,6 +64,136 @@ function getCustomizationModule() {
step: 1,
},
},
+ {
+ id: 'cornerstone.measurements',
+ Angle: {
+ displayText: [],
+ report: [],
+ },
+ CobbAngle: {
+ displayText: [],
+ report: [],
+ },
+ ArrowAnnotate: {
+ displayText: [],
+ report: [],
+ },
+ RectangleROi: {
+ displayText: [],
+ report: [],
+ },
+ CircleROI: {
+ displayText: [],
+ report: [],
+ },
+ EllipticalROI: {
+ displayText: [],
+ report: [],
+ },
+ Bidirectional: {
+ displayText: [],
+ report: [],
+ },
+ Length: {
+ displayText: [],
+ report: [],
+ },
+ LivewireContour: {
+ displayText: [],
+ report: [],
+ },
+ SplineROI: {
+ displayText: [
+ {
+ displayName: 'Area',
+ value: 'area',
+ type: 'value',
+ },
+ {
+ value: 'areaUnit',
+ for: ['area'],
+ type: 'unit',
+ },
+ /**
+ {
+ displayName: 'Modality',
+ value: 'Modality',
+ type: 'value',
+ },
+ */
+ ],
+ report: [
+ {
+ displayName: 'Area',
+ value: 'area',
+ type: 'value',
+ },
+ {
+ displayName: 'Unit',
+ value: 'areaUnit',
+ type: 'value',
+ },
+ ],
+ },
+ PlanarFreehandROI: {
+ displayText: [
+ {
+ displayName: 'Mean',
+ value: 'mean',
+ type: 'value',
+ },
+ {
+ displayName: 'Max',
+ value: 'max',
+ type: 'value',
+ },
+ {
+ displayName: 'Area',
+ value: 'area',
+ type: 'value',
+ },
+ {
+ value: 'modalityUnit',
+ for: ['mean', 'max' /** 'stdDev **/],
+ type: 'unit',
+ },
+ {
+ value: 'areaUnit',
+ for: ['area'],
+ type: 'unit',
+ },
+ /**
+ {
+ displayName: 'Std Dev',
+ value: 'stdDev',
+ type: 'value',
+ },
+ */
+ ],
+ report: [
+ {
+ displayName: 'Mean',
+ value: 'mean',
+ type: 'value',
+ },
+ {
+ displayName: 'Max',
+ value: 'max',
+ type: 'value',
+ },
+ {
+ displayName: 'Area',
+ value: 'area',
+ type: 'value',
+ },
+ {
+ displayName: 'Unit',
+ value: 'unit',
+ type: 'value',
+ },
+ ],
+ },
+ },
],
},
];
diff --git a/extensions/cornerstone/src/initMeasurementService.js b/extensions/cornerstone/src/initMeasurementService.js
index c19e46c71..61145aa18 100644
--- a/extensions/cornerstone/src/initMeasurementService.js
+++ b/extensions/cornerstone/src/initMeasurementService.js
@@ -17,7 +17,8 @@ const CORNERSTONE_3D_TOOLS_SOURCE_VERSION = '0.1';
const initMeasurementService = (
measurementService,
displaySetService,
- cornerstoneViewportService
+ cornerstoneViewportService,
+ customizationService
) => {
/* Initialization */
const {
@@ -30,10 +31,13 @@ const initMeasurementService = (
CobbAngle,
RectangleROI,
PlanarFreehandROI,
+ SplineROI,
+ LivewireContour,
} = measurementServiceMappingsFactory(
measurementService,
displaySetService,
- cornerstoneViewportService
+ cornerstoneViewportService,
+ customizationService
);
const csTools3DVer1MeasurementSource = measurementService.createSource(
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
@@ -127,6 +131,14 @@ const initMeasurementService = (
PlanarFreehandROI.toMeasurement
);
+ measurementService.addMapping(
+ csTools3DVer1MeasurementSource,
+ 'SplineROI',
+ SplineROI.matchingCriteria,
+ SplineROI.toAnnotation,
+ SplineROI.toMeasurement
+ );
+
// On the UI side, the Calibration Line tool will work almost the same as the
// Length tool
measurementService.addMapping(
@@ -137,16 +149,29 @@ const initMeasurementService = (
Length.toMeasurement
);
+ measurementService.addMapping(
+ csTools3DVer1MeasurementSource,
+ 'LivewireContour',
+ LivewireContour.matchingCriteria,
+ LivewireContour.toAnnotation,
+ LivewireContour.toMeasurement
+ );
+
return csTools3DVer1MeasurementSource;
};
const connectToolsToMeasurementService = servicesManager => {
- const { measurementService, displaySetService, cornerstoneViewportService } =
- servicesManager.services;
+ const {
+ measurementService,
+ displaySetService,
+ cornerstoneViewportService,
+ customizationService,
+ } = servicesManager.services;
const csTools3DVer1MeasurementSource = initMeasurementService(
measurementService,
displaySetService,
- cornerstoneViewportService
+ cornerstoneViewportService,
+ customizationService
);
connectMeasurementServiceToTools(
measurementService,
diff --git a/extensions/cornerstone/src/utils/callInputDialog.tsx b/extensions/cornerstone/src/utils/callInputDialog.tsx
index e450536ea..05946b87f 100644
--- a/extensions/cornerstone/src/utils/callInputDialog.tsx
+++ b/extensions/cornerstone/src/utils/callInputDialog.tsx
@@ -109,13 +109,10 @@ export function callLabelAutocompleteDialog(uiDialogService, callback, dialogCon
uiDialogService.create({
id: 'select-annotation',
+ centralize: true,
isDraggable: false,
showOverlay: true,
content: LabellingFlow,
- defaultPosition: {
- x: window.innerWidth / 2,
- y: window.innerHeight / 2,
- },
contentProps: {
labellingDoneCallback: labellingDoneCallback,
measurementData: { label: '' },
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
index 7173e1344..2e178f2d5 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Angle.ts
@@ -16,7 +16,8 @@ const Angle = {
csToolsEventDetail,
displaySetService,
CornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -54,8 +55,9 @@ const Angle = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -127,7 +129,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -160,7 +162,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
index 3d5904171..373bd115c 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/ArrowAnnotate.ts
@@ -14,7 +14,8 @@ const Length = {
csToolsEventDetail,
displaySetService,
cornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -52,7 +53,7 @@ const Length = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
return {
uid: annotationUID,
@@ -106,7 +107,7 @@ function getMappedAnnotations(annotation, displaySetService) {
return annotations;
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
index 958e22ed6..6517445d2 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
@@ -11,7 +11,8 @@ const Bidirectional = {
csToolsEventDetail,
displaySetService,
cornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -49,8 +50,9 @@ const Bidirectional = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -122,7 +124,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -155,7 +157,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
index e65564c81..c995fb171 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/CircleROI.ts
@@ -9,7 +9,8 @@ const CircleROI = {
csToolsEventDetail,
DisplaySetService,
CornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -47,8 +48,9 @@ const CircleROI = {
const mappedAnnotations = getMappedAnnotations(annotation, DisplaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -125,7 +127,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -163,7 +165,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
index dbde82860..631f0d029 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/CobbAngle.ts
@@ -16,7 +16,8 @@ const CobbAngle = {
csToolsEventDetail,
displaySetService,
CornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -54,8 +55,9 @@ const CobbAngle = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -127,7 +129,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -160,7 +162,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
index 1882d9ba0..30a925dd1 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
@@ -9,7 +9,8 @@ const EllipticalROI = {
csToolsEventDetail,
displaySetService,
cornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -47,8 +48,9 @@ const EllipticalROI = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -125,7 +127,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -163,7 +165,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
index e5e9886b3..bb1319b24 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
@@ -15,7 +15,8 @@ const Length = {
csToolsEventDetail,
displaySetService,
cornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -32,11 +33,7 @@ const Length = {
throw new Error('Tool not supported');
}
- const {
- SOPInstanceUID,
- SeriesInstanceUID,
- StudyInstanceUID,
- } = getSOPInstanceAttributes(
+ const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
referencedImageId,
cornerstoneViewportService,
viewportId
@@ -57,8 +54,9 @@ const Length = {
const mappedAnnotations = getMappedAnnotations(annotation, displaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -99,11 +97,8 @@ function getMappedAnnotations(annotation, displaySetService) {
throw new Error('Non-acquisition plane measurement mapping not supported');
}
- const {
- SOPInstanceUID,
- SeriesInstanceUID,
- frameNumber,
- } = getSOPInstanceAttributes(referencedImageId);
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
+ getSOPInstanceAttributes(referencedImageId);
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
@@ -132,7 +127,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -167,7 +162,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
@@ -175,13 +170,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];
// Area is the same for all series
- const {
- length,
- SeriesNumber,
- SOPInstanceUID,
- frameNumber,
- unit,
- } = mappedAnnotations[0];
+ const { length, SeriesNumber, SOPInstanceUID, frameNumber, unit } = mappedAnnotations[0];
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
@@ -197,9 +186,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
return displayText;
}
const roundedLength = utils.roundNumber(length, 2);
- displayText.push(
- `${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
- );
+ displayText.push(`${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
return displayText;
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/LivewireContour.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/LivewireContour.ts
new file mode 100644
index 000000000..4c2d3f56f
--- /dev/null
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/LivewireContour.ts
@@ -0,0 +1,161 @@
+import SUPPORTED_TOOLS from './constants/supportedTools';
+import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
+import { getDisplayUnit } from './utils';
+import { utils } from '@ohif/core';
+
+/**
+ * Represents a mapping utility for Livewire measurements.
+ */
+const LivewireContour = {
+ toAnnotation: measurement => {},
+
+ /**
+ * Maps cornerstone annotation event data to measurement service format.
+ *
+ * @param {Object} csToolsEventDetail Cornerstone event data
+ * @param {DisplaySetService} DisplaySetService Service for managing display sets
+ * @param {CornerstoneViewportService} CornerstoneViewportService Service for managing viewports
+ * @param {Function} getValueTypeFromToolType Function to get value type from tool type
+ * @returns {Measurement} Measurement instance
+ */
+ toMeasurement: (
+ csToolsEventDetail,
+ DisplaySetService,
+ CornerstoneViewportService,
+ getValueTypeFromToolType,
+ customizationService
+ ) => {
+ const { annotation } = csToolsEventDetail;
+ const { metadata, data, annotationUID } = annotation;
+
+ if (!metadata || !data) {
+ console.warn('Livewire tool: Missing metadata or data');
+ return null;
+ }
+
+ const { toolName, referencedImageId, FrameOfReferenceUID } = metadata;
+ const validToolType = SUPPORTED_TOOLS.includes(toolName);
+ if (!validToolType) {
+ throw new Error(`Tool ${toolName} not supported`);
+ }
+
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber, StudyInstanceUID } =
+ getSOPInstanceAttributes(referencedImageId);
+
+ let displaySet;
+ if (SOPInstanceUID) {
+ displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
+ SOPInstanceUID,
+ SeriesInstanceUID
+ );
+ } else {
+ displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ }
+
+ return {
+ uid: annotationUID,
+ SOPInstanceUID,
+ FrameOfReferenceUID,
+ points: data.contour.polyline,
+ textBox: data.handles.textBox,
+ metadata,
+ frameNumber,
+ referenceSeriesUID: SeriesInstanceUID,
+ referenceStudyUID: StudyInstanceUID,
+ toolName: metadata.toolName,
+ displaySetInstanceUID: displaySet.displaySetInstanceUID,
+ label: data.label,
+ displayText: getDisplayText(annotation, displaySet, customizationService),
+ data: data.cachedStats,
+ type: getValueTypeFromToolType(toolName),
+ getReport: () => getColumnValueReport(annotation, customizationService),
+ };
+ },
+};
+
+/**
+ * This function is used to convert the measurement data to a
+ * format that is suitable for report generation (e.g. for the csv report).
+ * The report returns a list of columns and corresponding values.
+ *
+ * @param {object} annotation
+ * @returns {object} Report's content from this tool
+ */
+function getColumnValueReport(annotation, customizationService) {
+ const columns = [];
+ const values = [];
+
+ /** Add type */
+ columns.push('AnnotationType');
+ values.push('Cornerstone:Livewire');
+
+ /** Add cachedStats */
+ const { metadata, data } = annotation;
+
+ /** Add FOR */
+ if (metadata.FrameOfReferenceUID) {
+ columns.push('FrameOfReferenceUID');
+ values.push(metadata.FrameOfReferenceUID);
+ }
+
+ /** Add points */
+ if (data.contour.polyline) {
+ /**
+ * Points has the form of [[x1, y1, z1], [x2, y2, z2], ...]
+ * convert it to string of [[x1 y1 z1];[x2 y2 z2];...]
+ * so that it can be used in the CSV report
+ */
+ columns.push('points');
+ values.push(data.contour.polyline.map(p => p.join(' ')).join(';'));
+ }
+
+ return { columns, values };
+}
+
+/**
+ * Retrieves the display text for an annotation in a display set.
+ *
+ * @param {Object} annotation - The annotation object.
+ * @param {Object} displaySet - The display set object.
+ * @returns {string[]} - An array of display text.
+ */
+function getDisplayText(annotation, displaySet, customizationService) {
+ const { metadata, data } = annotation;
+
+ if (!data.cachedStats || !data.cachedStats[`imageId:${metadata.referencedImageId}`]) {
+ return [];
+ }
+
+ const { area, areaUnit } = data.cachedStats[`imageId:${metadata.referencedImageId}`];
+
+ const { SOPInstanceUID, frameNumber } = getSOPInstanceAttributes(metadata.referencedImageId);
+
+ const displayText = [];
+
+ const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
+ let InstanceNumber;
+ if (instance) {
+ InstanceNumber = instance.InstanceNumber;
+ }
+
+ const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
+ const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
+
+ const { SeriesNumber } = displaySet;
+ if (SeriesNumber) {
+ displayText.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
+ }
+
+ if (area) {
+ /**
+ * Add Area
+ * Area sometimes becomes undefined if `preventHandleOutsideImage` is off
+ */
+ const roundedArea = utils.roundNumber(area || 0, 2);
+ displayText.push(`${roundedArea} ${getDisplayUnit(areaUnit)}`);
+ }
+
+ return displayText;
+}
+
+export default LivewireContour;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
index 3820522b1..d3c837c2a 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/PlanarFreehandROI.ts
@@ -22,7 +22,8 @@ const PlanarFreehandROI = {
csToolsEventDetail,
DisplaySetService,
CornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -64,10 +65,10 @@ const PlanarFreehandROI = {
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
label: data.label,
- displayText: getDisplayText(annotation, displaySet),
+ displayText: getDisplayText(annotation, displaySet, customizationService),
data: data.cachedStats,
type: getValueTypeFromToolType(toolName),
- getReport: () => getColumnValueReport(annotation),
+ getReport: () => getColumnValueReport(annotation, customizationService),
};
},
};
@@ -80,7 +81,9 @@ const PlanarFreehandROI = {
* @param {object} annotation
* @returns {object} Report's content from this tool
*/
-function getColumnValueReport(annotation) {
+function getColumnValueReport(annotation, customizationService) {
+ const { PlanarFreehandROI } = customizationService.get('cornerstone.measurements');
+ const { report } = PlanarFreehandROI;
const columns = [];
const values = [];
@@ -90,10 +93,12 @@ function getColumnValueReport(annotation) {
/** Add cachedStats */
const { metadata, data } = annotation;
- const { mean, stdDev, max, area, unit, areaUnit, perimeter } =
- data.cachedStats[`imageId:${metadata.referencedImageId}`];
- columns.push(`Maximum`, `Mean`, `Std Dev`, 'Pixel Unit', `Area`, 'Unit', 'Perimeter');
- values.push(max, mean, stdDev, unit, area, areaUnit, perimeter);
+ const stats = data.cachedStats[`imageId:${metadata.referencedImageId}`];
+
+ report.forEach(({ name, value }) => {
+ columns.push(name);
+ stats[value] ? values.push(stats[value]) : values.push('not available');
+ });
/** Add FOR */
if (metadata.FrameOfReferenceUID) {
@@ -103,11 +108,6 @@ function getColumnValueReport(annotation) {
/** Add points */
if (data.contour.polyline) {
- /**
- * Points has the form of [[x1, y1, z1], [x2, y2, z2], ...]
- * convert it to string of [[x1 y1 z1];[x2 y2 z2];...]
- * so that it can be used in the CSV report
- */
columns.push('points');
values.push(data.contour.polyline.map(p => p.join(' ')).join(';'));
}
@@ -122,19 +122,19 @@ function getColumnValueReport(annotation) {
* @param {Object} displaySet - The display set object.
* @returns {string[]} - An array of display text.
*/
-function getDisplayText(annotation, displaySet) {
+function getDisplayText(annotation, displaySet, customizationService) {
+ const { PlanarFreehandROI } = customizationService.get('cornerstone.measurements');
+ const { displayText } = PlanarFreehandROI;
+
const { metadata, data } = annotation;
if (!data.cachedStats || !data.cachedStats[`imageId:${metadata.referencedImageId}`]) {
return [];
}
- const { mean, stdDev, max, area, modalityUnit, areaUnit, perimeter } =
- data.cachedStats[`imageId:${metadata.referencedImageId}`];
-
const { SOPInstanceUID, frameNumber } = getSOPInstanceAttributes(metadata.referencedImageId);
- const displayText = [];
+ const displayTextArray = [];
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
let InstanceNumber;
@@ -147,55 +147,39 @@ function getDisplayText(annotation, displaySet) {
const { SeriesNumber } = displaySet;
if (SeriesNumber) {
- displayText.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
+ displayTextArray.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
}
- if (area) {
- /**
- * Add Area
- * Area sometimes becomes undefined if `preventHandleOutsideImage` is off
- */
- const roundedArea = utils.roundNumber(area || 0, 2);
- displayText.push(`Area: ${roundedArea} ${getDisplayUnit(areaUnit)}`);
- }
+ const stats = data.cachedStats[`imageId:${metadata.referencedImageId}`];
- if (mean) {
- if (Array.isArray(mean)) {
- const meanValues = mean.map(value => utils.roundNumber(value));
- displayText.push(`Mean: ${meanValues.join(', ')} ${modalityUnit}`);
- } else {
- displayText.push(`Mean: ${utils.roundNumber(mean)} ${modalityUnit}`);
+ const roundValues = values => {
+ if (Array.isArray(values)) {
+ return values.map(value => {
+ if (isNaN(value)) {
+ return value;
+ }
+ return utils.roundNumber(value);
+ });
}
- }
+ return isNaN(values) ? values : utils.roundNumber(values);
+ };
- if (max) {
- if (Array.isArray(max)) {
- const maxValues = max.map(value => utils.roundNumber(value, 2));
- displayText.push(`Max: ${maxValues.join(', ')} ${modalityUnit}`);
- } else {
- displayText.push(`Max: ${utils.roundNumber(max, 2)} ${modalityUnit}`);
+ const findUnitForValue = (displayTextItems, value) =>
+ displayTextItems.find(({ type, for: filter }) => type === 'unit' && filter.includes(value))
+ ?.value;
+
+ const formatDisplayText = (displayName, result, unit) =>
+ `${displayName}: ${Array.isArray(result) ? roundValues(result).join(', ') : roundValues(result)} ${unit}`;
+
+ displayText.forEach(({ displayName, value, type }) => {
+ if (type === 'value') {
+ const result = stats[value];
+ const unit = stats[findUnitForValue(displayText, value)] || '';
+ displayTextArray.push(formatDisplayText(displayName, result, unit));
}
- }
+ });
- if (stdDev) {
- if (Array.isArray(stdDev)) {
- const stdDevValues = stdDev.map(value => utils.roundNumber(value));
- displayText.push(`Std Dev: ${stdDevValues.join(', ')} ${modalityUnit}`);
- } else {
- displayText.push(`Std Dev: ${utils.roundNumber(stdDev)} ${modalityUnit}`);
- }
- }
-
- if (perimeter) {
- if (Array.isArray(perimeter)) {
- const perimeterValues = perimeter.map(value => utils.roundNumber(value));
- displayText.push(`Perimeter: ${perimeterValues.join(', ')} ${modalityUnit}`);
- } else {
- displayText.push(`Perimeter: ${utils.roundNumber(perimeter)} ${modalityUnit}`);
- }
- }
-
- return displayText;
+ return displayTextArray;
}
export default PlanarFreehandROI;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
index 6c7e4b4ca..943822de7 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/RectangleROI.ts
@@ -9,7 +9,8 @@ const RectangleROI = {
csToolsEventDetail,
DisplaySetService,
CornerstoneViewportService,
- getValueTypeFromToolType
+ getValueTypeFromToolType,
+ customizationService
) => {
const { annotation, viewportId } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -47,8 +48,9 @@ const RectangleROI = {
const mappedAnnotations = getMappedAnnotations(annotation, DisplaySetService);
- const displayText = getDisplayText(mappedAnnotations, displaySet);
- const getReport = () => _getReport(mappedAnnotations, points, FrameOfReferenceUID);
+ const displayText = getDisplayText(mappedAnnotations, displaySet, customizationService);
+ const getReport = () =>
+ _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService);
return {
uid: annotationUID,
@@ -125,7 +127,7 @@ This function is used to convert the measurement data to a format that is
suitable for the report generation (e.g. for the csv report). The report
returns a list of columns and corresponding values.
*/
-function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
+function _getReport(mappedAnnotations, points, FrameOfReferenceUID, customizationService) {
const columns = [];
const values = [];
@@ -163,7 +165,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
};
}
-function getDisplayText(mappedAnnotations, displaySet) {
+function getDisplayText(mappedAnnotations, displaySet, customizationService) {
if (!mappedAnnotations || !mappedAnnotations.length) {
return '';
}
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/SplineROI.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/SplineROI.ts
new file mode 100644
index 000000000..05ed5b1dc
--- /dev/null
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/SplineROI.ts
@@ -0,0 +1,188 @@
+import SUPPORTED_TOOLS from './constants/supportedTools';
+import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
+import { getDisplayUnit } from './utils';
+import { utils } from '@ohif/core';
+
+/**
+ * Represents a mapping utility for Spline ROI measurements.
+ */
+const SplineROI = {
+ toAnnotation: measurement => {},
+
+ /**
+ * Maps cornerstone annotation event data to measurement service format.
+ *
+ * @param {Object} csToolsEventDetail Cornerstone event data
+ * @param {DisplaySetService} DisplaySetService Service for managing display sets
+ * @param {CornerstoneViewportService} CornerstoneViewportService Service for managing viewports
+ * @param {Function} getValueTypeFromToolType Function to get value type from tool type
+ * @returns {Measurement} Measurement instance
+ */
+ toMeasurement: (
+ csToolsEventDetail,
+ DisplaySetService,
+ CornerstoneViewportService,
+ getValueTypeFromToolType,
+ customizationService
+ ) => {
+ const { annotation } = csToolsEventDetail;
+ const { metadata, data, annotationUID } = annotation;
+
+ if (!metadata || !data) {
+ console.warn('SplineROI tool: Missing metadata or data');
+ return null;
+ }
+
+ const { toolName, referencedImageId, FrameOfReferenceUID } = metadata;
+ const validToolType = SUPPORTED_TOOLS.includes(toolName);
+ if (!validToolType) {
+ throw new Error(`Tool ${toolName} not supported`);
+ }
+
+ const { SOPInstanceUID, SeriesInstanceUID, frameNumber, StudyInstanceUID } =
+ getSOPInstanceAttributes(referencedImageId);
+
+ let displaySet;
+ if (SOPInstanceUID) {
+ displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
+ SOPInstanceUID,
+ SeriesInstanceUID
+ );
+ } else {
+ displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
+ }
+
+ return {
+ uid: annotationUID,
+ SOPInstanceUID,
+ FrameOfReferenceUID,
+ points: data.contour.polyline,
+ textBox: data.handles.textBox,
+ metadata,
+ frameNumber,
+ referenceSeriesUID: SeriesInstanceUID,
+ referenceStudyUID: StudyInstanceUID,
+ toolName: metadata.toolName,
+ displaySetInstanceUID: displaySet.displaySetInstanceUID,
+ label: data.label,
+ displayText: getDisplayText(annotation, displaySet, customizationService),
+ data: data.cachedStats,
+ type: getValueTypeFromToolType(toolName),
+ getReport: () => getColumnValueReport(annotation, customizationService),
+ };
+ },
+};
+
+/**
+ * This function is used to convert the measurement data to a
+ * format that is suitable for report generation (e.g. for the csv report).
+ * The report returns a list of columns and corresponding values.
+ *
+ * @param {object} annotation
+ * @returns {object} Report's content from this tool
+ */
+function getColumnValueReport(annotation, customizationService) {
+ const { SplineROI } = customizationService.get('cornerstone.measurements');
+ const { report } = SplineROI;
+ const columns = [];
+ const values = [];
+
+ /** Add type */
+ columns.push('AnnotationType');
+ values.push('Cornerstone:SplineROI');
+
+ /** Add cachedStats */
+ const { metadata, data } = annotation;
+ const stats = data.cachedStats[`imageId:${metadata.referencedImageId}`];
+
+ report.forEach(({ name, value }) => {
+ columns.push(name);
+ stats[value] ? values.push(stats[value]) : values.push('not available');
+ });
+
+ /** Add FOR */
+ if (metadata.FrameOfReferenceUID) {
+ columns.push('FrameOfReferenceUID');
+ values.push(metadata.FrameOfReferenceUID);
+ }
+
+ /** Add points */
+ if (data.contour.polyline) {
+ /**
+ * Points has the form of [[x1, y1, z1], [x2, y2, z2], ...]
+ * convert it to string of [[x1 y1 z1];[x2 y2 z2];...]
+ * so that it can be used in the CSV report
+ */
+ columns.push('points');
+ values.push(data.contour.polyline.map(p => p.join(' ')).join(';'));
+ }
+
+ return { columns, values };
+}
+
+/**
+ * Retrieves the display text for an annotation in a display set.
+ *
+ * @param {Object} annotation - The annotation object.
+ * @param {Object} displaySet - The display set object.
+ * @returns {string[]} - An array of display text.
+ */
+function getDisplayText(annotation, displaySet, customizationService) {
+ const { SplineROI } = customizationService.get('cornerstone.measurements');
+ const { displayText } = SplineROI;
+ const { metadata, data } = annotation;
+
+ if (!data.cachedStats || !data.cachedStats[`imageId:${metadata.referencedImageId}`]) {
+ return [];
+ }
+ const { SOPInstanceUID, frameNumber } = getSOPInstanceAttributes(metadata.referencedImageId);
+
+ const displayTextArray = [];
+
+ const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
+ let InstanceNumber;
+ if (instance) {
+ InstanceNumber = instance.InstanceNumber;
+ }
+
+ const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
+ const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
+
+ const { SeriesNumber } = displaySet;
+ if (SeriesNumber) {
+ displayTextArray.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
+ }
+
+ const stats = data.cachedStats[`imageId:${metadata.referencedImageId}`];
+
+ const roundValues = values => {
+ if (Array.isArray(values)) {
+ return values.map(value => {
+ if (isNaN(value)) {
+ return value;
+ }
+ return utils.roundNumber(value);
+ });
+ }
+ return isNaN(values) ? values : utils.roundNumber(values);
+ };
+
+ const findUnitForValue = (displayTextItems, value) =>
+ displayTextItems.find(({ type, for: filter }) => type === 'unit' && filter.includes(value))
+ ?.value;
+
+ const formatDisplayText = (displayName, result, unit) =>
+ `${displayName}: ${Array.isArray(result) ? roundValues(result).join(', ') : roundValues(result)} ${unit}`;
+
+ displayText.forEach(({ displayName, value, type }) => {
+ if (type === 'value') {
+ const result = stats[value];
+ const unit = stats[findUnitForValue(displayText, value)] || '';
+ displayTextArray.push(formatDisplayText(displayName, result, unit));
+ }
+ });
+
+ return displayTextArray;
+}
+
+export default SplineROI;
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js b/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
index e1e8a1755..8f69319da 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
@@ -9,4 +9,6 @@ export default [
'Probe',
'RectangleROI',
'PlanarFreehandROI',
+ 'SplineROI',
+ 'LivewireContour',
];
diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts
index e3ccf4e51..19de0308f 100644
--- a/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts
+++ b/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts
@@ -8,11 +8,14 @@ import CobbAngle from './CobbAngle';
import Angle from './Angle';
import PlanarFreehandROI from './PlanarFreehandROI';
import RectangleROI from './RectangleROI';
+import SplineROI from './SplineROI';
+import LivewireContour from './LivewireContour';
const measurementServiceMappingsFactory = (
measurementService: MeasurementService,
displaySetService,
- cornerstoneViewportService
+ cornerstoneViewportService,
+ customizationService
) => {
/**
* Maps measurement service format object to cornerstone annotation object.
@@ -39,6 +42,8 @@ const measurementServiceMappingsFactory = (
ArrowAnnotate: POINT,
CobbAngle: ANGLE,
Angle: ANGLE,
+ SplineROI: POLYLINE,
+ LivewireContour: POLYLINE,
};
return TOOL_TYPE_TO_VALUE_TYPE[toolType];
@@ -52,7 +57,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -68,7 +74,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
// TODO -> We should eventually do something like shortAxis + longAxis,
@@ -91,7 +98,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -107,7 +115,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -123,7 +132,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -139,7 +149,42 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
+ ),
+ matchingCriteria: [
+ {
+ valueType: MeasurementService.VALUE_TYPES.POLYLINE,
+ },
+ ],
+ },
+
+ SplineROI: {
+ toAnnotation: SplineROI.toAnnotation,
+ toMeasurement: csToolsAnnotation =>
+ SplineROI.toMeasurement(
+ csToolsAnnotation,
+ displaySetService,
+ cornerstoneViewportService,
+ _getValueTypeFromToolType,
+ customizationService
+ ),
+ matchingCriteria: [
+ {
+ valueType: MeasurementService.VALUE_TYPES.POLYLINE,
+ },
+ ],
+ },
+
+ LivewireContour: {
+ toAnnotation: LivewireContour.toAnnotation,
+ toMeasurement: csToolsAnnotation =>
+ LivewireContour.toMeasurement(
+ csToolsAnnotation,
+ displaySetService,
+ cornerstoneViewportService,
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -155,7 +200,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -172,7 +218,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
@@ -188,7 +235,8 @@ const measurementServiceMappingsFactory = (
csToolsAnnotation,
displaySetService,
cornerstoneViewportService,
- _getValueTypeFromToolType
+ _getValueTypeFromToolType,
+ customizationService
),
matchingCriteria: [
{
diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptBeginTracking.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptBeginTracking.js
index acf298146..d8bb02b99 100644
--- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptBeginTracking.js
+++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptBeginTracking.js
@@ -66,6 +66,12 @@ function _askTrackMeasurements(uiViewportDialogService, viewportId) {
uiViewportDialogService.hide();
resolve(RESPONSE.CANCEL);
},
+ onKeyPress: event => {
+ if (event.key === 'Enter') {
+ const action = actions.find(action => action.id === 'prompt-begin-tracking-yes');
+ onSubmit(action.value);
+ }
+ },
});
});
}
diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js
index 2837de7cb..b590af3f6 100644
--- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js
+++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js
@@ -65,6 +65,12 @@ function _askTrackMeasurements(UIViewportDialogService, viewportId) {
UIViewportDialogService.hide();
resolve(RESPONSE.CANCEL);
},
+ onKeyPress: event => {
+ if (event.key === 'Enter') {
+ const action = actions.find(action => action.value === RESPONSE.SET_STUDY_AND_SERIES);
+ onSubmit(action.value);
+ }
+ },
});
});
}
diff --git a/modes/basic-test-mode/src/initToolGroups.ts b/modes/basic-test-mode/src/initToolGroups.ts
index a791d6ab0..5feb3214b 100644
--- a/modes/basic-test-mode/src/initToolGroups.ts
+++ b/modes/basic-test-mode/src/initToolGroups.ts
@@ -42,6 +42,7 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage
},
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
+ { toolName: toolNames.Probe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.CircleROI },
{ toolName: toolNames.RectangleROI },
@@ -170,6 +171,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
},
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
+ { toolName: toolNames.Probe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.CircleROI },
{ toolName: toolNames.RectangleROI },
diff --git a/modes/basic-test-mode/src/moreTools.ts b/modes/basic-test-mode/src/moreTools.ts
index 5f49e08ad..5708c2a17 100644
--- a/modes/basic-test-mode/src/moreTools.ts
+++ b/modes/basic-test-mode/src/moreTools.ts
@@ -119,7 +119,7 @@ const moreTools = [
evaluate: 'evaluate.viewportProperties.toggle',
}),
createButton({
- id: 'DragProbe',
+ id: 'Probe',
icon: 'tool-probe',
label: 'Probe',
tooltip: 'Probe',
diff --git a/modes/longitudinal/src/initToolGroups.js b/modes/longitudinal/src/initToolGroups.js
index f5bae8d86..329d047b5 100644
--- a/modes/longitudinal/src/initToolGroups.js
+++ b/modes/longitudinal/src/initToolGroups.js
@@ -55,6 +55,7 @@ function initDefaultToolGroup(
},
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
+ { toolName: toolNames.Probe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.CircleROI },
{ toolName: toolNames.RectangleROI },
@@ -201,6 +202,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager, m
},
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
+ { toolName: toolNames.Probe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.CircleROI },
{ toolName: toolNames.RectangleROI },
diff --git a/modes/longitudinal/src/moreTools.ts b/modes/longitudinal/src/moreTools.ts
index 267114f73..70ead4860 100644
--- a/modes/longitudinal/src/moreTools.ts
+++ b/modes/longitudinal/src/moreTools.ts
@@ -126,7 +126,7 @@ const moreTools = [
evaluate: 'evaluate.viewportProperties.toggle',
}),
createButton({
- id: 'DragProbe',
+ id: 'Probe',
icon: 'tool-probe',
label: 'Probe',
tooltip: 'Probe',
diff --git a/modes/longitudinal/src/toolbarButtons.ts b/modes/longitudinal/src/toolbarButtons.ts
index dc5700fe6..62e33a679 100644
--- a/modes/longitudinal/src/toolbarButtons.ts
+++ b/modes/longitudinal/src/toolbarButtons.ts
@@ -65,14 +65,6 @@ const toolbarButtons: Button[] = [
commands: setToolActiveToolbar,
evaluate: 'evaluate.cornerstoneTool',
}),
- createButton({
- id: 'PlanarFreehandROI',
- icon: 'tool-freehand-polygon',
- label: 'Freehand',
- tooltip: 'Freehand ROI',
- commands: setToolActiveToolbar,
- evaluate: 'evaluate.cornerstoneTool',
- }),
createButton({
id: 'RectangleROI',
icon: 'tool-rectangle',
diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts
index 58e12eca8..9d53484f7 100644
--- a/modes/segmentation/src/toolbarButtons.ts
+++ b/modes/segmentation/src/toolbarButtons.ts
@@ -195,7 +195,7 @@ const toolbarButtons: Button[] = [
evaluate: 'evaluate.viewportProperties.toggle',
}),
createButton({
- id: 'DragProbe',
+ id: 'Probe',
icon: 'tool-probe',
label: 'Probe',
tooltip: 'Probe',
diff --git a/platform/app/src/routes/WorkList/WorkList.tsx b/platform/app/src/routes/WorkList/WorkList.tsx
index bfa4ecd70..a5e522c86 100644
--- a/platform/app/src/routes/WorkList/WorkList.tsx
+++ b/platform/app/src/routes/WorkList/WorkList.tsx
@@ -534,7 +534,7 @@ function WorkList({
showPatientInfo={PatientInfoVisibility.DISABLED}
/>