feat(measurements): show untracked measurements in measurement panel under additional findings (#4160)
This commit is contained in:
parent
07eb3c527d
commit
18686c2caf
@ -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"
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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) =>
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 && (
|
||||
<MeasurementTable
|
||||
title="Non-tracked"
|
||||
data={nonAcquisitionMeasurements}
|
||||
servicesManager={servicesManager}
|
||||
onClick={jumpToImage}
|
||||
onEdit={onMeasurementItemEditHandler}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{!appConfig?.disableEditing && (
|
||||
<div className="flex justify-center p-4">
|
||||
@ -207,7 +220,7 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }: wi
|
||||
t={t}
|
||||
actions={[
|
||||
{
|
||||
label: 'Export',
|
||||
label: 'Download CSV',
|
||||
onClick: exportReport,
|
||||
},
|
||||
{
|
||||
@ -266,6 +279,7 @@ function _mapMeasurementToDisplay(measurement, types, displaySetService) {
|
||||
selected,
|
||||
findingSites,
|
||||
finding,
|
||||
referencedImageId,
|
||||
} = measurement;
|
||||
|
||||
const firstSite = findingSites?.[0];
|
||||
@ -294,6 +308,7 @@ function _mapMeasurementToDisplay(measurement, types, displaySetService) {
|
||||
isActive: selected,
|
||||
finding,
|
||||
findingSites,
|
||||
referencedImageId,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.5",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.74.7",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.74.8",
|
||||
"@emotion/serialize": "^1.1.3",
|
||||
"@ohif/core": "3.9.0-beta.23",
|
||||
"@ohif/extension-cornerstone": "3.9.0-beta.23",
|
||||
|
||||
@ -37,7 +37,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",
|
||||
"@ohif/ui": "3.9.0-beta.23",
|
||||
"cornerstone-math": "0.1.9",
|
||||
"dicom-parser": "^1.8.21"
|
||||
|
||||
@ -60,6 +60,7 @@ const MEASUREMENT_SCHEMA_KEYS = [
|
||||
'cachedStats',
|
||||
'selected',
|
||||
'textBox',
|
||||
'referencedImageId',
|
||||
];
|
||||
|
||||
const EVENTS = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user