Skip to content

[Bug] NIfTI volume loader sets PixelSpacing array in wrong DICOM order (column, row instead of row, column) #2602

@SrZhang4160

Description

@SrZhang4160

Describe the Bug

The NIfTI volume loader populates the pixelSpacing array in [columnSpacing, rowSpacing] order, but the DICOM convention for the PixelSpacing attribute (0028,0030) is [rowSpacing, columnSpacing].
This occurs in two places:

  1. createNiftiImageIdsAndCacheMetadata.ts (line 201):
    tsconst imagePlaneMetadata = {
    // ...
    pixelSpacing: [spacing[0], spacing[1]], // [column, row] ← wrong order
    rowPixelSpacing: spacing[1], // correct
    columnPixelSpacing: spacing[0], // correct
    };
  2. makeVolumeMetadata.ts (line 34):
    tsPixelSpacing: [pixDims[1], pixDims[2]], // [column, row] ← wrong order
    In both cases, spacing[0] / pixDims[1] is the i-axis (column) spacing and spacing[1] / pixDims[2] is the j-axis (row) spacing. The DICOM standard specifies PixelSpacing as [row spacing, column spacing].

Steps to Reproduce

Load a NIfTI file with anisotropic in-plane spacing (e.g. pixDims = [1, 0.3, 0.5, 2.0]).
Call createNiftiImageIdsAndCacheMetadata({ url }).
Retrieve the cached imagePlaneModule metadata for any image ID.
Compare:

metadata.pixelSpacing[0] → returns 0.3 (column spacing)
metadata.pixelSpacing[1] → returns 0.5 (row spacing)
DICOM convention expects [0] = row spacing, [1] = column spacing

The current behavior

The pixelSpacing array is [columnSpacing, rowSpacing], which is the reverse of DICOM convention.
Current impact is low because Cornerstone's core code (calculateSpacingBetweenImageIds, volume construction) reads the named fields columnPixelSpacing and rowPixelSpacing first, which are set correctly. It only falls back to the pixelSpacing array when the named fields are missing.
However, any external code that reads the pixelSpacing array directly and assumes DICOM ordering would get swapped values. This affects interoperability with tools that expect DICOM-standard metadata.

The expected behavior

pixelSpacing: [spacing[1], spacing[0]]
And in makeVolumeMetadata.ts:
tsPixelSpacing: [pixDims[2], pixDims[1]]

System Information

System:
OS: macOS 15.7.3
CPU: (14) arm64 Apple M4 Pro
Memory: 240.39 MB / 48.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.19.5 - /Users/zlin/.nvm/versions/node/v20.19.5/bin/node
npm: 10.9.2 - /Users/zlin/.nvm/versions/node/v20.19.5/bin/npm
Browsers:
Chrome: 144.0.7559.133
Firefox: 147.0.2
Safari: 18.6

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions