Skip to content

WIP: ENH: Add order-explicit spatial keys to the Python image dict protocol - #6710

Draft
hjmjohnson wants to merge 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:python-geometry-protocol
Draft

WIP: ENH: Add order-explicit spatial keys to the Python image dict protocol#6710
hjmjohnson wants to merge 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:python-geometry-protocol

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Jul 26, 2026

Copy link
Copy Markdown
Member

Adds order-explicit spatial keys (origin|spacing|direction|index|size × _xyz|_zyx) to the itk.Image dict interface and deprecates the order-ambiguous bare keys, resolving the ITK↔SimpleITK convention conflict that blocks #6021. Fixes #6706. Companion SimpleITK WIP: SimpleITK/SimpleITK#2655 — both PRs implement the identical protocol so generic code works across toolkits.

Design summary
  • Bare image['spacing'] returns (z,y,x) in ITK but (x,y,z) in SimpleITK — same key, opposite conventions, silent geometry corruption for generic consumers (Python image['spacing'] axis-order conflict between ITK (z,y,x) and SimpleITK (x,y,z) blocks generic interop (PR #6021) #6706).
  • Both suffix families are complete coordinate frames: p = origin + direction @ (spacing * i) and its inverse reproduce TransformContinuousIndexToPhysicalPoint / TransformPhysicalPointToContinuousIndex to ≤3e-14 in either convention, including non-zero start index (index_* keys — absent from the old interface, causing 26 mm placement error in the test geometry).
  • direction_zyx = np.flip(D, axis=None) = P·D·P preserves composition/inversion; the SimpleITK counterpart tuple(reversed(flat_direction)) is bit-identical.
  • Writing index_*/size_* goes through SetRegions().
  • Bare keys keep exact historical behavior + DeprecationWarning; ITK_FUTURE_LEGACY_REMOVE=ON (or env ITK_PYTHON_FUTURE_LEGACY_REMOVE) escalates to always-visible FutureWarning via new itkConfig.FutureLegacyRemove.
  • Migration guide added to Documentation/docs/migration_guides/.
Testing
  • New PythonGeometryProtocolTest: both-domain forward/inverse vs C++ oracles, homomorphism identities, setter round-trips, warning category assertions, SetRegions-backed writes with reallocation.
  • Full Python wrapping label: 187/187 pass locally (macOS arm64, pixi env).
  • PythonExtrasTest (bare-key consumers, dict(image), serialization) unchanged and passing.

WIP pending: design sign-off on key naming (@thewtex @blowekamp @dzenanz), coordination with the SimpleITK companion, and whether keys() should stop listing the bare three under ITK_FUTURE_LEGACY_REMOVE.

Add 'origin', 'spacing', 'direction', 'index', and 'size' keys with
explicit '_xyz' (ITK order) and '_zyx' (NumPy order) suffixes to
itk.Image __getitem__/__setitem__/keys, and deprecate the bare
order-ambiguous 'origin'/'spacing'/'direction' keys, which return
(z,y,x) order in ITK but (x,y,z) order in SimpleITK (issue InsightSoftwareConsortium#6706).

Writing 'index'/'size' keys goes through SetRegions. Bare-key access
warns with DeprecationWarning, escalated to FutureWarning when
configured with ITK_FUTURE_LEGACY_REMOVE (itkConfig.FutureLegacyRemove,
env-overridable). A migration guide documents the protocol.

The test verifies both frames against the C++ oracles
TransformContinuousIndexToPhysicalPoint and
TransformPhysicalPointToContinuousIndex, including non-zero start
index, to 1e-12.
@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots area:Python wrapping Python bindings for a class type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Documentation Issues affecting the Documentation module labels Jul 26, 2026
@hjmjohnson
hjmjohnson requested review from blowekamp and thewtex July 26, 2026 16:22
@hjmjohnson

Copy link
Copy Markdown
Member Author

@thewtex @blowekamp This WIP is a proposal to resolve the ITK/SimpleITK/numpy interoperability inconsistencies. I've marked this as a WIP for discussion purposes. Feel free to criticize, update, adapt, or adopt whatever you think is useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Documentation Issues affecting the Documentation module area:Python wrapping Python bindings for a class type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python image['spacing'] axis-order conflict between ITK (z,y,x) and SimpleITK (x,y,z) blocks generic interop (PR #6021)

1 participant