# NiBabel

### Access a cacophony of neuro-imaging file formats

# `affines`

Utility routines for working with points and affine transforms

`AffineError` | Errors in calculating or using affines
`append_diag`(aff, steps[, starts]) | Add diagonal elements steps and translations starts to affine
`apply_affine`(aff, pts[, inplace]) | Apply affine matrix aff to points pts
`dot_reduce`(*args) | Apply numpy dot product function from right to left on arrays
`from_matvec`(matrix[, vector]) | Combine a matrix and vector into an homogeneous affine
`obliquity`(affine) | Estimate the obliquity an affine's axes represent
`rescale_affine`(affine, shape, zooms[, new_shape]) | Return a new affine matrix with updated voxel sizes (zooms)
`to_matvec`(transform) | Split a transform into its matrix and vector components
`voxel_sizes`(affine) | Return voxel size for each input axis given affine

## `AffineError`

class nibabel.affines.AffineError

  Bases: `ValueError`

  Errors in calculating or using affines

  __init__(*args, **kwargs)

## append_diag

nibabel.affines.append_diag(aff, steps, starts=())

  Add diagonal elements steps and translations starts to affine

  Typical use is in expanding 4x4 affines to larger dimensions. Nipy is the main consumer because it uses NxM affines, whereas we generally only use 4x4 affines; the routine is here for convenience.

  Parameters:
    aff 2D array

      N by M affine matrix

    steps scalar or sequence

      diagonal elements to append.

    starts scalar or sequence

      elements to append to last column of aff, representing translations corresponding to the steps. If empty, expands to a vector of zeros of the same length as steps

  Returns:
    aff_plus 2D array

      Now P by Q where L = `len(steps)` and P == N+L, Q=N+L

  Examples

      >>> aff = np.eye(4)
      >>> aff[:3,:3] = np.arange(9).reshape((3,3))
      >>> append_diag(aff, [9, 10], [99,100])
      array([[  0.,   1.,   2.,   0.,   0.,   0.],
             [  3.,   4.,   5.,   0.,   0.,   0.],
             [  6.,   7.,   8.,   0.,   0.,   0.],
             [  0.,   0.,   0.,   9.,   0.,  99.],
             [  0.,   0.,   0.,   0.,  10., 100.],
             [  0.,   0.,   0.,   0.,   0.,   1.]])

## apply_affine

nibabel.affines.apply_affine(aff, pts, inplace=False)

  Apply affine matrix aff to points pts

  Returns result of application of aff to the right of pts. The coordinate dimension of pts should be the last.

  For the 3D case, aff will be shape (4,4) and pts will have final axis length 3 - maybe it will just be N by 3. The return value is the transformed points, in this case:

      res = np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]
      transformed_pts = res.T

  This routine is more general than 3D, in that aff can have any shape (N,N), and pts can have any shape, as long as the last dimension is for the coordinates, and is therefore length N-1.

  Parameters:
    aff(N, N) array-like

      Homogeneous affine, for 3D points, will be 4 by 4. Contrary to first appearance, the affine will be applied on the left of pts.

    pts(…, N-1) array-like

      Points, where the last dimension contains the coordinates of each point. For 3D, the last dimension will be length 3.

    inplace bool, optional

      If True, attempt to apply the affine directly to `pts`. If False, or in-place application fails, a freshly allocated array will be returned.

  Returns:
    transformed_pts(…, N-1) array

      transformed points

  Examples

      >>> aff = np.array([[0,2,0,10],[3,0,0,11],[0,0,4,12],[0,0,0,1]])
      >>> pts = np.array([[1,2,3],[2,3,4],[4,5,6],[6,7,8]])
      >>> apply_affine(aff, pts)
      array([[14, 14, 24],
             [16, 17, 28],
             [20, 23, 36],
             [24, 29, 44]]...)

  Just to show that in the simple 3D case, it is equivalent to:

      >>> (np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]).T
      array([[14, 14, 24],
             [16, 17, 28],
             [20, 23, 36],
             [24, 29, 44]]...)

  But pts can be a more complicated shape:

      >>> pts = pts.reshape((2,2,3))
      >>> apply_affine(aff, pts)
      array([[[14, 14, 24],
              [16, 17, 28]],

             [[20, 23, 36],
              [24, 29, 44]]]...)

## dot_reduce

nibabel.affines.dot_reduce(*args)

  Apply numpy dot product function from right to left on arrays

  For passed arrays \(A, B, C, ... Z\) returns \(A \dot B \dot C ... \dot Z\) where “.” is the numpy array dot product.

  Parameters:
    **args arrays

      Arrays that can be passed to numpy `dot` function

  Returns:
    dot_product array

      If there are N arguments, result of `arg[0].dot(arg[1].dot(arg[2].dot ... arg[N-2].dot(arg[N-1])))...`

## from_matvec

nibabel.affines.from_matvec(matrix, vector=None)

  Combine a matrix and vector into an homogeneous affine

  Combine a rotation / scaling / shearing matrix and translation vector into a transform in homogeneous coordinates.

  Parameters:
    matrix array-like

      An NxM array representing the the linear part of the transform. A transform from an M-dimensional space to an N-dimensional space.

    vector None or array-like, optional

      None or an (N,) array representing the translation. None corresponds to an (N,) array of zeros.

  Returns:
    xform array

      An (N+1, M+1) homogeneous transform matrix.

  See also

  `to_matvec`

  Examples

      >>> from_matvec(np.diag([2, 3, 4]), [9, 10, 11])
      array([[ 2,  0,  0,  9],
             [ 0,  3,  0, 10],
             [ 0,  0,  4, 11],
             [ 0,  0,  0,  1]])

  The vector argument is optional:

      >>> from_matvec(np.diag([2, 3, 4]))
      array([[2, 0, 0, 0],
             [0, 3, 0, 0],
             [0, 0, 4, 0],
             [0, 0, 0, 1]])

## obliquity

nibabel.affines.obliquity(affine)

  Estimate the obliquity an affine’s axes represent

  The term obliquity is defined here as the rotation of those axes with respect to the cardinal axes. This implementation is inspired by AFNI’s implementation. For further details about obliquity, check AFNI’s documentation.

  Parameters:
    affine 2D array-like

      Affine transformation array. Usually shape (4, 4), but can be any 2D array.

  Returns:
    angles 1D array-like

      The obliquity of each axis with respect to the cardinal axes, in radians.

## rescale_affine

nibabel.affines.rescale_affine(affine, shape, zooms, new_shape=None)

  Return a new affine matrix with updated voxel sizes (zooms)

  This function preserves the rotations and shears of the original affine, as well as the RAS location of the central voxel of the image.

  Parameters:
    affine(N, N) array-like

      NxN transform matrix in homogeneous coordinates representing an affine transformation from an (N-1)-dimensional space to an (N-1)-dimensional space. An example is a 4x4 transform representing rotations and translations in 3 dimensions.

    shape(N-1,) array-like

      The extent of the (N-1) dimensions of the original space

    zooms(N-1,) array-like

      The size of voxels of the output affine

    new_shape(N-1,) array-like, optional

      The extent of the (N-1) dimensions of the space described by the new affine. If `None`, use `shape`.

  Returns:
    affine(N, N) array

      A new affine transform with the specified voxel sizes

## to_matvec

nibabel.affines.to_matvec(transform)

  Split a transform into its matrix and vector components

  The transformation must be represented in homogeneous coordinates and is split into its rotation matrix and translation vector components.

  Parameters:
    transform array-like

      NxM transform matrix in homogeneous coordinates representing an affine transformation from an (N-1)-dimensional space to an (M-1)-dimensional space. An example is a 4x4 transform representing rotations and translations in 3 dimensions. A 4x3 matrix can represent a 2-dimensional plane embedded in 3 dimensional space.

  Returns:
    matrix(N-1, M-1) array

      Matrix component of transform

    vector(M-1,) array

      Vector component of transform

  See also

  `from_matvec`

  Examples

      >>> aff = np.diag([2, 3, 4, 1])
      >>> aff[:3,3] = [9, 10, 11]
      >>> to_matvec(aff)
      (array([[2, 0, 0],
             [0, 3, 0],
             [0, 0, 4]]), array([ 9, 10, 11]))

## voxel_sizes

nibabel.affines.voxel_sizes(affine)

  Return voxel size for each input axis given affine

  The affine is the mapping between array (voxel) coordinates and mm (world) coordinates.

  The voxel size for the first voxel (array) axis is the distance moved in world coordinates when moving one unit along the first voxel (array) axis. This is the distance between the world coordinate of voxel (0, 0, 0) and the world coordinate of voxel (1, 0, 0). The world coordinate vector of voxel coordinate vector (0, 0, 0) is given by `v0 = affine.dot((0, 0, 0, 1)[:3]`. The world coordinate vector of voxel vector (1, 0, 0) is `v1_ax1 = affine.dot((1, 0, 0, 1))[:3]`. The final 1 in the voxel vectors and the `[:3]` at the end are because the affine works on homogeneous coordinates. The translations part of the affine is `trans = affine[:3, 3]`, and the rotations, zooms and shearing part of the affine is `rzs = affine[:3, :3]`. Because of the final 1 in the input voxel vector, `v0 == rzs.dot((0, 0, 0)) + trans`, and `v1_ax1 == rzs.dot((1, 0, 0)) + trans`, and the difference vector is `rzs.dot((0, 0, 0)) - rzs.dot((1, 0, 0)) == rzs.dot((1, 0, 0)) == rzs[:, 0]`. The distance vectors in world coordinates between (0, 0, 0) and (1, 0, 0), (0, 1, 0), (0, 0, 1) are given by `rzs.dot(np.eye(3)) = rzs`. The voxel sizes are the Euclidean lengths of the distance vectors. So, the voxel sizes are the Euclidean lengths of the columns of the affine (excluding the last row and column of the affine).

  Parameters:
    affine 2D array-like

      Affine transformation array. Usually shape (4, 4), but can be any 2D array.

  Returns:
    vox_sizes 1D array

      Voxel sizes for each input axis of affine. Usually 1D array length 3, but in general has length (N-1) where input affine is shape (M, N).