nibabel.cifti2.cifti2_axes

Defines Axis objects to create, read, and manipulate CIFTI-2 files

These axes provide an alternative interface to the information in the CIFTI-2 header. Each type of CIFTI-2 axes describing the rows/columns in a CIFTI-2 matrix is given a unique class:

  • BrainModelAxis: each row/column is a voxel or vertex

  • ParcelsAxis: each row/column is a group of voxels and/or vertices

  • ScalarAxis: each row/column has a unique name (with optional meta-data)

  • LabelAxis: each row/column has a unique name and label table (with optional meta-data)

  • SeriesAxis: each row/column is a timepoint, which increases monotonically

All of these classes are derived from the Axis class.

After loading a CIFTI-2 file a tuple of axes describing the rows and columns can be obtained from the cifti2.Cifti2Header.get_axis() method on the header object (e.g. nibabel.load(<filename>).header.get_axis()). Inversely, a new cifti2.Cifti2Header object can be created from existing Axis objects using the cifti2.Cifti2Header.from_axes() factory method.

CIFTI-2 Axis objects of the same type can be concatenated using the ‘+’-operator. Numpy indexing also works on axes (except for SeriesAxis objects, which have to remain monotonically increasing or decreasing).

Creating new CIFTI-2 axes

New Axis objects can be constructed by providing a description for what is contained in each row/column of the described tensor. For each Axis sub-class this descriptor is:

  • BrainModelAxis: a CIFTI-2 structure name and a voxel or vertex index

  • ParcelsAxis: a name and a sequence of voxel and vertex indices

  • ScalarAxis: a name and optionally a dict of meta-data

  • LabelAxis: a name, dict of label index to name and colour, and optionally a dict of meta-data

  • SeriesAxis: the time-point of each row/column is set by setting the start, stop, size, and unit of the time-series

Several helper functions exist to create new BrainModelAxis axes:

  • BrainModelAxis.from_mask() creates a new BrainModelAxis volume covering the non-zero values of a mask

  • BrainModelAxis.from_surface() creates a new BrainModelAxis surface covering the provided indices of a surface

A ParcelsAxis axis can be created from a sequence of BrainModelAxis axes using ParcelsAxis.from_brain_models().

Examples

We can create brain models covering the left cortex and left thalamus using:

>>> from nibabel import cifti2
>>> import numpy as np
>>> bm_cortex = cifti2.BrainModelAxis.from_mask([True, False, True, True],
...                                             name='cortex_left')
>>> bm_thal = cifti2.BrainModelAxis.from_mask(np.ones((2, 2, 2)), affine=np.eye(4),
...                                           name='thalamus_left')

In this very simple case bm_cortex describes a left cortical surface skipping the second out of four vertices. bm_thal contains all voxels in a 2x2x2 volume.

Brain structure names automatically get converted to valid CIFTI-2 indentifiers using BrainModelAxis.to_cifti_brain_structure_name(). A 1-dimensional mask will be automatically interpreted as a surface element and a 3-dimensional mask as a volume element.

These can be concatenated in a single brain model covering the left cortex and thalamus by simply adding them together

>>> bm_full = bm_cortex + bm_thal

Brain models covering the full HCP grayordinate space can be constructed by adding all the volumetric and surface brain models together like this (or by reading one from an already existing HCP file).

Getting a specific brain region from the full brain model is as simple as:

>>> assert bm_full[bm_full.name == 'CIFTI_STRUCTURE_CORTEX_LEFT'] == bm_cortex
>>> assert bm_full[bm_full.name == 'CIFTI_STRUCTURE_THALAMUS_LEFT'] == bm_thal

You can also iterate over all brain structures in a brain model:

>>> for idx, (name, slc, bm) in enumerate(bm_full.iter_structures()):
...     print((str(name), slc))
...     assert bm == bm_full[slc]
...     assert bm == bm_cortex if idx == 0 else bm_thal
('CIFTI_STRUCTURE_CORTEX_LEFT', slice(0, 3, None))
('CIFTI_STRUCTURE_THALAMUS_LEFT', slice(3, None, None))

In this case there will be two iterations, namely: (‘CIFTI_STRUCTURE_CORTEX_LEFT’, slice(0, <size of cortex mask>), bm_cortex) and (‘CIFTI_STRUCTURE_THALAMUS_LEFT’, slice(<size of cortex mask>, None), bm_thal)

ParcelsAxis can be constructed from selections of these brain models:

>>> parcel = cifti2.ParcelsAxis.from_brain_models([
...        ('surface_parcel', bm_cortex[:2]),  # contains first 2 cortical vertices
...        ('volume_parcel', bm_thal),  # contains thalamus
...        ('combined_parcel', bm_full[[1, 8, 10]]),  # contains selected voxels/vertices
...    ])

Time series are represented by their starting time (typically 0), step size (i.e. sampling time or TR), and number of elements:

>>> series = cifti2.SeriesAxis(start=0, step=100, size=5000)

So a header for fMRI data with a TR of 100 ms covering the left cortex and thalamus with 5000 timepoints could be created with

>>> type(cifti2.Cifti2Header.from_axes((series, bm_cortex + bm_thal)))
<class 'nibabel.cifti2.cifti2.Cifti2Header'>

Similarly the curvature and cortical thickness on the left cortex could be stored using a header like:

>>> type(cifti2.Cifti2Header.from_axes((cifti2.ScalarAxis(['curvature', 'thickness']),
...                                     bm_cortex)))
<class 'nibabel.cifti2.cifti2.Cifti2Header'>

Functions

from_index_mapping(mim)

Parses the MatrixIndicesMap to find the appropriate CIFTI-2 axis describing the rows or columns

to_header(axes)

Converts the axes describing the rows/columns of a CIFTI-2 vector/matrix to a Cifti2Header

Classes

Axis()

Abstract class for any object describing the rows or columns of a CIFTI-2 vector/matrix

BrainModelAxis(name[, voxel, vertex, ...])

Each row/column in the CIFTI-2 vector/matrix represents a single vertex or voxel

LabelAxis(name, label[, meta])

Defines CIFTI-2 axis for label array.

ParcelsAxis(name, voxels, vertices[, ...])

Each row/column in the CIFTI-2 vector/matrix represents a parcel of voxels/vertices

ScalarAxis(name[, meta])

Along this axis of the CIFTI-2 vector/matrix each row/column has been given a unique name and optionally metadata

SeriesAxis(start, step, size[, unit])

Along this axis of the CIFTI-2 vector/matrix the rows/columns increase monotonously in time