Python library to read and apply CMTK transformations (affine and spline warps)
Project description
cmtk-apply
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 (.listfolder) or aregistrationfile (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 coordinatestransform:"warp"evaluates both affine and spline;"affine"evaluates affine onlyallow_extrapolation: IfFalse, points outside the spline domain return NaNfallback_to_affine: IfTrue, 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 coordinatestransform:"warp"evaluates both affine and spline;"affine"evaluates affine onlyallow_extrapolation: IfFalse, points outside the spline domain return NaNfallback_to_affine: IfTrue, points that fail spline evaluation fall back to affinesolver: 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
reformatxfor that). - The
activefield in spline warps is parsed but not used; all control points are weighted equally (matches behavior of CMTK'sstreamxform).
References
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db8b2e8cf6881b17050f6d1680c4b0e0d87b570dc493b3222ca91db7017dca95
|
|
| MD5 |
aec38553b3cf913ed18d04a5098e99b4
|
|
| BLAKE2b-256 |
57fa8a37d76aac0e1432b7c3ba917c0747907058c90672d1d87fa42388062643
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d442327913214a5983b4d74182b08a712cd580c48834e69e05f1224769e166b7
|
|
| MD5 |
f7f11cb18efa5a766e78e432b5844166
|
|
| BLAKE2b-256 |
4273df89555253f0b28515db82a593992d0b349c584999ee69e5dde1b95f01df
|