Project

General

Profile

Logged in as brainvisa

Cuboid

Motivation

Developping code in neuro-imaging implies handling n-dimensionnal data (typically 3D images, with sagittal, coronal, axial axes) which also is associated with meta data. Usually, the data representation consists of two detached objects:
  • an array containing the actual measurements
  • a "header" gathering all meta data.

This twofold form is used in most common file format but also for object design. In Python, measurements are typically stored in a numpy.ndarray and meta data in a dictionnary-like structure.

In terms of design, it seems that some information available in meta-data are more closely related to measurements than others, namely: axes information which consists of their names/labels (eg sagittal) and the mapping between slice indexes in the data array and a "real world" value (eg distance for spatial axes, duration for temporal axes).

Features

  • gathers extra info for ndarray: axes labels, axes domains, value label, meta_data (eg Nifti header, affine)
  • array orientation from axes labels
  • array expansion based on axes labels
  • array slicing based on axes labels and domain values
  • stacking
  • nifti I/O (TODO: gifti)

Example script

TODO: split into features ...

source:pyhrf-free/trunk/script/example/cuboid.py

import pyhrf
from pyhrf.ndarray import Cuboid, MRI3Daxes, MRI4Daxes, stack_cuboids

mask_fn = pyhrf.get_data_file_name('audio-video_nalocalizer__roimask.nii.gz')
bold_fn = pyhrf.get_data_file_name('audio-video_nalocalizer__session0.nii.gz')

print 'Nibabel convention for axes orientation (nifti format):'
print MRI4Daxes

## Data load examples:
cmask = Cuboid.load(mask_fn)
print 'mask loaded as Cuboid:'
print cmask.descrip()

affine, nifti_header = cmask.meta_data
print 'affine:'
print affine

cbold = Cuboid.load(bold_fn)
print 'BOLD loaded as Cuboid:'
print cbold.descrip()

cbold_flat = cbold.cflatten(cmask, 'voxel')
cbold_flat.set_orientation(['time', 'voxel'])
print 'Flatten BOLD (reoriented):'
print cbold_flat.descrip()

cbold2 = cbold_flat.cexpand(cmask, 'voxel')
cbold2.set_orientation(MRI4Daxes)
print 'Re-expanded BOLD :'
print cbold2.descrip()

time_axis_id = cbold.get_axis_id('time')
bold_mean = cbold.data.mean(time_axis_id)
bold_var = cbold.data.var(time_axis_id)

# Cuboid init synopsis:
# c = Cuboid(self, narray, axes_names, axes_domains, value_label, meta_data)

cbold_mean = Cuboid(bold_mean, MRI3Daxes, value_label='intensity',
                    meta_data=cbold.meta_data)
print 'Mean of BOLD:'
print cbold_mean.descrip()

cbold_var = Cuboid(bold_var, MRI3Daxes, value_label='intensity',
                    meta_data=cbold.meta_data)
print 'Var of BOLD'
print cbold_var.descrip()

cbold_vm = stack_cuboids([cbold_mean, cbold_var], 'mv_axis', ['mean','var'])
cbold_vm.set_orientation(MRI3Daxes + ['mv_axis'])
print 'Stack of BOLD mean and var in a single Cuboid:'
print cbold_vm.descrip()

Output of this script:

Nibabel convention for axes orientation (nifti format):
['sagittal', 'coronal', 'axial', 'time']
mask loaded as Cuboid:
* shape : (53, 63, 46)
* orientation: ['sagittal', 'coronal', 'axial'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)

affine:
[[ -3.    0.    0.   78. ]
 [  0.    3.    0.  -93. ]
 [  0.    0.    3.  -67.5]
 [  0.    0.    0.    1. ]]
BOLD loaded as Cuboid:
* shape : (53, 63, 46, 125)
* orientation: ['sagittal', 'coronal', 'axial', 'time'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)
  'time': arange(0,124,1)

Flatten BOLD (reoriented):
* shape : (125, 1272)
* orientation: ['time', 'voxel'] 
* value label: intensity
* axes domains: 
  'time': arange(0,124,1)
  'voxel': arange(0,1271,1)

Re-expanded BOLD :
* shape : (53, 63, 46, 125)
* orientation: ['sagittal', 'coronal', 'axial', 'time'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)
  'time': arange(0,124,1)

Mean of BOLD:
* shape : (53, 63, 46)
* orientation: ['sagittal', 'coronal', 'axial'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)

Var of BOLD
* shape : (53, 63, 46)
* orientation: ['sagittal', 'coronal', 'axial'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)

Stack of BOLD mean and var in a single Cuboid:
* shape : (53, 63, 46, 2)
* orientation: ['sagittal', 'coronal', 'axial', 'mv_axis'] 
* value label: intensity
* axes domains: 
  'sagittal': arange(0,52,1)
  'coronal': arange(0,62,1)
  'axial': arange(0,45,1)
  'mv_axis': array(['mean', 'var'], 
      dtype='|S4')

Also available in: PDF HTML TXT