Skip to content

Commit

Permalink
fix(measurements): Update the calibration tool to match changes in CS…
Browse files Browse the repository at this point in the history
…3D (#3505)

This change makes the OHIF side consistent with the CS3D user calibration settings, and will correctly display px and rounding values consistent with the CS3D display.
  • Loading branch information
wayfarer3130 authored Sep 15, 2023
1 parent bd7f959 commit 38af311
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 90 deletions.
7 changes: 4 additions & 3 deletions extensions/cornerstone/src/tools/CalibrationLineTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ export function onCompletedCalibrationLine(servicesManager, csToolsEvent) {

const adjustCalibration = newLength => {
const spacingScale = newLength / length;
const rowSpacing = spacingScale * currentRowPixelSpacing;
const colSpacing = spacingScale * currentColumnPixelSpacing;

// trigger resize of the viewport to adjust the world/pixel mapping
calibrateImageSpacing(imageId, viewport.getRenderingEngine(), rowSpacing, colSpacing);
calibrateImageSpacing(imageId, viewport.getRenderingEngine(), {
type: 'User',
scale: 1 / spacingScale,
});
};

return new Promise((resolve, reject) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ function getMappedAnnotations(annotation, displaySetService) {
);

const { SeriesNumber } = displaySet;
const { length, width } = targetStats;
const unit = 'mm';
const { length, width, unit } = targetStats;

annotations.push({
SeriesInstanceUID,
Expand Down Expand Up @@ -130,9 +129,9 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
values.push('Cornerstone:Bidirectional');

mappedAnnotations.forEach(annotation => {
const { length, width } = annotation;
columns.push(`Length (mm)`, `Width (mm)`);
values.push(length, width);
const { length, width, unit } = annotation;
columns.push(`Length`, `Width`, 'Unit');
values.push(length, width, unit);
});

if (FrameOfReferenceUID) {
Expand Down Expand Up @@ -162,7 +161,14 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];

// Area is the same for all series
const { length, width, SeriesNumber, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
const {
length,
width,
unit,
SeriesNumber,
SOPInstanceUID,
frameNumber,
} = mappedAnnotations[0];
const roundedLength = utils.roundNumber(length, 2);
const roundedWidth = utils.roundNumber(width, 2);

Expand All @@ -176,8 +182,10 @@ function getDisplayText(mappedAnnotations, displaySet) {
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';

displayText.push(`L: ${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`);
displayText.push(`W: ${roundedWidth} mm`);
displayText.push(
`L: ${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
);
displayText.push(`W: ${roundedWidth} ${unit}`);

return displayText;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function getMappedAnnotations(annotation, DisplaySetService) {
);

const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, modalityUnit } = targetStats;
const { mean, stdDev, max, area, Modality, areaUnit, modalityUnit } = targetStats;

annotations.push({
SeriesInstanceUID,
Expand All @@ -111,6 +111,7 @@ function getMappedAnnotations(annotation, DisplaySetService) {
stdDev,
max,
area,
areaUnit,
});
});

Expand All @@ -131,14 +132,20 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
values.push('Cornerstone:CircleROI');

mappedAnnotations.forEach(annotation => {
const { mean, stdDev, max, area, unit } = annotation;
const { mean, stdDev, max, area, unit, areaUnit } = annotation;

if (!mean || !unit || !max || !area) {
return;
}

columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, `area (mm2)`);
values.push(max, mean, stdDev, area);
columns.push(
`max (${unit})`,
`mean (${unit})`,
`std (${unit})`,
'Area',
'Unit'
);
values.push(max, mean, stdDev, area, areaUnit);
});

if (FrameOfReferenceUID) {
Expand Down Expand Up @@ -168,7 +175,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];

// Area is the same for all series
const { area, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
const { area, SOPInstanceUID, frameNumber, areaUnit } = mappedAnnotations[0];

const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);

Expand All @@ -182,7 +189,7 @@ function getDisplayText(mappedAnnotations, displaySet) {

// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
const roundedArea = utils.roundNumber(area || 0, 2);
displayText.push(`${roundedArea} mm<sup>2</sup>`);
displayText.push(`${roundedArea} ${areaUnit}`);

// Todo: we need a better UI for displaying all these information
mappedAnnotations.forEach(mappedAnnotation => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function getMappedAnnotations(annotation, displaySetService) {
);

const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, modalityUnit } = targetStats;
const { mean, stdDev, max, area, Modality, areaUnit, modalityUnit } = targetStats;

annotations.push({
SeriesInstanceUID,
Expand All @@ -107,6 +107,7 @@ function getMappedAnnotations(annotation, displaySetService) {
frameNumber,
Modality,
unit: modalityUnit,
areaUnit,
mean,
stdDev,
max,
Expand All @@ -131,14 +132,20 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
values.push('Cornerstone:EllipticalROI');

mappedAnnotations.forEach(annotation => {
const { mean, stdDev, max, area, unit } = annotation;
const { mean, stdDev, max, area, unit, areaUnit } = annotation;

if (!mean || !unit || !max || !area) {
return;
}

columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, `area (mm2)`);
values.push(max, mean, stdDev, area);
columns.push(
`max (${unit})`,
`mean (${unit})`,
`std (${unit})`,
'Area',
'Unit'
);
values.push(max, mean, stdDev, area, areaUnit);
});

if (FrameOfReferenceUID) {
Expand Down Expand Up @@ -168,7 +175,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];

// Area is the same for all series
const { area, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
const { area, SOPInstanceUID, frameNumber, areaUnit } = mappedAnnotations[0];

const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);

Expand All @@ -180,9 +187,8 @@ function getDisplayText(mappedAnnotations, displaySet) {
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';

// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
const roundedArea = utils.roundNumber(area || 0, 2);
displayText.push(`${roundedArea} mm<sup>2</sup>`);
const roundedArea = utils.roundNumber(area, 2);
displayText.push(`${roundedArea} ${areaUnit}`);

// Todo: we need a better UI for displaying all these information
mappedAnnotations.forEach(mappedAnnotation => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ const Length = {
throw new Error('Tool not supported');
}

const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
const {
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
} = getSOPInstanceAttributes(
referencedImageId,
cornerstoneViewportService,
viewportId
Expand Down Expand Up @@ -94,8 +98,11 @@ 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,
Expand All @@ -104,8 +111,7 @@ function getMappedAnnotations(annotation, displaySetService) {
);

const { SeriesNumber } = displaySet;
const { length } = targetStats;
const unit = 'mm';
const { length, unit = 'mm' } = targetStats;

annotations.push({
SeriesInstanceUID,
Expand Down Expand Up @@ -134,9 +140,11 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
values.push('Cornerstone:Length');

mappedAnnotations.forEach(annotation => {
const { length } = annotation;
columns.push(`Length (mm)`);
const { length, unit } = annotation;
columns.push(`Length`);
values.push(length);
columns.push('Unit');
values.push(unit);
});

if (FrameOfReferenceUID) {
Expand Down Expand Up @@ -166,7 +174,13 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];

// Area is the same for all series
const { length, SeriesNumber, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
const {
length,
SeriesNumber,
SOPInstanceUID,
frameNumber,
unit,
} = mappedAnnotations[0];

const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);

Expand All @@ -182,7 +196,9 @@ function getDisplayText(mappedAnnotations, displaySet) {
return displayText;
}
const roundedLength = utils.roundNumber(length, 2);
displayText.push(`${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`);
displayText.push(
`${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
);

return displayText;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ const RectangleROI = {
throw new Error('Tool not supported');
}

const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } = getSOPInstanceAttributes(
const {
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
} = getSOPInstanceAttributes(
referencedImageId,
CornerstoneViewportService,
viewportId
Expand Down Expand Up @@ -88,8 +92,11 @@ 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,
Expand All @@ -98,7 +105,7 @@ function getMappedAnnotations(annotation, DisplaySetService) {
);

const { SeriesNumber } = displaySet;
const { mean, stdDev, max, area, Modality, modalityUnit } = targetStats;
const { mean, stdDev, max, area, Modality, modalityUnit, areaUnit } = targetStats;

annotations.push({
SeriesInstanceUID,
Expand All @@ -111,6 +118,7 @@ function getMappedAnnotations(annotation, DisplaySetService) {
stdDev,
max,
area,
areaUnit,
});
});

Expand All @@ -131,14 +139,14 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
values.push('Cornerstone:RectangleROI');

mappedAnnotations.forEach(annotation => {
const { mean, stdDev, max, area, unit } = annotation;
const { mean, stdDev, max, area, unit, areaUnit } = annotation;

if (!mean || !unit || !max || !area) {
return;
}

columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, `area (mm2)`);
values.push(max, mean, stdDev, area);
columns.push(`Maximum`, `Mean`, `Std Dev`, 'Pixel Unit', `Area`, 'Unit');
values.push(max, mean, stdDev, unit, area, areaUnit);
});

if (FrameOfReferenceUID) {
Expand Down Expand Up @@ -168,7 +176,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
const displayText = [];

// Area is the same for all series
const { area, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
const { area, SOPInstanceUID, frameNumber, areaUnit } = mappedAnnotations[0];

const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);

Expand All @@ -182,7 +190,7 @@ function getDisplayText(mappedAnnotations, displaySet) {

// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
const roundedArea = utils.roundNumber(area || 0, 2);
displayText.push(`${roundedArea} mm<sup>2</sup>`);
displayText.push(`${roundedArea} ${areaUnit}`);

// Todo: we need a better UI for displaying all these information
mappedAnnotations.forEach(mappedAnnotation => {
Expand Down
Loading

0 comments on commit 38af311

Please sign in to comment.