# Computing volume header data with freesurferformats

In this document, we show how to derive various data from the header of FreeSurfer brain volume files.

## About the MGH header

The header of MGH (or MGZ) brain volume files can contain important information on the volume data, including orientation, slice thickness, and MR acquisition parameters. The freesurferformats package provides functions to compute important properties from the header.

## Getting access to the header data in MGH or MGZ files

When reading a brain volume, make sure you explicitely request the full data, including the header:

        library("freesurferformats");
        mgh_file = system.file("extdata", "brain.mgz", package = "freesurferformats", mustWork = TRUE);
        brain = read.fs.mgh(mgh_file, with_header = TRUE);

This will give you an `fs.volume` instance, which is very handy. To see the header information, just type the variable name to print it:

    brain
    Brain volume with 4 dimensions '256x256x256x1' and 16777216 voxels.
     - Data dimensions according to header: '256x256x256x1'.
     - Datatype according to header is 0 ('MRI_UCHAR'), values are in range [0.00, 156.00].
     - Header contains vox2ras transformation information. Voxel size is 1.00 x 1.00 x 1.00 mm.
     - Volume is conformed, pimary slice direction is 'coronal', orientation is 'LIA'.
     - Header contains MR acquisition parameters: TR: 2300.00 msec, TE: 2.01 msec, TI: 900.00 msec, flip angle: 9.00 degrees, fov = 256.000.

You can access the volume data in `brain$data` and the header in `brain$header` now.

## Computing more information from the header

Not all MGH files contain a valid header that can be used to compute more information. To check your data, use the `mghheader.is.ras.valid` function:

    mghheader.is.ras.valid(brain$header);

If the header is valid, it can be used to compute various transformation matrices. Here is an example that computes the `vox2ras` matrix and then uses it to get the right, anterior, superior (RAS) coordinates of the voxel at column, row, slice (CRS) index `(128, 128, 128)`:

    voxel = c(128, 128, 128);
    vox2ras = mghheader.vox2ras(brain);
    ras_coords = vox2ras %*% c(voxel, 1);  # the 1 is because we use homogeneous coordinates

### Transformation matrices

You can use the following functions in the same way to compute various matrices:

- `mghheader.vox2ras` – CRS voxel index to RAS coordinate matrix (compute the position of a voxel).
- `mghheader.ras2vox` – RAS coordinate to CRS voxel index matrix (compute the voxel at a position).
- `mghheader.vox2ras.tkr` – like vox2ras above, but uses tkregister space.
- `mghheader.ras2vox.tkr` – like ras2vox above, but uses tkregister space.
- `mghheader.tkreg2scanner` – RAS to RAS transform between tkregister space and scanner space.
- `mghheader.scanner2tkreg` – RAS to RAS transform between scanner space and tkregister space.

### Primary slice direction and volume CRS orientation

To get the primary slice direction:

    mghheader.primary.slice.direction(brain);

To get the orientation string for the 3 axes:

    mghheader.crs.orientation(brain);

### Check whether the volume is conformed

To check whether the volume is conformed:

    mghheader.is.conformed(brain);

A volume is considered conformed if it is in coronal primary slice direction, has CRS dimensions 256x256x256 and a voxel size of 1 mm in all 3 directions.