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.

@thewtex

thewtex commented Aug 4, 2026

Copy link
Copy Markdown
Member

I like the explicit approach 👍

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)

2 participants