The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Read imaging data

ieegio supports reading from and writing to multiple imaging formats:

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")

Volume files

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.

volume <- read_volume(nifti_file)
volume

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,

volume[128, , ]

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))
}

Surface files

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:

merged <- merge(geometry, measurement, time_series)
print(merged)

Plot the surfaces in 3D viewer, colored by shape measurement

# plot the first column in measurements section
plot(merged, name = list("measurements", 1))

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"
  )
)

Streamline files

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

message("Total number of streamlines: ", length(trk))

head(trk[[1]]$coords)

To preview the streamline data

pal <- colorRampPalette(c("navy", "grey", "red"))
plot(trk, col = pal(length(trk)))

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)

Surface annotations from AFNI/SUMA

NIML 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.

std141_geometry <- read_surface(std141_geom_file)

annotation <- read_surface(niml_file)
annotation

The sample geometry and annotation live on the same std.141 mesh, so they merge directly:

labeled <- merge(std141_geometry, annotation)
labeled
plot(labeled, name = "annotations")

If you need the raw NIML element tree rather than a surface object, use the low-level io_read_niml together with niml_find.

Regions of interest

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)
roi
# compute: turn that description into geometry
resolve_roi_as(roi, "pointcloud")

Because 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:

overlap <- detect_roi_overlap(
  as_ieegio_roi(atlas, threshold_lb = 1),
  trk,
  radius = 2
)
overlap

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

volume_to_surface turns a mask or a set of atlas labels into a smoothed mesh:

volume_to_surface(atlas, threshold_lb = 1, threshold_ub = 5)

Coordinate spaces and transforms

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.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.