Skip to content

Add 64-bit integer support and fix intensity windowing for tiny units - #5

Merged
marcoduering merged 3 commits into
mainfrom
claude/dazzling-darwin-wlgid2
Sep 27, 2026
Merged

marcoduering merged 3 commits into
mainfrom
claude/dazzling-darwin-wlgid2

Conversation

@marcoduering

@marcoduering marcoduering commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

This PR ports three fixes from MIQCore to enable proper handling of 64-bit integer data and improve intensity windowing for data in tiny units.

Summary

Adds support for 64-bit integer voxel types (Int64/Uint64) which are commonly used by NumPy and scientific imaging tools, fixes intensity window computation for data with very small magnitudes (e.g., SI-unit ADC maps), and optimizes label detection for MIF files with custom memory layouts.

Key Changes

64-bit Integer Support (Int64DatatypeTests.cs)

  • Added MiqDatatype.Int64 (1024) and MiqDatatype.Uint64 (1280) enum values
  • Extended NIfTI, MIF, and NRRD parsers to recognize and parse 64-bit integer types
  • Implemented 64-bit voxel reading in MiqVolume.RawVoxelValue() and label scanning
  • Added comprehensive tests verifying correct decoding beyond int32 range and label map detection

Intensity Window Fix for Tiny Units (TinyUnitWindowTests.cs)

  • Modified IntensityWindow.GetBounds() to use a two-tier approach for selecting the foreground subset
  • First tier: values above NonZeroFloor (1e-6) to drop interpolation residue
  • Fallback tier: exactly non-zero values when the first tier is too small
  • Preserves backward compatibility with ordinary-unit data while fixing windowing for data in tiny units (e.g., 1e-9 magnitude ADC maps)

Binary Mask Layout Optimization (BinaryMaskLayoutTests.cs)

  • Introduced Volume0IsContiguous property to detect when volume 0 occupies the first W·H·D payload elements regardless of axis order
  • Enables fast contiguous scanning path for dense MIF layouts with custom strides (previously only worked for row-major)
  • Correctly falls back to per-voxel walk for volume-interleaved layouts (e.g., DWI-style)
  • Improves label detection performance for MIF masks by ~8× on 256³ volumes

Implementation Details

  • Label scanning now handles 64-bit integers with proper signed/unsigned semantics
  • Volume0IsContiguous checks that spatial strides (when sorted) follow the pattern 1, d₀, d₀·d₁, independent of axis permutation
  • Intensity windowing preserves the /20 ratio heuristic to avoid rejecting legitimate dim regions
  • All changes maintain backward compatibility with existing data formats

NIfTI datatypes 1024/1280, MIF Int64/UInt64 and NRRD 64-bit integer types
were rejected, which broke numpy-generated label maps (int64 is NumPy's
default integer dtype). Add them to MiqDatatype, decode them through
double -> float like MIQCore, make them label-detection candidates, and
give ScanVolume0's binary-mask confirm a 64-bit arm.

Port of MIQ 2cf1764.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYbaAXasvPKzEgLcoESA9s
IntensityWindow.GetBounds preferred the |v| > 1e-6 subset, so data in tiny
units (an SI-unit ADC map, ~1e-9) had no foreground subset and was windowed
over tissue plus background zeros. When the floored subset is too small,
exactly-non-zero values now stand in. Ordinary data is unchanged (pinned
bit-identical against the previous implementation).

Port of MIQ bcf3e18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYbaAXasvPKzEgLcoESA9s
ScanVolume0 and CollectVolume0Labels took the per-voxel walk whenever
ElementStrides was set, and MifParser always sets it, so every MIF mask
paid for it. Key off Volume0IsContiguous instead: volume 0 is the first
W*H*D elements in some order, which is all these order-independent scans
need. A 256^3 MIF mask's BuildSegmentationLut drops from ~750 ms to
~30 ms; layouts with the volume axis faster than a spatial one still walk.

Port of the mask-scan part of MIQ 8323423.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYbaAXasvPKzEgLcoESA9s
@marcoduering
marcoduering merged commit 79603ca into main Sep 27, 2026
1 check passed
@marcoduering
marcoduering deleted the claude/dazzling-darwin-wlgid2 branch September 27, 2026 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants