Skip to content

brainhops.io.base.freesurfer

The volume geometry shared by every FreeSurfer format.

FreeSurfer describes the world placement of a volume the same way in every file that records one -- the header of an MGH/MGZ image, the source and destination blocks of an LTA transform, the source and atlas geometries of a non-linear morph (.m3z), ... -- with:

  • the volume's shape, in voxels (width, height, depth);
  • the voxel size (xsize, ysize, zsize), in millimetres;
  • the direction cosines of each voxel axis in RAS (x_ras, y_ras, z_ras), which form the columns of the rotation part of the voxel-to-RAS matrix;
  • the RAS coordinates of the centre of the volume (c_ras, Pxyz_c).

Three coordinate systems derive from it:

  • scanner RAS, the world space the volume was acquired in (mri_info --vox2ras);
  • tkr RAS (also "surface RAS" or "tkregister RAS"), the space FreeSurfer surfaces live in. It has the same voxel sizes but drops the direction cosines and c_ras: the centre of the volume is the origin, and the axes are those of a conformed (LIA) volume (mri_info --vox2ras-tkr);
  • physical (or "physvox"), the scaled voxel space shifted so that its origin is the centre of the volume. It is the space between voxels and scanner RAS used by LTA files of type LINEAR_PHYSVOX.

The centre of the volume

FreeSurfer places the centre of the volume at voxel coordinate shape / 2, not at (shape - 1) / 2. With 0-based voxel coordinates whose integers are voxel centres, the centre therefore falls half a voxel past the true centre of an even-sized volume. This is FreeSurfer's convention, and every matrix here follows it so that it matches FreeSurfer and nibabel exactly.

The functions take the geometry as plain values, so that each format reads it from wherever it stores it.

Every FreeSurfer format -- MGH/MGZ images, LTA transforms, morphs, ... -- derives from [FreesurferFormat][brainhops.io.base.freesurfer. FreesurferFormat], so that the "freesurfer" hint selects them all.

Attributes

FS_DEFAULT_XRAS module-attribute

FS_DEFAULT_XRAS: _3Floats = (-1.0, 0.0, 0.0)

Direction cosine of the first voxel axis of a default (LIA) volume.

FS_DEFAULT_YRAS module-attribute

FS_DEFAULT_YRAS: _3Floats = (0.0, 0.0, -1.0)

Direction cosine of the second voxel axis of a default (LIA) volume.

FS_DEFAULT_ZRAS module-attribute

FS_DEFAULT_ZRAS: _3Floats = (0.0, 1.0, 0.0)

Direction cosine of the third voxel axis of a default (LIA) volume.

FreeSurfer falls back on these three -- a coronal, "conformed" LIA orientation -- with a 1 mm voxel size and a zero c_ras when a volume records no valid geometry (an MGH header whose goodRASFlag is not positive, an LTA volume marked invalid).

Classes

FreesurferFormat

A format of the FreeSurfer family, whatever it stores.

It is the shared base of the FreeSurfer image formats (MGH/MGZ) and transformation formats (LTA, M3Z), and carries the "freesurfer" hint they all answer to. Each format adds its own hints ("mgh", "lta", "m3z", ...), which are then also reachable as "freesurfer.mgh", "freesurfer.lta", ...

Functions:

fs_vox2phys

fs_vox2phys(
    shape: Sequence[int], voxelsize: _Vec
) -> ndarray

The (4, 4) matrix from voxel to physical (centred scaled voxel) space.

It scales by the voxel size and moves the origin to the centre of the volume, voxel shape / 2.

fs_phys2ras

fs_phys2ras(
    xras: _Vec, yras: _Vec, zras: _Vec, cras: _Vec
) -> ndarray

The (4, 4) matrix from physical space to scanner RAS.

Its columns are the three direction cosines and the centre of the volume.

fs_vox2ras

fs_vox2ras(
    shape: Sequence[int],
    voxelsize: _Vec,
    xras: _Vec,
    yras: _Vec,
    zras: _Vec,
    cras: _Vec,
) -> ndarray

The (4, 4) matrix from voxel space to scanner RAS.

fs_vox2tkr

fs_vox2tkr(
    shape: Sequence[int], voxelsize: _Vec
) -> ndarray

The (4, 4) matrix from voxel space to tkr (surface) RAS.

This is FreeSurfer's Torig: the voxel-to-RAS matrix of the same volume with default (LIA) direction cosines and a zero c_ras. It depends only on the shape and the voxel size.

fs_geometry_from_vox2ras

fs_geometry_from_vox2ras(
    vox2ras: ndarray, shape: Sequence[int]
) -> tuple[
    _3Floats, _3Floats, _3Floats, _3Floats, _3Floats
]

Decompose a voxel-to-RAS matrix into FreeSurfer's volume geometry.

This is the inverse of fs_vox2ras: the voxel size is the norm of each column, the direction cosines are the normalised columns, and the centre is the RAS position of voxel shape / 2. A matrix with a shear, which FreeSurfer cannot store, loses it: the direction cosines are then not orthogonal, exactly as FreeSurfer would write them.

Returns:

Type Description
voxelsize, xras, yras, zras, cras : tuple of three floats each

mat2orient

mat2orient(vox2ras: ndarray) -> str

Convert a vox2ras matrix to an orientation string, such as "LIA".