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']