From a40b8beafde052a7741712335b09976a8e89a969 Mon Sep 17 00:00:00 2001 From: Devu Jayalekshmi Date: Sun, 3 May 2026 12:21:08 +0530 Subject: [PATCH 1/3] fix: oblique data closed freehand and other tools invalid results validation --- .../adapters/Cornerstone3D/Bidirectional.ts | 11 ++++-- .../src/adapters/Cornerstone3D/CircleROI.ts | 16 ++++---- .../adapters/Cornerstone3D/EllipticalROI.ts | 12 +++--- .../src/adapters/Cornerstone3D/Length.ts | 4 +- .../Cornerstone3D/PlanarFreehandROI.ts | 12 +++--- .../adapters/Cornerstone3D/RectangleROI.ts | 12 +++--- .../adapters/src/adapters/helpers/index.ts | 10 ++++- .../adapters/helpers/validateNumericValue.ts | 14 +++++++ .../tools/annotation/PlanarFreehandROITool.ts | 37 ++++++++++++++++--- 9 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 packages/adapters/src/adapters/helpers/validateNumericValue.ts diff --git a/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts b/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts index 42cb9a2f84..c2fa3bc4a8 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts @@ -1,6 +1,11 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; -import { scoordToWorld, toScoord, toArray } from '../helpers'; +import { + scoordToWorld, + toScoord, + toArray, + validateNumericValue, +} from '../helpers'; import BaseAdapter3D from './BaseAdapter3D'; const { Bidirectional: TID300Bidirectional } = utilities.TID300; @@ -137,8 +142,8 @@ class Bidirectional extends BaseAdapter3D { point1: shortAxisStartImage, point2: shortAxisEndImage, }, - longAxisLength: length, - shortAxisLength: width, + longAxisLength: validateNumericValue(length), + shortAxisLength: validateNumericValue(width), unit, trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding: finding, diff --git a/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts b/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts index 422af6b36b..b2f200978b 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts @@ -1,7 +1,7 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord } from '../helpers'; +import { toScoord, validateNumericValue } from '../helpers'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; const { Circle: TID300Circle } = utilities.TID300; @@ -93,16 +93,16 @@ class CircleROI extends BaseAdapter3D { const perimeter = 2 * Math.PI * radius; return { - area, + area: validateNumericValue(area), areaUnit, - perimeter, + perimeter: validateNumericValue(perimeter), modalityUnit, radiusUnit, - radius, - max, - min, - stdDev, - mean, + radius: validateNumericValue(radius), + max: validateNumericValue(max), + min: validateNumericValue(min), + stdDev: validateNumericValue(stdDev), + mean: validateNumericValue(mean), points: [center, end], trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding, diff --git a/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts b/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts index c31df8e57a..aa87fda1d8 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts @@ -3,7 +3,7 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord } from '../helpers'; +import { toScoord, validateNumericValue } from '../helpers'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; const { Ellipse: TID300Ellipse } = utilities.TID300; @@ -109,12 +109,12 @@ class EllipticalROI extends BaseAdapter3D { const convertedPoints = points.map((point) => toScoord(scoordProps, point)); return { - area, + area: validateNumericValue(area), areaUnit, - max, - min, - mean, - stdDev, + max: validateNumericValue(max), + min: validateNumericValue(min), + mean: validateNumericValue(mean), + stdDev: validateNumericValue(stdDev), modalityUnit, points: convertedPoints, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/Cornerstone3D/Length.ts b/packages/adapters/src/adapters/Cornerstone3D/Length.ts index e176a2ec23..fa43f0bf77 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/Length.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/Length.ts @@ -1,7 +1,7 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord } from '../helpers'; +import { toScoord, validateNumericValue } from '../helpers'; const { Length: TID300Length } = utilities.TID300; @@ -76,7 +76,7 @@ export default class Length extends BaseAdapter3D { return { point1, point2, - distance, + distance: validateNumericValue(distance), trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding, findingSites: findingSites || [], diff --git a/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts b/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts index 610cef5155..2908925808 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts @@ -3,7 +3,7 @@ import { utilities } from 'dcmjs'; import { vec3 } from 'gl-matrix'; import BaseAdapter3D from './BaseAdapter3D'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; -import { toScoords, toArray } from '../helpers'; +import { toScoords, toArray, validateNumericValue } from '../helpers'; import ControlPointPolyline from './ControlPointPolyline'; import { SPLINE_TYPE_CODE } from './constants'; @@ -142,13 +142,13 @@ class PlanarFreehandROI extends BaseAdapter3D { /** From cachedStats */ points, controlPoints, - area, + area: validateNumericValue(area), areaUnit, - perimeter: perimeter ?? length, + perimeter: validateNumericValue(perimeter ?? length), modalityUnit, - mean, - max, - stdDev, + mean: validateNumericValue(mean), + max: validateNumericValue(max), + stdDev: validateNumericValue(stdDev), /** Other */ splineType: data.spline?.type, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts b/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts index 3d1a8a0156..393bc89615 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts @@ -1,6 +1,6 @@ import { utilities } from 'dcmjs'; -import { toScoords } from '../helpers'; +import { toScoords, validateNumericValue } from '../helpers'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; @@ -95,11 +95,11 @@ export class RectangleROI extends BaseAdapter3D { return { points: [corners[0], corners[1], corners[3], corners[2], corners[0]], - area, - perimeter, - max, - mean, - stdDev, + area: validateNumericValue(area), + perimeter: validateNumericValue(perimeter), + max: validateNumericValue(max), + mean: validateNumericValue(mean), + stdDev: validateNumericValue(stdDev), areaUnit, modalityUnit, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/helpers/index.ts b/packages/adapters/src/adapters/helpers/index.ts index 59c574b61c..9cfb13d516 100644 --- a/packages/adapters/src/adapters/helpers/index.ts +++ b/packages/adapters/src/adapters/helpers/index.ts @@ -2,6 +2,8 @@ import { toArray } from './toArray'; import { codeMeaningEquals } from './codeMeaningEquals'; import { graphicTypeEquals } from './graphicTypeEquals'; import { downloadDICOMData } from './downloadDICOMData'; +import { validateNumericValue } from './validateNumericValue'; + export { copyStudyTags } from './copyStudyTags'; export { copySeriesTags } from './copySeriesTags'; @@ -9,4 +11,10 @@ export * from './toScoordType'; export * from './scoordToWorld'; export * from './toPoint3'; -export { toArray, codeMeaningEquals, graphicTypeEquals, downloadDICOMData }; +export { + toArray, + codeMeaningEquals, + graphicTypeEquals, + downloadDICOMData, + validateNumericValue, +}; diff --git a/packages/adapters/src/adapters/helpers/validateNumericValue.ts b/packages/adapters/src/adapters/helpers/validateNumericValue.ts new file mode 100644 index 0000000000..f2c226b5b5 --- /dev/null +++ b/packages/adapters/src/adapters/helpers/validateNumericValue.ts @@ -0,0 +1,14 @@ +/** + * Validates a numeric value for DICOM SR NumericValue field (VR: DS). + * DS (Decimal String) does not support Infinity, -Infinity, or NaN. + * + * @param value - The numeric value to validate + * @returns The value if valid, undefined if invalid (Infinity, -Infinity, NaN, null, or undefined) + */ +export function validateNumericValue( + value: number | null | undefined +): number | undefined { + return typeof value === 'number' && Number.isFinite(value) + ? value + : undefined; +} diff --git a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts index 2f3848c416..2df8e708c6 100644 --- a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts +++ b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts @@ -960,16 +960,44 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool { let intersections = []; let intersectionCounter = 0; + const { viewPlaneNormal } = viewport.getCamera(); + + /** + * Detect if the current viewport orientation is oblique. + * For oblique planes, the worldToCanvas transformation can produce + * slightly different floating-point Y values for points that belong + * to the same scanline due to floating-point precision and projection. + * + * This causes the scanline intersection logic to reset frequently, + * resulting in missing voxels and incorrect min/max/density statistics. + * + * To stabilize scanline detection, we introduce a tolerance (rowDelta) + * when comparing the current canvas Y coordinate with the previous row. + * + * - For orthogonal views, no tolerance is required (rowDelta = 0). + * - For oblique views, we allow a small half-pixel tolerance (0.5) + * so that points with very small floating-point differences are + * treated as belonging to the same scanline. + */ + const TOLERANCE = 0.5; + + const isOblique = + viewPlaneNormal.filter((c) => Math.abs(c) > EPSILON).length > 1; + + const rowDelta = isOblique ? TOLERANCE : 0; + let pointsInShape; + if (voxelManager) { pointsInShape = voxelManager.forEach( this.configuration.statsCalculator.statsCallback, { imageData, isInObject: (pointLPS, _pointIJK) => { - let result = true; const point = viewport.worldToCanvas(pointLPS); - if (point[1] != curRow) { + // Use tolerance-based comparison to avoid scanline resets caused + // by floating-point precision differences in oblique projections. + if (Math.abs(point[1] - curRow) > rowDelta) { intersectionCounter = 0; curRow = point[1]; intersections = getLineSegmentIntersectionsCoordinates( @@ -993,10 +1021,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool { intersections.shift(); intersectionCounter++; } - if (intersectionCounter % 2 === 0) { - result = false; - } - return result; + return intersectionCounter % 2 === 1; }, boundsIJK, returnPoints: this.configuration.storePointData, From ff6e60d062e1ce65d8f216c8e26e8dd3479c2177 Mon Sep 17 00:00:00 2001 From: Devu Jayalekshmi Date: Wed, 20 May 2026 12:17:31 +0530 Subject: [PATCH 2/3] fix: reused toFiniteNumber method --- .../adapters/Cornerstone3D/Bidirectional.ts | 14 ++++++-------- .../src/adapters/Cornerstone3D/CircleROI.ts | 19 +++++++++++-------- .../adapters/Cornerstone3D/EllipticalROI.ts | 15 +++++++++------ .../src/adapters/Cornerstone3D/Length.ts | 6 ++++-- .../Cornerstone3D/PlanarFreehandROI.ts | 15 +++++++++------ .../adapters/Cornerstone3D/RectangleROI.ts | 15 +++++++++------ .../adapters/src/adapters/helpers/index.ts | 9 +-------- .../adapters/helpers/validateNumericValue.ts | 14 -------------- packages/core/src/utilities/index.ts | 2 ++ 9 files changed, 51 insertions(+), 58 deletions(-) delete mode 100644 packages/adapters/src/adapters/helpers/validateNumericValue.ts diff --git a/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts b/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts index c2fa3bc4a8..b86fb92ee1 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/Bidirectional.ts @@ -1,14 +1,12 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; -import { - scoordToWorld, - toScoord, - toArray, - validateNumericValue, -} from '../helpers'; +import { utilities as csUtilities } from '@cornerstonejs/core'; +import { scoordToWorld, toScoord, toArray } from '../helpers'; + import BaseAdapter3D from './BaseAdapter3D'; const { Bidirectional: TID300Bidirectional } = utilities.TID300; +const { toFiniteNumber } = csUtilities; const LONG_AXIS = 'Long Axis'; const SHORT_AXIS = 'Short Axis'; @@ -142,8 +140,8 @@ class Bidirectional extends BaseAdapter3D { point1: shortAxisStartImage, point2: shortAxisEndImage, }, - longAxisLength: validateNumericValue(length), - shortAxisLength: validateNumericValue(width), + longAxisLength: toFiniteNumber(length), + shortAxisLength: toFiniteNumber(width), unit, trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding: finding, diff --git a/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts b/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts index b2f200978b..1138f0bfaf 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/CircleROI.ts @@ -1,10 +1,13 @@ import { utilities } from 'dcmjs'; +import { utilities as csUtilities } from '@cornerstonejs/core'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord, validateNumericValue } from '../helpers'; +import { toScoord } from '../helpers'; + import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; const { Circle: TID300Circle } = utilities.TID300; +const { toFiniteNumber } = csUtilities; class CircleROI extends BaseAdapter3D { static { @@ -93,16 +96,16 @@ class CircleROI extends BaseAdapter3D { const perimeter = 2 * Math.PI * radius; return { - area: validateNumericValue(area), + area: toFiniteNumber(area), areaUnit, - perimeter: validateNumericValue(perimeter), + perimeter: toFiniteNumber(perimeter), modalityUnit, radiusUnit, - radius: validateNumericValue(radius), - max: validateNumericValue(max), - min: validateNumericValue(min), - stdDev: validateNumericValue(stdDev), - mean: validateNumericValue(mean), + radius: toFiniteNumber(radius), + max: toFiniteNumber(max), + min: toFiniteNumber(min), + stdDev: toFiniteNumber(stdDev), + mean: toFiniteNumber(mean), points: [center, end], trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding, diff --git a/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts b/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts index aa87fda1d8..36eb6dd6d7 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/EllipticalROI.ts @@ -3,10 +3,13 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord, validateNumericValue } from '../helpers'; +import { utilities as csUtilities } from '@cornerstonejs/core'; +import { toScoord } from '../helpers'; + import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; const { Ellipse: TID300Ellipse } = utilities.TID300; +const { toFiniteNumber } = csUtilities; const EPSILON = 1e-4; @@ -109,12 +112,12 @@ class EllipticalROI extends BaseAdapter3D { const convertedPoints = points.map((point) => toScoord(scoordProps, point)); return { - area: validateNumericValue(area), + area: toFiniteNumber(area), + max: toFiniteNumber(max), + min: toFiniteNumber(min), + mean: toFiniteNumber(mean), + stdDev: toFiniteNumber(stdDev), areaUnit, - max: validateNumericValue(max), - min: validateNumericValue(min), - mean: validateNumericValue(mean), - stdDev: validateNumericValue(stdDev), modalityUnit, points: convertedPoints, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/Cornerstone3D/Length.ts b/packages/adapters/src/adapters/Cornerstone3D/Length.ts index fa43f0bf77..3a5d1b1fb8 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/Length.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/Length.ts @@ -1,9 +1,11 @@ import { utilities } from 'dcmjs'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; -import { toScoord, validateNumericValue } from '../helpers'; +import { utilities as csUtilities } from '@cornerstonejs/core'; +import { toScoord } from '../helpers'; const { Length: TID300Length } = utilities.TID300; +const { toFiniteNumber } = csUtilities; const LENGTH = 'Length'; @@ -76,7 +78,7 @@ export default class Length extends BaseAdapter3D { return { point1, point2, - distance: validateNumericValue(distance), + distance: toFiniteNumber(distance), trackingIdentifierTextValue: this.trackingIdentifierTextValue, finding, findingSites: findingSites || [], diff --git a/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts b/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts index 2908925808..01f8c29bbd 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/PlanarFreehandROI.ts @@ -1,12 +1,15 @@ import MeasurementReport from './MeasurementReport'; import { utilities } from 'dcmjs'; +import { utilities as csUtilities } from '@cornerstonejs/core'; import { vec3 } from 'gl-matrix'; import BaseAdapter3D from './BaseAdapter3D'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; -import { toScoords, toArray, validateNumericValue } from '../helpers'; +import { toScoords, toArray } from '../helpers'; import ControlPointPolyline from './ControlPointPolyline'; import { SPLINE_TYPE_CODE } from './constants'; +const { toFiniteNumber } = csUtilities; + /** Contour/polyline SR logic is shared by LivewireContour, registered as a subtype. */ class PlanarFreehandROI extends BaseAdapter3D { public static closedContourThreshold = 1e-5; @@ -142,13 +145,13 @@ class PlanarFreehandROI extends BaseAdapter3D { /** From cachedStats */ points, controlPoints, - area: validateNumericValue(area), + area: toFiniteNumber(area), areaUnit, - perimeter: validateNumericValue(perimeter ?? length), + perimeter: toFiniteNumber(perimeter ?? length), modalityUnit, - mean: validateNumericValue(mean), - max: validateNumericValue(max), - stdDev: validateNumericValue(stdDev), + mean: toFiniteNumber(mean), + max: toFiniteNumber(max), + stdDev: toFiniteNumber(stdDev), /** Other */ splineType: data.spline?.type, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts b/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts index 393bc89615..76d7b91a30 100644 --- a/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts +++ b/packages/adapters/src/adapters/Cornerstone3D/RectangleROI.ts @@ -1,11 +1,14 @@ import { utilities } from 'dcmjs'; +import { utilities as csUtilities } from '@cornerstonejs/core'; + +import { toScoords } from '../helpers'; -import { toScoords, validateNumericValue } from '../helpers'; import MeasurementReport from './MeasurementReport'; import BaseAdapter3D from './BaseAdapter3D'; import { extractAllNUMGroups, restoreAdditionalMetrics } from './metricHandler'; const { Polyline: TID300Polyline } = utilities.TID300; +const { toFiniteNumber } = csUtilities; export class RectangleROI extends BaseAdapter3D { static { @@ -95,11 +98,11 @@ export class RectangleROI extends BaseAdapter3D { return { points: [corners[0], corners[1], corners[3], corners[2], corners[0]], - area: validateNumericValue(area), - perimeter: validateNumericValue(perimeter), - max: validateNumericValue(max), - mean: validateNumericValue(mean), - stdDev: validateNumericValue(stdDev), + area: toFiniteNumber(area), + perimeter: toFiniteNumber(perimeter), + max: toFiniteNumber(max), + mean: toFiniteNumber(mean), + stdDev: toFiniteNumber(stdDev), areaUnit, modalityUnit, trackingIdentifierTextValue: this.trackingIdentifierTextValue, diff --git a/packages/adapters/src/adapters/helpers/index.ts b/packages/adapters/src/adapters/helpers/index.ts index 9cfb13d516..91ec898e12 100644 --- a/packages/adapters/src/adapters/helpers/index.ts +++ b/packages/adapters/src/adapters/helpers/index.ts @@ -2,7 +2,6 @@ import { toArray } from './toArray'; import { codeMeaningEquals } from './codeMeaningEquals'; import { graphicTypeEquals } from './graphicTypeEquals'; import { downloadDICOMData } from './downloadDICOMData'; -import { validateNumericValue } from './validateNumericValue'; export { copyStudyTags } from './copyStudyTags'; export { copySeriesTags } from './copySeriesTags'; @@ -11,10 +10,4 @@ export * from './toScoordType'; export * from './scoordToWorld'; export * from './toPoint3'; -export { - toArray, - codeMeaningEquals, - graphicTypeEquals, - downloadDICOMData, - validateNumericValue, -}; +export { toArray, codeMeaningEquals, graphicTypeEquals, downloadDICOMData }; diff --git a/packages/adapters/src/adapters/helpers/validateNumericValue.ts b/packages/adapters/src/adapters/helpers/validateNumericValue.ts deleted file mode 100644 index f2c226b5b5..0000000000 --- a/packages/adapters/src/adapters/helpers/validateNumericValue.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Validates a numeric value for DICOM SR NumericValue field (VR: DS). - * DS (Decimal String) does not support Infinity, -Infinity, or NaN. - * - * @param value - The numeric value to validate - * @returns The value if valid, undefined if invalid (Infinity, -Infinity, NaN, null, or undefined) - */ -export function validateNumericValue( - value: number | null | undefined -): number | undefined { - return typeof value === 'number' && Number.isFinite(value) - ? value - : undefined; -} diff --git a/packages/core/src/utilities/index.ts b/packages/core/src/utilities/index.ts index fcba9af39f..0115acc222 100644 --- a/packages/core/src/utilities/index.ts +++ b/packages/core/src/utilities/index.ts @@ -107,6 +107,7 @@ export * from './getPixelSpacingInformation'; export * from './getPlaneCubeIntersectionDimensions'; export * from './rotateToViewCoordinates'; import { asArray } from './asArray'; +import { toFiniteNumber } from './toNumber'; export { updatePlaneRestriction } from './updatePlaneRestriction'; const getViewportModality = (viewport: IViewport, volumeId?: string) => @@ -214,4 +215,5 @@ export { buildMetadata, calculateNeighborhoodStats, asArray, + toFiniteNumber, }; From c26fe97c5b3b11cce7b7366d94ea2f43e1461b08 Mon Sep 17 00:00:00 2001 From: Devu Jayalekshmi Date: Mon, 25 May 2026 11:24:49 +0530 Subject: [PATCH 3/3] test commit --- packages/adapters/src/adapters/helpers/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/adapters/src/adapters/helpers/index.ts b/packages/adapters/src/adapters/helpers/index.ts index 91ec898e12..59c574b61c 100644 --- a/packages/adapters/src/adapters/helpers/index.ts +++ b/packages/adapters/src/adapters/helpers/index.ts @@ -2,7 +2,6 @@ import { toArray } from './toArray'; import { codeMeaningEquals } from './codeMeaningEquals'; import { graphicTypeEquals } from './graphicTypeEquals'; import { downloadDICOMData } from './downloadDICOMData'; - export { copyStudyTags } from './copyStudyTags'; export { copySeriesTags } from './copySeriesTags';