Basic read and slice with Xibabel¶
In [1]:
Copied!
from pathlib import Path
import xibabel as xib
import matplotlib.pyplot as plt
plt.rc('image', cmap='gray')
from pathlib import Path
import xibabel as xib
import matplotlib.pyplot as plt
plt.rc('image', cmap='gray')
We can load images directly from web URLs:
In [2]:
Copied!
ximg = xib.load('https://s3.amazonaws.com/openneuro.org/ds000105/sub-1/func/sub-1_task-objectviewing_run-01_bold.nii.gz')
ximg
ximg = xib.load('https://s3.amazonaws.com/openneuro.org/ds000105/sub-1/func/sub-1_task-objectviewing_run-01_bold.nii.gz')
ximg
Out[2]:
<xarray.DataArray 'sub-1_task-objectviewing_run-01_bold' (i: 40, j: 64, k: 64, time: 121)> Size: 159MB dask.array<array, shape=(40, 64, 64, 121), dtype=float64, chunksize=(40, 64, 64, 121), chunktype=numpy.ndarray> Coordinates: * i (i) int64 320B 0 1 2 3 4 5 6 7 8 9 ... 31 32 33 34 35 36 37 38 39 * j (j) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63 * k (k) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63 * time (time) float64 968B 0.0 2.5 5.0 7.5 ... 292.5 295.0 297.5 300.0 Attributes: RepetitionTime: 2.5 xib-affines: {'scanner': [[-3.5, 0.0, 0.0, 68.25], [0.0, 3.75, 0.0, -...
Notice that loading automatically picks up BIDS data in corresponding JSON files:
In [3]:
Copied!
ximg.attrs
ximg.attrs
Out[3]:
{'RepetitionTime': 2.5, 'xib-affines': {'scanner': [[-3.5, 0.0, 0.0, 68.25], [0.0, 3.75, 0.0, -118.125], [0.0, 0.0, 3.75, -118.125], [0.0, 0.0, 0.0, 1.0]]}}
Slicing can now use axis labels:
In [4]:
Copied!
mean_img = ximg.mean('time')
mean_img
mean_img = ximg.mean('time')
mean_img
Out[4]:
<xarray.DataArray 'sub-1_task-objectviewing_run-01_bold' (i: 40, j: 64, k: 64)> Size: 1MB dask.array<mean_agg-aggregate, shape=(40, 64, 64), dtype=float64, chunksize=(40, 64, 64), chunktype=numpy.ndarray> Coordinates: * i (i) int64 320B 0 1 2 3 4 5 6 7 8 9 ... 31 32 33 34 35 36 37 38 39 * j (j) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63 * k (k) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63
Notice that we haven't yet fetched the data. We do so only when we need it - for example, when plotting the image data:
In [5]:
Copied!
plt.imshow(mean_img.sel(k=32))
plt.imshow(mean_img.sel(k=32))
Out[5]:
<matplotlib.image.AxesImage at 0x13d50e4c0>
We may also want to get a local in-memory copy of the image so we don't have to do repeated reads from the source:
In [6]:
Copied!
ximg_loaded = ximg.compute()
ximg_loaded
ximg_loaded = ximg.compute()
ximg_loaded
Out[6]:
<xarray.DataArray 'sub-1_task-objectviewing_run-01_bold' (i: 40, j: 64, k: 64, time: 121)> Size: 159MB array([[[[ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], ..., [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.]], [[ 9., 0., 0., ..., 14., 11., 17.], [14., 0., 0., ..., 17., 8., 15.], [27., 0., 0., ..., 10., 13., 10.], ..., [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.]], [[ 7., 0., 0., ..., 11., 9., 11.], [14., 0., 0., ..., 9., 10., 17.], [29., 0., 0., ..., 13., 9., 13.], ..., ... ..., [17., 15., 15., ..., 16., 11., 11.], [11., 15., 12., ..., 11., 13., 13.], [ 8., 10., 6., ..., 7., 9., 7.]], [[ 0., 0., 0., ..., 0., 0., 0.], [13., 5., 14., ..., 11., 11., 9.], [15., 8., 9., ..., 12., 17., 17.], ..., [16., 17., 18., ..., 15., 11., 16.], [14., 13., 17., ..., 18., 9., 10.], [10., 8., 8., ..., 9., 9., 5.]], [[ 0., 0., 0., ..., 0., 0., 0.], [14., 7., 15., ..., 21., 15., 13.], [19., 12., 11., ..., 17., 21., 21.], ..., [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.]]]]) Coordinates: * i (i) int64 320B 0 1 2 3 4 5 6 7 8 9 ... 31 32 33 34 35 36 37 38 39 * j (j) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63 * k (k) int64 512B 0 1 2 3 4 5 6 7 8 9 ... 55 56 57 58 59 60 61 62 63 * time (time) float64 968B 0.0 2.5 5.0 7.5 ... 292.5 295.0 297.5 300.0 Attributes: RepetitionTime: 2.5 xib-affines: {'scanner': [[-3.5, 0.0, 0.0, 68.25], [0.0, 3.75, 0.0, -...
We can save the original image as Zarr format, written with the .ximg
extension:
In [7]:
Copied!
xib.save(ximg_loaded, 'out.ximg')
xib.save(ximg_loaded, 'out.ximg')
Out[7]:
<xarray.backends.zarr.ZarrStore at 0x13fc566c0>
and load it back again:
In [8]:
Copied!
back = xib.load('out.ximg')
back = xib.load('out.ximg')
We can convert the Xibabel image to NIfTI in-memory thus:
In [9]:
Copied!
nib_img, attrs = xib.to_nifti(ximg_loaded)
nib_img
nib_img, attrs = xib.to_nifti(ximg_loaded)
nib_img
Out[9]:
<nibabel.nifti1.Nifti1Image at 0x13fccc700>
We can also write the image out to BIDS (NIfTI / JSON):
In [10]:
Copied!
xib.save(ximg_loaded, 'out.nii.gz')
xib.save(ximg_loaded, 'out.nii.gz')
List files in this directory:
In [11]:
Copied!
sorted(str(p) for p in Path().glob('out*'))
sorted(str(p) for p in Path().glob('out*'))
Out[11]:
['out.json', 'out.nii.gz', 'out.ximg']