Transforms
Base classes
- class castalign.base.Transform(**kwargs)[source]
Bases:
objectBase class for all transforms.
This is the core transform interface used across CASTalign. A transform maps 3D volume coordinates from one space to another, and can also be applied to full volumetric images through resampling.
Conceptually, transforms in CASTalign are usually either:
point-based (see
PointTransform), orparameterized transforms that do not use correspondence points.
DEFAULT_PARAMETERSserves two purposes:it provides default values, and
it defines the complete set of constructor keyword parameters accepted by that transform class.
Parameter values are stored in
self.paramsand can be edited in the GUI. These are for user-settable controls (for example shifts, scales, toggles), not values that are fit from selected points.Notes
To implement a new subclass:
Implement
_transform(points)for forward mapping.Implement
invert()for reverse mapping.Implement
_fit()if parameters must be derived from point data._fit()is called during initialization when present.If there is no analytic inverse, subclass
PointTransformNoAnalyticInverse.
Any transform must be exactly reconstructible from
__repr__output.- save(filename)[source]
Save this transform to disk as a reconstructible text string.
- Parameters:
filename (str or path-like) – Output file path.
Notes
The saved content is
repr(self)and is intended to be read back withload().
- static load(filename, version=None)[source]
Load a transform from a file written by
save().- Parameters:
filename (str or path-like) – Input file path containing a transform repr string.
version (int or None, optional) – File format version for this transform text. If
None, uses the current format version. Set to1for older files that may use legacy class names.
- Returns:
Reconstructed transform object.
- Return type:
- transform(points)[source]
Transform 3D point coordinates from source space to target space.
Use this when you want to move landmarks, annotations, or other coordinate sets into the transformed image space.
- Parameters:
points (array-like) – Point coordinates in
(z, y, x)order. Accepts either a single point(3,)or many points(N, 3).- Returns:
Transformed coordinates, with the same single-point vs multi-point structure as the input.
- Return type:
numpy.ndarray
- inverse_transform(points)[source]
Map points from target space back to source space.
- Parameters:
points (numpy.ndarray) – Array with shape
(N, 3)or a single point(3,).- Returns:
Inverse-transformed points with the same leading shape as input.
- Return type:
numpy.ndarray
Notes
Override this for a faster implementation; default is
self.invert().transform(points).
- invert()[source]
Return the inverse transform.
Use this when you need to map coordinates or images in the opposite direction (target space back to source space).
- Returns:
A transform representing the inverse mapping.
- Return type:
Notes
Subclasses must implement this.
- origin_and_maxpos(img, output_size=None, force_size=True)[source]
Compute output-space bounds for a transformed image.
This is used internally to inspect or control the output coordinate box before calling
transform_image. This is especially useful when you need consistent output extents across multiple transformed volumes.- Parameters:
img (numpy.ndarray or ndarray_shifted) – Input 3D image.
output_size (None, sequence, or sequence of 2-tuples, optional) – Output bounds.
None: tight bounds from transformed corners.(z, y, x): explicit upper bounds from origin 0.((zmin, zmax), (ymin, ymax), (xmin, xmax)): explicit bounds.
Nonevalues inside explicit bounds are treated as open bounds.force_size (bool, optional) – If
True, use explicit bounds exactly. IfFalse, treat them as limits and allow smaller computed bounds.
- Returns:
(origin, maxpos)each with shape(3,).- Return type:
tuple of numpy.ndarray
Examples
>>> # Use automatic tight bounds. >>> origin, maxpos = t.origin_and_maxpos(img) >>> # Force a specific output size from origin 0. >>> origin, maxpos = t.origin_and_maxpos(img, output_size=(80, 256, 256)) >>> # Force explicit coordinate bounds. >>> origin, maxpos = t.origin_and_maxpos( ... img, ... output_size=((10, 90), (20, 220), (30, 230)), ... force_size=True, ... )
- transform_image(img, output_size=None, labels=None, force_size=True)[source]
Transform an image
output_sizecontrols the output coordinate box. If it isNone, the transformed image uses a tight bounding box based on transformed corners (and point targets for point-based transforms). If it is explicit, it can be either(z, y, x)max bounds from origin 0, or full per-axis bounds((zmin, zmax), (ymin, ymax), (xmin, xmax)). Withforce_size=Truethese bounds are used exactly; withforce_size=Falsethey are treated as limits and the method may return a smaller box when possible.- Parameters:
img (numpy.ndarray or ndarray_shifted) – Input image. 2D images are promoted to 3D single-slice volumes.
output_size (None, sequence, or sequence of 2-tuples, optional) – Output bounds, same formats as
origin_and_maxpos.labels (bool or None, optional) – Label mode.
True: nearest-neighbor interpolation.False: linear interpolation.None: auto-detect withimage_is_label.
force_size (bool, optional) – If
False, output size may be smaller thanoutput_sizeif the output would include empty space
- Returns:
Transformed image in output coordinates.
- Return type:
ndarray_shifted or numpy.ndarray
Notes
Generic implementation for non-rigid transforms. Subclasses can override with faster special cases.
Examples
>>> # Transform with automatic tight output bounds. >>> out = t.transform_image(img) >>> # Transform a label volume with nearest-neighbor interpolation. >>> out = t.transform_image(labels_img, labels=True) >>> # Transform with explicit output bounds. >>> out = t.transform_image( ... img, ... output_size=((10, 90), (20, 220), (30, 230)), ... )
- static pretransform(*args, **kwargs)[source]
Return the fixed pre-transform applied before this transform.
- Returns:
Pre-transform to apply first. The default is
Identity().- Return type:
Notes
Most transform classes should keep this default. Override it when a class represents a composed transform where only part of the chain is meant to be fit from data (for example, when an earlier component is fixed and only the final component is fit).
- class castalign.base.PointTransform(points_start=None, points_end=None, **kwargs)[source]
Bases:
TransformBase class for transforms fit from point correspondences.
This class stores matched 3D points and is the base for transforms that are learned from those matches.
Notes
Subclasses can rely on:
self.points_start: source coordinates.self.points_end: target coordinates.
Subclasses are expected to implement the standard transform behavior:
forward mapping through
_transform,inverse mapping through
invert,and optional fitting logic in
_fit.
- class castalign.base.AffineTransform[source]
Bases:
objectMixin implementing affine transform behavior.
This class provides shared affine logic for transform classes that represent mappings of the form:
output = input @ matrix - shift.Notes
Subclasses should use
_fitto set:self.matrixwith shape(3, 3)self.shiftwith shape(3,)
This mixin is designed for multiple inheritance with
TransformorPointTransform-derived classes.
- class castalign.base.PointTransformNoAnalyticInverse(*args, **kwargs)[source]
Bases:
PointTransformBase class for point transforms without an analytic inverse.
This class uses numerical inversion when needed, for transforms that are still bijective but do not have a closed-form inverse.
Notes
Subclasses should:
include
{"invert": False}inDEFAULT_PARAMETERSimplement
_transform(points, points_start, points_end)
By default, this class treats
_transformas the inverse-direction map, which is typically the faster direction for image resampling workflows. Passinginvert=Falseflips that behavior.
Parametric transforms
- class castalign.base.RigidParametric(**kwargs)[source]
Bases:
AffineTransform,TransformRigid transform defined by fixed translation and rotation parameters.
- Parameters:
z, y, x (float, optional) – Translation offsets in voxel coordinates.
zrotate, yrotate, xrotate (float, optional) – Clockwise rotation angles (degrees) about each axis.
invert (bool, optional) – If
True, uses the inverse rotation direction.
- class castalign.base.AffineParametric(**kwargs)[source]
Bases:
AffineTransform,TransformAffine transform defined by fixed translation/rotation/scale/shear.
- Parameters:
z, y, x (float, optional) – Translation offsets in voxel coordinates.
zrotate, yrotate, xrotate (float, optional) – Clockwise rotation angles (degrees) about each axis.
zscale, yscale, xscale (float, optional) – Axis-wise scale factors.
yzshear, xzshear, xyshear (float, optional) – Shear coefficients.
invert (bool, optional) – If
True, inverts the combined affine matrix.
- class castalign.base.MatrixParametric(**kwargs)[source]
Bases:
AffineTransform,TransformAffine transform specified directly by matrix coefficients.
- Parameters:
a11, a12, a13, a21, a22, a23, a31, a32, a33 (float, optional) – Entries of the 3x3 affine matrix in row-major order.
z, y, x (float, optional) – Translation offsets in voxel coordinates.
- class castalign.base.FlipParametric(**kwargs)[source]
Bases:
AffineTransform,TransformAxis-flip transform controlled by boolean flip parameters.
- Parameters:
z, y, x (bool, optional) – Whether to flip along each axis.
zthickness, ythickness, xthickness (float or int, optional) – Axis extents used to compute the post-flip shift.
- class castalign.base.RescaleParametric(**kwargs)[source]
Bases:
AffineTransform,TransformAxis-wise rescaling transform with fixed scale parameters.
- Parameters:
z, y, x (float, optional) – Scale factors for each axis.
- class castalign.base.TranslateParametric(**kwargs)[source]
Bases:
AffineTransform,TransformTranslation-only transform with fixed z/y/x offsets.
- Parameters:
z, y, x (float, optional) – Translation offsets in voxel coordinates.
Point-based transforms
- class castalign.base.Identity(**kwargs)[source]
Bases:
AffineTransform,TransformIdentity transform that leaves coordinates unchanged.
- class castalign.base.Translate(points_start=None, points_end=None, **kwargs)[source]
Bases:
AffineTransform,PointTransformTranslation-only transform fit from corresponding points.
- class castalign.base.Rigid(points_start=None, points_end=None, **kwargs)[source]
Bases:
AffineTransform,PointTransformRigid transform fit from points using rotation and translation.
- class castalign.base.Affine(points_start=None, points_end=None, **kwargs)[source]
Bases:
AffineTransform,PointTransformFull affine transform fit from corresponding 3D points.
- class castalign.base.LaminarAffine(points_start=None, points_end=None, **kwargs)[source]
Bases:
AffineTransform,PointTransformLaminar affine fit for section-like data.
Splits fitting into high-variance laminar components plus low-variance normal-depth component to reduce skew in thin volumes. The laminar basis is estimated from the dominant fitted plane of the matched points.
- class castalign.base.Triangulation(points_start=None, points_end=None, **kwargs)[source]
Bases:
PointTransformNonlinear 3D deformation using piecewise-affine triangulation.
This transform warps a 3D volume by building a Delaunay triangulation over control points, then applying a local affine map per tetrahedron.
Notes
The implementation supports both directions of mapping. For one direction it can use
find_simplexdirectly; for the other it manually checks tetrahedron containment, because SciPy does not provide the exact arbitrary-triangulation path needed for this workflow.
- class castalign.base.LaminarTriangulation(points_start=None, points_end=None, **kwargs)[source]
Bases:
PointTransformNonlinear laminar triangulation in 3D.
This is generally the recommended nonlinear transform for mostly flat section-like 3D data (broad in two dimensions, thinner in the third).
If
normal_z,normal_y, andnormal_xare all zero, the normal is estimated automatically from the input points.Notes
The transform triangulates points after projection into the fitted laminar plane, then computes local 3D affine maps using those projected triangles plus a normal-direction anchor so depth is handled consistently.
As with
Triangulation, one mapping direction can usefind_simplexdirectly, while the other uses manual triangle containment checks due to SciPy API limitations for this specific inverse workflow.
Deprecated transforms
- class castalign.base.Flip(**kwargs)[source]
Bases:
AffineTransform,TransformDeprecated parametric axis-flip transform.
- class castalign.base.DistanceWeightedAverageGaussian(*args, **kwargs)[source]
Bases:
PointTransformNoAnalyticInverseDeprecated nonlinear displacement-field transform with Gaussian weighting.