Source code for AFQ.registration

"""
Registration tools
"""

import nibabel as nib
import numpy as np
from dipy.align.imaffine import AffineMap
from dipy.align.imwarp import DiffeomorphicMap

__all__ = [
    "read_affine_mapping",
    "read_syn_mapping",
    "read_old_mapping",
]


def reduce_shape(shape):
    """
    Reduce dimension in shape to 3 if possible
    """
    try:
        return shape[:3]
    except TypeError:
        return shape


[docs] def read_syn_mapping(disp, codisp): """ Read a syn registration mapping from a nifti file Parameters ---------- disp : str or Nifti1Image If string, file must of an image or ndarray. If image, contains the mapping displacement field in each voxel from subject to template codisp : str or Nifti1Image If string, file must of an image or ndarray. If image, contains the mapping displacement field in each voxel from template to subject Returns ------- A :class:`DiffeomorphicMap` object """ if isinstance(disp, str): disp = nib.load(disp) if isinstance(codisp, str): codisp = nib.load(codisp) mapping = DiffeomorphicMap( dim=3, disp_shape=codisp.get_fdata().shape[:3], disp_grid2world=None, domain_shape=disp.get_fdata().shape[:3], domain_grid2world=None, codomain_shape=codisp.get_fdata().shape[:3], codomain_grid2world=None, ) mapping.forward = disp.get_fdata().astype(np.float32) mapping.backward = codisp.get_fdata().astype(np.float32) return mapping
[docs] def read_affine_mapping(affine, domain_img, codomain_img): """ Read a syn registration mapping from a nifti file Parameters ---------- affine : str or ndarray If string, file must of an ndarray. If ndarray, contains affine transformation used for mapping domain_img : str or Nifti1Image codomain_img : str or Nifti1Image Returns ------- A :class:`AffineMap` object """ if isinstance(affine, str): affine = np.load(affine) if isinstance(domain_img, str): domain_img = nib.load(domain_img) if isinstance(codomain_img, str): codomain_img = nib.load(codomain_img) mapping = AffineMap( affine, domain_grid_shape=reduce_shape(domain_img.shape), domain_grid2world=domain_img.affine, codomain_grid_shape=reduce_shape(codomain_img.shape), codomain_grid2world=codomain_img.affine, ) return mapping
[docs] def read_old_mapping(disp, domain_img, codomain_img, prealign=None): """ Warning: This is only used for pyAFQ tests and backwards compatibility. Read old-style registration mapping from a nifti file. Parameters ---------- disp : str or Nifti1Image If string, file must of an image or ndarray. If image, contains the mapping displacement field in each voxel Shape (x, y, z, 3, 2) domain_img : str or Nifti1Image codomain_img : str or Nifti1Image Returns ------- A :class:`DiffeomorphicMap` object """ if isinstance(disp, str): disp = nib.load(disp) if isinstance(domain_img, str): domain_img = nib.load(domain_img) if isinstance(codomain_img, str): codomain_img = nib.load(codomain_img) mapping = DiffeomorphicMap( 3, disp.shape[:3], disp_grid2world=np.linalg.inv(disp.affine), domain_shape=domain_img.shape[:3], domain_grid2world=domain_img.affine, codomain_shape=codomain_img.shape, codomain_grid2world=codomain_img.affine, prealign=prealign, ) disp_data = disp.get_fdata().astype(np.float32) mapping.forward = disp_data[..., 0] mapping.backward = disp_data[..., 1] mapping.is_inverse = False return mapping