Skip to main content

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

Release files for cmtk-apply 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cmtk-apply 0.1.0
File Size Uploaded
cmtk_apply-0.1.0.tar.gz 336.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cmtk-apply 0.1.0
File Interpreter ABI Platform
cmtk_apply-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 352.1 kB

Release files / cmtk_apply-0.1.0.tar.gz

Download URL cmtk_apply-0.1.0.tar.gz
Size 336.8 kB
Tags Source
SHA-256 checksum
How to use checksums
db8b2e8cf6881b17050f6d1680c4b0e0d87b570dc493b3222ca91db7017dca95
BLAKE2b-256 checksum
How to use checksums
57fa8a37d76aac0e1432b7c3ba917c0747907058c90672d1d87fa42388062643
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.8

Release files / cmtk_apply-0.1.0-py3-none-any.whl

Download URL cmtk_apply-0.1.0-py3-none-any.whl
Size 15.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d442327913214a5983b4d74182b08a712cd580c48834e69e05f1224769e166b7
BLAKE2b-256 checksum
How to use checksums
4273df89555253f0b28515db82a593992d0b349c584999ee69e5dde1b95f01df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.8

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page