Skip to content

Commit 2096f8c

Browse files
committed
ultrasound: extract unitToMm helper, document unit codes per spec
Per DICOM PS3.3 C.8.5.5.1.15, code 3 (cm) is the only spatial spacing unit defined for PhysicalUnitsXDirection / YDirection — codes 0, 1, 2, 4–10 cover none / percent / dB / seconds / hertz / dB/sec / cm/sec / cm² / cm²/sec / degrees. Replace the strict cm equality check with a unitToMm helper that returns 10 for cm and null for everything else, applied per axis. Functionally equivalent to the previous strict check, but isolates the unit-to-spacing mapping in one tested place and adds a clear extension point if a vendor exception ever needs to be honoured.
1 parent 55eb9bb commit 2096f8c

3 files changed

Lines changed: 35 additions & 12 deletions

File tree

src/core/streaming/dicom/__tests__/ultrasoundRegion.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
encodeUltrasoundRegionMeta,
66
getUltrasoundRegionFromMetadata,
77
parseUltrasoundRegionFromBlob,
8+
unitToMm,
89
US_REGION_META_KEY,
910
US_UNIT_CENTIMETERS,
1011
} from '@/src/core/streaming/dicom/ultrasoundRegion';
@@ -124,6 +125,20 @@ describe('decodeUltrasoundRegion', () => {
124125
});
125126
});
126127

128+
describe('unitToMm', () => {
129+
it('returns 10 for centimetres (code 3)', () => {
130+
expect(unitToMm(US_UNIT_CENTIMETERS)).toBe(10);
131+
});
132+
133+
it('returns null for non-spatial unit codes', () => {
134+
// Per DICOM PS3.3 C.8.5.5.1.15: 0=none, 1=percent, 2=dB, 4=seconds,
135+
// 5=hertz, 6=dB/sec, 7=cm/sec, 8=cm², 9=cm²/sec, 10=degrees.
136+
[0, 1, 2, 4, 5, 6, 7, 8, 9, 10].forEach((code) => {
137+
expect(unitToMm(code)).toBeNull();
138+
});
139+
});
140+
});
141+
127142
describe('encodeUltrasoundRegionMeta / getUltrasoundRegionFromMetadata', () => {
128143
it('round-trips through the metadata tag array', () => {
129144
const region = {

src/core/streaming/dicom/ultrasoundRegion.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,21 @@ import { Tags, tagToGroupElement } from '@/src/core/dicomTags';
66

77
export const US_REGION_META_KEY = '__volview_us_region';
88

9-
// DICOM unit codes for PhysicalUnitsXDirection / YDirection
10-
// 0x0003 = centimeters. See DICOM PS3.3 C.8.5.5.1.1.
9+
// DICOM unit codes for PhysicalUnitsXDirection / YDirection.
10+
// See DICOM PS3.3 C.8.5.5.1.15. The only spatial spacing code defined for
11+
// this field is 3 (cm). Other codes (0=none, 1=percent, 2=dB, 4=seconds,
12+
// 5=hertz, 6=dB/seconds, 7=cm/sec, 8=cm², 9=cm²/sec, A=degrees) are time,
13+
// frequency, velocity, area, or angle, so they are not converted to a VTK
14+
// image spacing.
1115
export const US_UNIT_CENTIMETERS = 3;
1216

17+
// Returns the multiplier that converts a physical-delta value in the given
18+
// unit to millimetres, or null when the unit is not a spatial spacing.
19+
export const unitToMm = (code: number): number | null => {
20+
if (code === US_UNIT_CENTIMETERS) return 10;
21+
return null;
22+
};
23+
1324
export type UltrasoundRegion = {
1425
physicalDeltaX: number;
1526
physicalDeltaY: number;

src/core/streaming/dicomChunkImage.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { computed } from 'vue';
2828
import vtkITKHelper from '@kitware/vtk.js/Common/DataModel/ITKHelper';
2929
import {
3030
getUltrasoundRegionFromMetadata,
31-
US_UNIT_CENTIMETERS,
31+
unitToMm,
3232
} from '@/src/core/streaming/dicom/ultrasoundRegion';
3333

3434
const { fastComputeRange } = vtkDataArray;
@@ -291,18 +291,15 @@ export default class DicomChunkImage
291291

292292
const region = getUltrasoundRegionFromMetadata(this.getDicomMetadata());
293293
if (!region) return;
294-
if (
295-
region.physicalUnitsXDirection !== US_UNIT_CENTIMETERS ||
296-
region.physicalUnitsYDirection !== US_UNIT_CENTIMETERS
297-
) {
298-
return;
299-
}
300294

301-
const CM_TO_MM = 10;
295+
const xFactor = unitToMm(region.physicalUnitsXDirection);
296+
const yFactor = unitToMm(region.physicalUnitsYDirection);
297+
if (xFactor === null || yFactor === null) return;
298+
302299
const [, , zSpacing] = this.vtkImageData.value.getSpacing();
303300
this.vtkImageData.value.setSpacing([
304-
region.physicalDeltaX * CM_TO_MM,
305-
region.physicalDeltaY * CM_TO_MM,
301+
region.physicalDeltaX * xFactor,
302+
region.physicalDeltaY * yFactor,
306303
zSpacing,
307304
]);
308305
}

0 commit comments

Comments
 (0)