Skip to main content

Python library to read and apply CMTK transformations (affine and spline warps)

Project description

cmtk-apply

Tests

Fast, accurate and user-friendly Python interface for applying CMTK (Computational Morphometry Toolkit) transformations, without requiring subprocess calls to external command-line tools.

Thanks to the use of numba, we are on par for inverse transforms and ~2x faster for forward transforms compared to CMTK's streamxform tool. For smaller point sets the speed-up is even more dramatic due to eliminating overhead from process startup and file I/O. See BENCHMARK_RESULTS.md for details.

Installation

From Github

pip install git+https://github.com/schlegelp/cmtk_apply

From source with development dependencies

Clone the repository and run:

pip install -e ".[dev]"

Quick start

from cmtk_apply import load_registration

# Load a registration (directory or file path)
reg = load_registration("JFRC2_FCWB.list")

# Forward transform points
points = [[10.0, 20.0, 30.0], [40.0, 50.0, 60.0]]
forward = reg.transform_points(points)
print(forward)

# Inverse transform
inverse = reg.inverse_transform_points(forward)
print(inverse)

Optional Fastmath

Enable fastmath for Numba kernels by setting the environment variable:

export CMTK_APPLY_FASTMATH=1

Expected impact (warp forward): ~1.5x speedup with max absolute drift around 1e-13 on typical inputs. Restart the Python process after changing the variable.

API Reference

load_registration(path: str) -> Registration

Load a CMTK registration from a .list folder or registration file.

Parameters:

  • path: Path to a CMTK registration directory (.list folder) or a registration file (optionally gzipped).

Returns: A Registration object.

Registration.transform_points(...) -> np.ndarray

Apply the registration transformation to points.

output = reg.transform_points(
    points,                      # N×3 array-like of 3D points
    transform="warp",            # "warp" (default) or "affine"
    allow_extrapolation=True,   # Allow evaluation outside spline grid
    fallback_to_affine=True,     # Use affine if spline fails
)

Parameters:

  • points: N×3 array or list of 3D coordinates
  • transform: "warp" evaluates both affine and spline; "affine" evaluates affine only
  • allow_extrapolation: If False, points outside the spline domain return NaN
  • fallback_to_affine: If True, points that fail spline evaluation fall back to affine

Returns: N×3 NumPy array of transformed points

Registration.inverse_transform_points(...) -> np.ndarray

Apply the inverse transformation to points.

output = reg.inverse_transform_points(
    points,                      # N×3 array-like of 3D points
    transform="warp",            # "warp" (default) or "affine"
    allow_extrapolation=True,   # Allow evaluation outside spline grid
    fallback_to_affine=True,     # Use affine if spline fails
    solver="auto",               # "auto" (default), "analytical" or "numerical"
)

Parameters:

  • points: N×3 array or list of 3D coordinates
  • transform: "warp" evaluates both affine and spline; "affine" evaluates affine only
  • allow_extrapolation: If False, points outside the spline domain return NaN
  • fallback_to_affine: If True, points that fail spline evaluation fall back to affine
  • solver: Method for solving inverse warp; "auto" uses analytical for >500 points and "numerical" otherwise

Returns: N×3 NumPy array of inverse transformed points

Implementation Details

Spline Warp

The library interprets the absolute flag in the spline warp configuration:

  • absolute yes: Coefficients represent absolute positions → final = spline(affine_transformed_point)
  • absolute no: Coefficients represent displacements → final = affine_transformed_point + spline_displacement

Affine Composition

CMTK affine parameters are decomposed into:

  • xlate: Translation (tx, ty, tz)
  • rotate: Rotation angles in degrees (rx, ry, rz)
  • scale: Anisotropic scaling (sx, sy, sz)
  • shear: Shear components (shx, shy, shz)
  • center: Center of rotation (cx, cy, cz)

The matrix composition follows CMTK's post-2.4.0 convention. Legacy (<2.4.0) behavior is auto-detected from the TypedStream version field.

B-spline Basis

The cubic B-spline basis functions for parameter t ∈ [0,1] are: $$w_0(t) = \frac{(1 - 3t + 3t^2 - t^3)}{6}$$ $$w_1(t) = \frac{(4 - 6t^2 + 3t^3)}{6}$$ $$w_2(t) = \frac{(1 + 3t + 3t^2 - 3t^3)}{6}$$ $$w_3(t) = \frac{t^3}{6}$$

A 4×4×4 neighborhood of control points is evaluated for each query point using tensor products of these weights.

Testing

Run tests with pytest:

pytest tests/

To compare against CMTK's streamxform tool (if available):

pytest -v tests/test_cmtk_xf.py::test_affine_matches_streamxform
pytest -v tests/test_cmtk_xf.py::test_warp_matches_streamxform

Tests skip automatically if streamxform is not in the expected location.

Example: JFRC2 to FCWB Registration

The JFRC2_FCWB.list/ folder contains a pre-computed registration from the Drosophila reference brain JFRC2 to the FCWB template. This registration includes:

  • An affine component (12 DOF)
  • A 59×27×11 B-spline warp grid with deformation coefficients

File Format

CMTK's TypedStream format is a text-based nested structure:

! TYPEDSTREAM 2.4

registration {
  reference_study "..."
  floating_study "..."
  affine_xform {
    xlate 0 0 0
    rotate 0 0 0
    ...
  }
  spline_warp {
    affine_xform { ... }
    absolute yes
    dims 59 27 11
    origin -11.36 -13.24 -16.87
    domain 636.39 317.88 134.99
    coefficients ...
  }
}

Limitations

  • This library focuses on the core transformation logic; it does not reformat images (use CMTK's reformatx for that).
  • The active field in spline warps is parsed but not used; all control points are weighted equally (matches behavior of CMTK's streamxform).

References

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cmtk_apply-0.1.0.tar.gz (336.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cmtk_apply-0.1.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file cmtk_apply-0.1.0.tar.gz.

File metadata

  • Download URL: cmtk_apply-0.1.0.tar.gz
  • Upload date:
  • Size: 336.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.8

File hashes

Hashes for cmtk_apply-0.1.0.tar.gz
Algorithm Hash digest
SHA256 db8b2e8cf6881b17050f6d1680c4b0e0d87b570dc493b3222ca91db7017dca95
MD5 aec38553b3cf913ed18d04a5098e99b4
BLAKE2b-256 57fa8a37d76aac0e1432b7c3ba917c0747907058c90672d1d87fa42388062643

See more details on using hashes here.

File details

Details for the file cmtk_apply-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cmtk_apply-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.8

File hashes

Hashes for cmtk_apply-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d442327913214a5983b4d74182b08a712cd580c48834e69e05f1224769e166b7
MD5 f7f11cb18efa5a766e78e432b5844166
BLAKE2b-256 4273df89555253f0b28515db82a593992d0b349c584999ee69e5dde1b95f01df

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page