Transform API

neuroreg.transforms.LTA

class neuroreg.transforms.LTA(matrix, lta_type, src, dst, subject=None, fscale=None)[source]

FreeSurfer Linear Transform Array.

Wraps a 4×4 affine matrix together with source and destination volume geometry, mirroring the .lta file format used by FreeSurfer.

Typical usage:

lta = LTA.read("T2_to_T1.lta")
print(lta.affine_dist())        # distance to identity
print(lta.affine_dist(other))   # distance to another LTA
lta.invert().write("T1_to_T2.lta")
Parameters:
  • matrix (npt.ArrayLike)

  • lta_type (int)

  • src (dict)

  • dst (dict)

  • subject (str | None)

  • fscale (float | None)

classmethod read(filename, lta_type=None)[source]

Read a FreeSurfer .lta file.

Parameters:
filenamestr or Path
lta_type{0, 1, None}, optional

If given, convert the stored matrix to this type on load.

Returns:
LTA
Parameters:
  • filename (str | Path)

  • lta_type (int | None)

Return type:

LTA

classmethod from_matrix(matrix, src_fname, src_img, dst_fname, dst_img, lta_type=1)[source]

Create an LTA from a matrix and image geometry.

Parameters:
matrixarray-like, shape (4, 4)

May be a torch.Tensor (detached automatically).

src_fnamestr

Source filename stored as metadata in the .lta file.

src_imgpath, nibabel header/image, or dict

Source image geometry.

dst_fnamestr

Destination filename stored as metadata.

dst_imgpath, nibabel header/image, dict, or None

Destination image geometry. If None, the destination volume info is written with valid = 0 to indicate unknown geometry.

lta_type{0, 1}

0 = LINEAR_VOX_TO_VOX, 1 = LINEAR_RAS_TO_RAS (default).

Parameters:
  • matrix (ArrayLike)

  • src_fname (str)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict)

  • dst_fname (str)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • lta_type (int)

Return type:

LTA

write(filename, lta_type=None)[source]

Write to a FreeSurfer .lta file.

Parameters:
filenamestr or Path
lta_type{0, 1, None}, optional

Output transform type. 0 = LINEAR_VOX_TO_VOX, 1 = LINEAR_RAS_TO_RAS. When None (default) the matrix is written as stored. When given and different from the stored type, the matrix is converted before writing; self is not mutated.

Parameters:
  • filename (str | Path)

  • lta_type (int | None)

Return type:

None

r2r()[source]

Return the 4×4 RAS-to-RAS matrix.

Return type:

ndarray

v2v()[source]

Return the 4×4 voxel-to-voxel matrix.

Return type:

ndarray

invert()[source]

Return an inverted copy with src/dst swapped, stored as R2R.

Return type:

LTA

concat(other)[source]

Concatenate two transforms: self (A→B) followed by other (B→C).

Returns a new LTA that maps directly from A to C, stored as R2R. The src geometry is taken from self and the dst geometry from other; the caller is responsible for ensuring that the intermediate spaces (self.dst / other.src) are compatible.

Equivalent to FreeSurfer’s mri_concatenate_lta.

Parameters:
otherLTA

The second transform to apply (maps B → C).

Returns:
LTA

New LTA whose matrix is other.r2r() @ self.r2r(), with src from self and dst from other.

Parameters:

other (LTA)

Return type:

LTA

decompose()[source]

Polar decomposition of the R2R matrix.

See decompose_transform() for the return dict keys.

Return type:

dict

property det: float

Determinant of the R2R matrix.

rigid_dist(other=None)[source]

Rigid-transform distance to other (or identity).

Operates on the RAS-to-RAS representation (converts automatically if stored as vox-to-vox). Delegates to rigid_dist().

Parameters:

other (LTA | None)

Return type:

float

affine_dist(other=None, radius=100.0)[source]

Affine RMS distance to other (Jenkinson 1999).

Operates on the RAS-to-RAS representation (converts automatically if stored as vox-to-vox). Delegates to affine_dist().

Parameters:
  • other (LTA | None)

  • radius (float)

Return type:

float

corner_dist(other=None)[source]

Mean displacement at the 8 source-volume corners in RAS mm.

Operates on the RAS-to-RAS representation (converts automatically if stored as vox-to-vox). Image-specific: depends on source volume shape and affine; see corner_dist() for the full description and limitations.

  • other is None - measures how far each corner moves from its original RAS position under this transform.

  • other is given - measures the separation between the two transforms’ mappings of each corner; both LTAs must share the same source image.

Parameters:
otherLTA, optional

Second transform. None compares this transform against identity.

Returns:
float

Mean corner displacement in mm. Delegates to corner_dist().

Parameters:

other (LTA | None)

Return type:

float

sphere_dist(other=None, radius=100.0)[source]

Max displacement on a sphere of given radius in RAS mm.

Operates on the RAS-to-RAS representation (converts automatically if stored as vox-to-vox). Image-independent: result depends only on the transform, not source/dst geometry. Delegates to sphere_dist().

Parameters:
  • other (LTA | None)

  • radius (float)

Return type:

float

neuroreg.transforms.XFM

class neuroreg.transforms.XFM(matrix, comments=<factory>, src_path=None, dst_path=None)[source]

MNI/MINC linear transform file.

The stored matrix is always the 4x4 scanner-RAS / RAS-to-RAS transform. Comment lines are preserved for round-tripping because FreeSurfer sometimes stores useful provenance there.

Parameters:
  • matrix (ndarray)

  • comments (list[str])

  • src_path (str | None)

  • dst_path (str | None)

classmethod read(filename)[source]

Read an MNI/MINC XFM file from disk.

Parameters:
filenamestr or Path

Path to a linear .xfm transform file.

Returns:
XFM

Parsed XFM wrapper with preserved comment lines.

Raises:
ValueError

If the file header is invalid or the linear transform block cannot be parsed.

Parameters:

filename (str | Path)

Return type:

XFM

classmethod from_lta(lta, comments=None)[source]

Create an XFM wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

commentslist[str] or None, optional

Comment lines to preserve in the output wrapper. When omitted, a simple provenance comment is generated.

Returns:
XFM

Wrapper containing the same RAS-to-RAS matrix and inferred source / destination paths.

Parameters:
  • lta (LTA)

  • comments (list[str] | None)

Return type:

XFM

to_lta(src_fname=None, src_img=None, dst_fname=None, dst_img=None)[source]

Convert the XFM wrapper to canonical scanner-RAS LTA form.

Parameters:
src_fname, dst_fnamestr or None, optional

Optional filenames to store in the output LTA metadata. When not provided, inferred paths from XFM comments are used if available.

src_img, dst_imgheader-like or None, optional

Optional source and destination image headers used to populate LTA volume information.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str | None)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • dst_fname (str | None)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

Return type:

LTA

write(filename)[source]

Write the transform in MNI/MINC XFM text format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.RegisterDat

class neuroreg.transforms.RegisterDat(matrix, subject='subject-unknown', inplane_resolution=1.0, between_plane_resolution=1.0, intensity=0.1, float2int='round')[source]

FreeSurfer tkregister-style volumetric registration file.

Parameters:
  • matrix (ndarray)

  • subject (str)

  • inplane_resolution (float)

  • between_plane_resolution (float)

  • intensity (float)

  • float2int (str)

classmethod read(filename)[source]

Read a FreeSurfer register.dat / tkregister transform file.

Parameters:
filenamestr or Path

Path to a register.dat file.

Returns:
RegisterDat

Parsed register.dat wrapper.

Raises:
ValueError

If the file is shorter than the required header-plus-matrix layout.

Parameters:

filename (str | Path)

Return type:

RegisterDat

classmethod from_lta(lta, *, subject=None, intensity=None, float2int='round')[source]

Create a register.dat transform from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

subjectstr or None, optional

Subject name to store in the output file. When omitted, the subject metadata from lta is used when available.

intensityfloat or None, optional

Intensity scale to store in the output file. When omitted, lta metadata is used when available.

float2int{‘tkregister’, ‘round’, ‘floor’}, default=’round’

Float-to-int conversion mode written to the output file.

Returns:
RegisterDat

Wrapper containing the equivalent tkregister transform.

Parameters:
  • lta (LTA)

  • subject (str | None)

  • intensity (float | None)

  • float2int (str)

Return type:

RegisterDat

to_lta(*, src_fname, src_img, dst_fname, dst_img)[source]

Convert the tkregister transform to canonical RAS-to-RAS LTA.

Parameters:
src_fname, dst_fnamestr

Source and destination filenames stored in the output LTA metadata.

src_img, dst_imgheader-like

Source and destination image headers used to recover tkregister geometry.

Returns:
LTA

Canonical scanner-RAS transform wrapper.

Parameters:
  • src_fname (str)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict)

  • dst_fname (str)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict)

Return type:

LTA

Notes

src is the moving/input volume and dst is the reference/target volume.

write(filename)[source]

Write the transform in register.dat format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.FSLMat

class neuroreg.transforms.FSLMat(matrix)[source]

FSL FLIRT affine matrix file.

The stored matrix maps moving voxels to reference voxels in FSL conventions, so conversion to canonical scanner-RAS space requires explicit moving and reference image geometry.

Parameters:

matrix (ndarray)

classmethod read(filename)[source]

Read an FSL FLIRT matrix file.

Parameters:
filenamestr or Path

Path to a text .mat file containing a 4x4 FLIRT affine.

Returns:
FSLMat

Parsed FSL matrix wrapper.

Raises:
ValueError

If the file does not contain exactly four rows of four values.

Parameters:

filename (str | Path)

Return type:

FSLMat

classmethod from_lta(lta)[source]

Create an FSL matrix wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

Returns:
FSLMat

Wrapper containing the equivalent FLIRT voxel-space affine.

Parameters:

lta (LTA)

Return type:

FSLMat

to_lta(*, src_fname, src_img, dst_fname, dst_img)[source]

Convert the FSL matrix to canonical scanner-RAS LTA form.

Parameters:
src_fname, dst_fnamestr

Source and destination filenames stored in the output LTA metadata.

src_img, dst_imgheader-like

Source and destination image headers used to resolve the FSL voxel conventions.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict)

  • dst_fname (str)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict)

Return type:

LTA

write(filename)[source]

Write the matrix in FSL text format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.ITKTransform

class neuroreg.transforms.ITKTransform(matrix, transform_type='AffineTransform_double_3_3')[source]

ITK/ANTs 3D affine text transform file.

The stored matrix is the file-space LPS affine mapping fixed/reference points to moving/source points. Conversion to canonical scanner-RAS LTA therefore converts LPS to RAS and inverts the matrix.

Parameters:
  • matrix (ndarray)

  • transform_type (str)

classmethod read(filename)[source]

Read an ITK affine text transform from disk.

Parameters:
filenamestr or Path

Path to an ITK .tfm-style affine transform file.

Returns:
ITKTransform

Parsed transform wrapper.

Raises:
ValueError

If the file is malformed or does not contain a supported 3-D affine transform.

Parameters:

filename (str | Path)

Return type:

ITKTransform

classmethod from_lta(lta)[source]

Create an ITK transform wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

Returns:
ITKTransform

Wrapper containing the equivalent ITK/ANTs file-space affine.

Parameters:

lta (LTA)

Return type:

ITKTransform

to_lta(src_fname=None, src_img=None, dst_fname=None, dst_img=None)[source]

Convert the ITK transform to canonical scanner-RAS LTA form.

Parameters:
src_fname, dst_fnamestr or None, optional

Optional filenames to store in the output LTA metadata.

src_img, dst_imgheader-like or None, optional

Optional source and destination image headers used to populate LTA volume information.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str | None)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • dst_fname (str | None)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

Return type:

LTA

write(filename)[source]

Write the transform in ITK text format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.ANTsMatTransform

class neuroreg.transforms.ANTsMatTransform(matrix, transform_type='AffineTransform_double_3_3', fixed_parameters=<factory>)[source]

ANTs / ITK Matlab-format affine transform.

This corresponds to the common 0GenericAffine.mat files written by ANTs. The stored transform uses the same physical-space ITK affine parameterization and LPS fixed-to-moving convention as text .tfm files, but is serialized via ITK’s Matlab transform IO backend instead of the legacy text format.

Parameters:
  • matrix (ndarray)

  • transform_type (str)

  • fixed_parameters (ndarray)

classmethod read(filename)[source]

Read an ANTs Matlab-format affine transform from disk.

Parameters:
filenamestr or Path

Path to an ANTs 0GenericAffine.mat-style transform file.

Returns:
ANTsMatTransform

Parsed ANTs Matlab transform wrapper.

Raises:
ValueError

If the file does not contain exactly one supported affine transform payload.

Parameters:

filename (str | Path)

Return type:

ANTsMatTransform

classmethod from_lta(lta)[source]

Create an ANTs Matlab transform wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

Returns:
ANTsMatTransform

Wrapper containing the equivalent ANTs/ITK file-space affine.

Parameters:

lta (LTA)

Return type:

ANTsMatTransform

to_lta(src_fname=None, src_img=None, dst_fname=None, dst_img=None)[source]

Convert the ANTs Matlab transform to canonical LTA form.

Parameters:
src_fname, dst_fnamestr or None, optional

Optional filenames to store in the output LTA metadata.

src_img, dst_imgheader-like or None, optional

Optional source and destination image headers used to populate LTA volume information.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str | None)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • dst_fname (str | None)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

Return type:

LTA

write(filename)[source]

Write the transform in ANTs Matlab .mat format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.AFNIAffine

class neuroreg.transforms.AFNIAffine(matrix)[source]

AFNI affine text transform.

Supports the common ASCII 3x4 affine encodings used by AFNI tools such as 3dAllineate and cat_matvec: 3x4 text, augmented 4x4 text, or a single row of 12 values as in .aff12.1D files.

This implementation interprets the stored matrix in AFNI’s DICOM/LPS physical coordinate convention and converts it to canonical scanner-RAS for LTA interop.

Parameters:

matrix (ndarray)

classmethod read(filename)[source]

Read an AFNI affine text transform from disk.

Parameters:
filenamestr or Path

Path to an AFNI affine text file, including .aff12.1D files.

Returns:
AFNIAffine

Parsed AFNI affine wrapper.

Raises:
ValueError

If the file cannot be interpreted as a supported AFNI affine text encoding.

Parameters:

filename (str | Path)

Return type:

AFNIAffine

classmethod from_lta(lta)[source]

Create an AFNI affine wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

Returns:
AFNIAffine

Wrapper containing the equivalent AFNI/DICOM-LPS affine.

Parameters:

lta (LTA)

Return type:

AFNIAffine

to_lta(src_fname=None, src_img=None, dst_fname=None, dst_img=None)[source]

Convert the AFNI affine to canonical scanner-RAS LTA form.

Parameters:
src_fname, dst_fnamestr or None, optional

Optional filenames to store in the output LTA metadata.

src_img, dst_imgheader-like or None, optional

Optional source and destination image headers used to populate LTA volume information.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str | None)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • dst_fname (str | None)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

Return type:

LTA

write(filename)[source]

Write the affine in AFNI text format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

neuroreg.transforms.NiftyRegTransform

class neuroreg.transforms.NiftyRegTransform(matrix)[source]

NiftyReg 3D affine text matrix.

FreeSurfer lta_convert treats the stored matrix as the inverse of the canonical scanner-RAS transform, i.e. target/reference RAS to source/moving RAS.

Parameters:

matrix (ndarray)

classmethod read(filename)[source]

Read a NiftyReg affine text matrix from disk.

Parameters:
filenamestr or Path

Path to a NiftyReg affine text file.

Returns:
NiftyRegTransform

Parsed NiftyReg transform wrapper.

Raises:
ValueError

If the file does not contain exactly four rows of four values.

Parameters:

filename (str | Path)

Return type:

NiftyRegTransform

classmethod from_lta(lta)[source]

Create a NiftyReg transform wrapper from a canonical LTA.

Parameters:
ltaLTA

Canonical scanner-RAS transform mapping moving to reference space.

Returns:
NiftyRegTransform

Wrapper containing the equivalent NiftyReg file-space matrix.

Parameters:

lta (LTA)

Return type:

NiftyRegTransform

to_lta(src_fname=None, src_img=None, dst_fname=None, dst_img=None)[source]

Convert the NiftyReg matrix to canonical scanner-RAS LTA form.

Parameters:
src_fname, dst_fnamestr or None, optional

Optional filenames to store in the output LTA metadata.

src_img, dst_imgheader-like or None, optional

Optional source and destination image headers used to populate LTA volume information.

Returns:
LTA

Canonical RAS-to-RAS transform wrapper.

Parameters:
  • src_fname (str | None)

  • src_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

  • dst_fname (str | None)

  • dst_img (str | Path | Nifti1Header | MGHHeader | Nifti1Image | MGHImage | dict | None)

Return type:

LTA

write(filename)[source]

Write the matrix in NiftyReg text format.

Parameters:
filenamestr or Path

Output transform path.

Returns:
None

Writes the transform to filename.

Parameters:

filename (str | Path)

Return type:

None

Selected transform helpers

neuroreg.transforms.convert_transform_type(matrix, src_affine, dst_affine, from_type, to_type)[source]

Convert a transformation matrix between vox-to-vox and RAS-to-RAS.

Parameters:
matrixarray-like, shape (4, 4)

Input transformation matrix.

src_affinearray-like, shape (4, 4)

Source image voxel-to-RAS affine (nibabel img.affine).

dst_affinearray-like, shape (4, 4)

Destination image voxel-to-RAS affine.

from_typeint

Type of the input matrix: LINEAR_VOX_TO_VOX (0) or LINEAR_RAS_TO_RAS (1).

to_typeint

Desired output type: LINEAR_VOX_TO_VOX (0) or LINEAR_RAS_TO_RAS (1).

Returns:
np.ndarray, shape (4, 4)

Converted transformation matrix. Returns a copy when from_type == to_type.

Raises:
ValueError

If from_type or to_type is not 0 or 1.

Parameters:
  • matrix (ArrayLike)

  • src_affine (ArrayLike)

  • dst_affine (ArrayLike)

  • from_type (int)

  • to_type (int)

Return type:

ndarray

Notes

Conversion formulae (M = matrix, A_s = src_affine, A_d = dst_affine):

  • vox→vox to RAS→RAS: A_d @ M @ inv(A_s)

  • RAS→RAS to vox→vox: inv(A_d) @ M @ A_s

neuroreg.transforms.get_affine(translation, rotvec=None, scales=None)[source]

Generate a 4 × 4 affine matrix from translation, rotation, and scale.

Parameters:
translationtorch.Tensor, shape (3,)

Translation vector.

rotvectorch.Tensor, shape (3,), optional

Euler angles [rx, ry, rz] in radians.

scalestorch.Tensor, shape (3,), optional

Per-axis scaling factors.

Returns:
torch.Tensor, shape (4, 4)

Affine transformation matrix.

Parameters:
  • translation (Tensor)

  • rotvec (Tensor | None)

  • scales (Tensor | None)

Return type:

Tensor

neuroreg.transforms.decompose_transform(M)[source]

Polar decomposition of a 4×4 affine matrix.

Decomposes the upper-left 3×3 linear part as

\[A = R \cdot S \cdot \operatorname{diag}(\text{scales})\]

where R is a proper rotation matrix, S is a shear matrix (ones on the diagonal), and diag(scales) captures anisotropic scaling. The translation vector is in mm because the input is expected to be RAS-to-RAS.

Corresponds to dist type 7 in FreeSurfer’s lta_diff (decompose).

Parameters:
Marray-like, shape (4, 4)

Affine matrix to decompose. For the two-transform case pass the concatenation M1 @ M2 (not the difference inv(M1) @ M2). Example: decompose_transform(lta1.r2r() @ lta2.r2r()).

Returns:
dict
rotationndarray, shape (3, 3)

Rotation matrix (det = +1).

rot_vecndarray, shape (3,)

Rotation vector (axis × angle, radians).

rot_angle_degfloat

Rotation angle in degrees.

shearndarray, shape (3, 3)

Shear matrix (unit diagonal).

scalesndarray, shape (3,)

Per-axis scale factors.

translationndarray, shape (3,)

Translation vector in mm.

abs_transfloat

Euclidean norm of the translation vector (mm).

determinantfloat

Determinant of the full 4×4 matrix.

Parameters:

M (ArrayLike)

Return type:

dict

neuroreg.transforms.rigid_dist(M1, M2=None)[source]

Rigid-transform distance between M1 and M2 (or M1 vs identity).

Both matrices must be RAS-to-RAS; the translation component is then in mm and the result has consistent physical units.

\[D = \sqrt{\|T_d\|^2 + \|\log R_d\|_F^2}\]

where \(d = M_1^{-1} M_2\) when M2 is given, else \(d = M_1\). \(T_d\) is the translation part (mm) and \(\|\log R_d\|_F\) is the Frobenius norm of the rotation-matrix logarithm (sqrt(2) × rotation angle in radians).

Corresponds to dist type 1 in FreeSurfer’s lta_diff.

Parameters:
M1array-like, shape (4, 4)

First (or only) RAS-to-RAS rigid transform.

M2array-like, shape (4, 4), optional

Second RAS-to-RAS rigid transform. When None, the distance to the identity is returned.

Returns:
float

Rigid-transform distance (mm and radians added in quadrature).

Parameters:
  • M1 (ArrayLike)

  • M2 (ArrayLike | None)

Return type:

float

neuroreg.transforms.affine_dist(M1, M2=None, radius=100.0)[source]

RMS affine-transform distance (Jenkinson 1999).

Both matrices must be RAS-to-RAS; the translation component is then in mm and radius has a consistent mm interpretation.

\[D = \sqrt{\frac{r^2}{5} \operatorname{Tr}(A^\top A) + \|T_d\|^2}\]

where \(d = M_1 - M_2\) (or \(M_1 - I\) when M2 is None), A is the upper-left 3×3 linear part of d, and \(T_d\) is the translation column (mm). r is the assumed brain radius in mm.

Reference: Jenkinson (1999), A method for motion correction of fMRI time-series, FMRIB Technical Report TR99MJ1.

Corresponds to dist type 2 in FreeSurfer’s lta_diff.

Parameters:
M1array-like or torch.Tensor, shape (4, 4)

First (or only) RAS-to-RAS transform.

M2array-like or torch.Tensor, shape (4, 4), optional

Second RAS-to-RAS transform. When None, the distance to identity is returned.

radiusfloat, default=100.0

Radius of the brain sphere in mm.

Returns:
float

RMS displacement in mm.

Parameters:
  • M1 (ArrayLike | Tensor)

  • M2 (ArrayLike | Tensor | None)

  • radius (float)

Return type:

float

Notes

The function accepts either NumPy-like arrays or torch tensors. When torch tensors are passed, the computation stays in torch until the final scalar conversion, which keeps it suitable for CPU/GPU registration loops.

neuroreg.transforms.corner_dist(M, src_shape, M2=None, src_affine=None)[source]

Mean displacement at the 8 corners of the source volume.

For a single transform (M2 is None), places each of the 8 source corners in RAS space via src_affine and measures how far M moves each corner from its original RAS position:

\[d_i = \|M \cdot c_i - c_i\|, \quad \text{result} = \tfrac{1}{8}\sum_i d_i\]

For two transforms, measures the separation between the two mappings of each corner:

\[d_i = \|M_1 \cdot c_i - M_2 \cdot c_i\|, \quad \text{result} = \tfrac{1}{8}\sum_i d_i\]

Both transforms must map the same source image, so src_affine and src_shape are unambiguous.

Image-specific metric: the result depends on the source image geometry, not just the transform. Corners at the edge of a large or padded FOV may be far from brain tissue, making the result less representative than sphere_dist() for typical neuroimaging use.

Corresponds to dist type 3 in FreeSurfer’s lta_diff.

Parameters:
Marray-like, shape (4, 4)

First (or only) RAS-to-RAS transform.

src_shapetuple of int (i_size, j_size, k_size)

Voxel dimensions of the source volume (width x height x depth).

M2array-like, shape (4, 4), optional

Second RAS-to-RAS transform. When None, displacement of each corner from its own RAS position (that is, comparison with identity) is measured.

src_affinearray-like, shape (4, 4), optional

Voxel-to-RAS affine of the source image. When given, the 8 corners are converted to RAS before applying the transform(s) and the result is in mm. When None, corners remain in voxel units.

Returns:
float

Mean corner displacement in mm (or voxels if src_affine is None).

Parameters:
  • M (ArrayLike)

  • src_shape (tuple[int, int, int])

  • M2 (ArrayLike | None)

  • src_affine (ArrayLike | None)

Return type:

float

neuroreg.transforms.sphere_dist(M1, M2=None, radius=100.0)[source]

Maximum displacement on a sphere of given radius (mm).

Samples approximately 1,600 points on a sphere of radius mm centred at the RAS origin and returns the peak displacement caused by the transform difference. Both matrices must be RAS-to-RAS so that the sphere is in a meaningful physical space and displacements are in mm.

\[ \begin{align}\begin{aligned}M_d = M_1^{-1} M_2 \quad \text{(or } M_d = M_1 \text{ when } M_2 = \text{None)}\\\text{result} = \max_{p\,\in\,\text{sphere}} \|M_d \, p - p\|\end{aligned}\end{align} \]

When M2 is None, this measures how far M1 alone displaces points on the sphere from their original positions (comparison with identity).

Unlike corner_dist() this metric is image-independent: the sphere is a canonical approximation of the head and the result depends only on the transforms, not on source volume geometry.

Corresponds to dist type 4 in FreeSurfer’s lta_diff.

Parameters:
M1array-like, shape (4, 4)

First (or only) RAS-to-RAS transform.

M2array-like, shape (4, 4), optional

Second RAS-to-RAS transform. When None, displacement from identity is returned.

radiusfloat, default=100.0

Sphere radius in mm (roughly the head radius).

Returns:
float

Maximum displacement in mm over all sampled sphere points.

Parameters:
  • M1 (ArrayLike)

  • M2 (ArrayLike | None)

  • radius (float)

Return type:

float