ieegio supports reading from and writing to multiple
imaging formats:
NIfTI &
FreeSurfer MGH/MGZGIfTI & FreeSurfer geometry,
annotation, curvature/measurement, w format,
AFNI/SUMA NIML, VTK
polygon meshesTRK, TCK, TT
(read-only), VTK, VTP, …Beyond reading and writing, ieegio can also map data
between volumes and surfaces, chain coordinate transforms, and compare
regions of interest; those are covered at the end of this article.
To start, please load ieegio. This vignette uses sample
data which requires extra download.
library(ieegio)
# volume file
nifti_file <- ieegio_sample_data("brain.demosubject.nii.gz")
# geometry
geom_file <- ieegio_sample_data(
"gifti/icosahedron3d/geometry.gii")
# measurements
shape_file <- ieegio_sample_data(
"gifti/icosahedron3d/rand.gii"
)
# time series
ts_file <- ieegio_sample_data(
"gifti/icosahedron3d/ts.gii")
# streamlines
trk_file <- ieegio_sample_data(
"streamlines/CNVII_R.trk")
tck_file <- ieegio_sample_data(
"streamlines/CNVII_R.tck")
tt_file <- ieegio_sample_data(
"streamlines/CNVII_R.tt")
# AFNI/SUMA std.141 geometry and matching annotation
std141_geom_file <- ieegio_sample_data(
"gifti/std.141.lh.inf_200.gii")
niml_file <- ieegio_sample_data(
"niml/std.141.lh.aparc.a2009s.annot.niml.dset")
# volumetric atlas
atlas_file <- ieegio_sample_data(
"atlases/YBA/YBA690.nii.gz")ieegio::read_volume and
ieegio::write_volume provides high-level interfaces for
reading and writing volume data such as MRI,
CT. fMRI, etc.
Each volume data (NIfTI, MGH, …) contains a
header, a data, and a transforms
list.
The transforms contain transforms from volume (column, row, slice)
index to other coordinate systems. The most commonly used one is
vox2ras, which is a 4x4 matrix mapping the
voxels to scanner (usually T1-weighted) RAS
(right-anterior-superior) system.
Accessing the image values via [ operator. For
example,
Plotting the anatomical slices:
par(mfrow = c(1, 3), mar = c(0, 0, 3.1, 0))
ras_position <- c(-50, -10, 15)
ras_str <- paste(sprintf("%.0f", ras_position), collapse = ",")
for (which in c("coronal", "axial", "sagittal")) {
plot(x = volume, position = ras_position, crosshair_gap = 10,
crosshair_lty = 2, zoom = 3, which = which,
main = sprintf("%s T1RAS=[%s]", which, ras_str))
}Reading surface file using read_surface supports
multiple data types
library(ieegio)
# geometry
geometry <- read_surface(geom_file)
# measurements
measurement <- read_surface(shape_file)
# time series
time_series <- read_surface(ts_file)You can merge them to a single object, making an object with multiple embedding data-sets:
Plot the surfaces in 3D viewer, colored by shape
measurement
Plot the normalized time-series data
ts_demean <- apply(
merged$time_series$value,
MARGIN = 1L,
FUN = function(x) {
x - mean(x)
}
)
merged$time_series$value <- t(ts_demean)
plot(
merged, name = "time_series",
col = c(
"#053061", "#2166ac", "#4393c3",
"#92c5de", "#d1e5f0", "#ffffff",
"#fddbc7", "#f4a582", "#d6604d",
"#b2182b", "#67001f"
)
)Reading streamlines via universal entry function
read_streamlines
trk <- read_streamlines(trk_file, half_voxel_offset = TRUE)
tck <- read_streamlines(tck_file)
tt <- read_streamlines(tt_file)To obtain the streamline data
To preview the streamline data
To write the streamlines, for example, write tck file to
trk file:
# Create a temporary file
tfile <- tempfile(fileext = ".trk")
write_streamlines(x = tck, con = tfile)AFNI/SUMANIML datasets (file names ending with
.niml.dset) are read by the same read_surface
entry point. The data type is resolved from the dataset itself: datasets
carrying a label table are read as annotations, the rest as
measurements.
The sample geometry and annotation live on the same
std.141 mesh, so they merge directly:
If you need the raw NIML element tree rather than a
surface object, use the low-level io_read_niml together
with niml_find.
A region of interest is described first and computed later.
as_ieegio_roi records the criteria without applying them,
and resolve_roi_as carries them out, returning geometry in
world (RAS) coordinates.
atlas <- read_volume(atlas_file)
# describe: which voxels count as the region
roi <- as_ieegio_roi(atlas, threshold_lb = 1, threshold_ub = 5)
roiBecause both sides are resolved to world coordinates first, regions stored in different ways can be compared directly. Here the whole atlas is tested against the facial-nerve tracts read earlier:
The result carries the annotated streamlines back in
overlap$annotated, so each tract knows whether it reached
the region, and overlap$hit_ratio reports the proportion
that did.
volume_to_surface turns a mask or a set of atlas labels
into a smoothed mesh:
new_space names a coordinate space, and
surface_to_surface moves a surface into it, recording the
target on the surface transform list.
mni <- new_space("MNI152", orientation = "RAS")
mni
surface_to_surface(
geometry,
space_from = "scanner",
space_to = mni,
transform = diag(1, 4)
)Transforms themselves can come from other tools:
io_read_ants_transform reads ANTs affine and
displacement field transforms, io_read_flirt_transform
reads FSL FLIRT matrices, and
transform_flirt2ras converts a FLIRT transform
into world (RAS) coordinates.