The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
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[@]dogado.de.

Four dimensional neuroimaging data

2025-04-09

## Warning: package 'purrr' was built under R version 4.3.3

Working with neuroimaging time-series data

The neuroim2 package contains data structures and functions for reading, accessing, and processing 4-dimensional neuroimaging data.

Reading a four-dimensional NifTI image with read_vec

Here we read in a 4D image consisting of 5 time points,

      library(purrr)
      library(ggplot2)
      file_name <- system.file("extdata", "global_mask_v4.nii", package="neuroim2")
      vec <- read_vec(file_name)
      dim(vec)
#> [1] 64 64 25  4
      vec
#> 
#> DenseNeuroVec (3.13 bytes MB)
#> 
#> - Spatial Info ---------------------------
#> | Dimensions    : 64 x 64 x 25 (4 timepoints)
#> | Total Voxels  : 102,400
#> | Spacing       : 3.5 x 3.5 x 3.7
#> 
#> - Properties ---------------------------
#> | Origin        : 112 x -108 x -46.2
#> | Orientation   : Right-to-Left Posterior-to-Anterior Inferior-to-Superior
#> 
#> - Statistics ---------------------------
#>     Mean +/- SD    : 0.288 +/- 0.453
#> 
#> Label: /private/var/folders/9h/nkjq6vss7mqdl4ck7q1hd8ph0000gp/T/RtmpniBpAs/Rinst125d05ae2f038/neuroim2/extdata/global_mask_v4.nii

Now imagine we have a set of 4d images. We can read them in with read_vec. (Here we are just using three versions of the same file for the example).

    
      file_name <- system.file("extdata", "global_mask_v4.nii", package="neuroim2")
      vec <- read_vec(c(file_name, file_name, file_name))
      dim(vec)
#> [1] 64 64 25 12
      
      vec2 <- read_vec(rep(file_name, 10))
      vec2
#> 
#> NeuroVecSeq (10 vectors)
#> 
#> += Sequence Info ---------------------------
#> | Length        : 10
#> | Total Time    : 40 points
#> 
#> += Spatial Info ---------------------------
#> | Dimensions    : 64 x 64 x 25
#> | Spacing       : 3.5 x 3.5 x 3.7
#> | Origin        : 112 x -108 x -46.2
#> | Orientation   : Right-to-Left Posterior-to-Anterior Inferior-to-Superior
#> 
#> += Vector Details --------------------------
#>   1. DenseNeuroVec (4 timepoints)
#>   2. DenseNeuroVec (4 timepoints)
#>   3. DenseNeuroVec (4 timepoints)
#>   4. DenseNeuroVec (4 timepoints)
#>   5. DenseNeuroVec (4 timepoints)
#>   6. DenseNeuroVec (4 timepoints)
#>   7. DenseNeuroVec (4 timepoints)
#>   8. DenseNeuroVec (4 timepoints)
#>   9. DenseNeuroVec (4 timepoints)
#>   10. DenseNeuroVec (4 timepoints)

To extract a subset of volumes we can use the sub_vector function:

    
      vec_1_6 <- sub_vector(vec, 1:6)
      dim(vec_1_6)
#> [1] 64 64 25  6
      vec_1_6
#> 
#> NeuroVecSeq (2 vectors)
#> 
#> += Sequence Info ---------------------------
#> | Length        : 2
#> | Total Time    : 6 points
#> 
#> += Spatial Info ---------------------------
#> | Dimensions    : 64 x 64 x 25
#> | Spacing       : 3.5 x 3.5 x 3.7
#> | Origin        : 112 x -108 x -46.2
#> | Orientation   : Right-to-Left Posterior-to-Anterior Inferior-to-Superior
#> 
#> += Vector Details --------------------------
#>   1. DenseNeuroVec (4 timepoints)
#>   2. DenseNeuroVec (2 timepoints)

Extracting time-series data using the series and series_roi functions

To get the time-series at voxel (1,1,1) we can use the series function:

      
      series(vec_1_6, 1,1,1)
#> [1] 0 0 0 0 0 0

We can extract a 4d region of interest with the series_roi as follows:

      file_name <- system.file("extdata", "global_mask_v4.nii", package="neuroim2")
      vol <- read_vol(file_name)
      roi <- spherical_roi(vol, c(12,12,12), radius=8)
      rvec1 <- series_roi(vec, roi)
      
      ## or alternatively as a pipeline
      rvec2 <- read_vol(file_name) %>% spherical_roi(c(12,12,12), radius=8) %>% series_roi(vec,.)
      rvec2
#> 
#>  === ROIVec Object === 
#> 
#> - Structure 
#>   Points:     49
#>   Features:   3 (147 total)
#>   Memory:     12.7 Kb
#> 
#> - Spatial Properties
#>   Parent Space: 64 x 64 x 25 x 12
#>   Centroid:     [13.0, 13.0, 13.0 mm]
#> 
#> - Value Properties
#>   Range:    [0.00, 0.00]
#> 
#> ======================================
#> 
#>  Access Methods: 
#>   .  Get Points:   coords(object) 
#>   .  Get Values:   as.matrix(object) 
#>   .  Subset:       object[1:10, ]
      
      ## we can extract the ROI values with the `values` method.
      assertthat::assert_that(all(values(rvec1) == values(rvec2)))
#> [1] TRUE
      assertthat::assert_that(all(coords(rvec1) == coords(rvec2)))
#> [1] TRUE

We can also extract an ROI using 1d indices:


r1 <- series_roi(vec, 1:100)
r1
#> 
#>  === ROIVec Object === 
#> 
#> - Structure 
#>   Points:     100
#>   Features:   3 (300 total)
#>   Memory:     17.5 Kb
#> 
#> - Spatial Properties
#>   Parent Space: 64 x 64 x 25 x 12
#>   Centroid:     [27.5, 1.4, 1.0 mm]
#> 
#> - Value Properties
#>   Range:    [0.00, 0.00]
#> 
#> ======================================
#> 
#>  Access Methods: 
#>   .  Get Points:   coords(object) 
#>   .  Get Values:   as.matrix(object) 
#>   .  Subset:       object[1:10, ]

Or we can extract a plain matrix using the series function:

r2 <- series(vec, 1:100)
dim(r2)
#> [1]  12 100

We can also use coordinate indexing using voxel coordinates. First we load a binary mask with the same spatial dimensions as our NeuroVec:

mask <- read_vol(system.file("extdata", "global_mask_v4.nii", package="neuroim2"))

Now we convert indices to voxels and extract a matrix of values at the specified locations:

vox <- index_to_grid(mask, 1:100)

r3 <- series(vec, vox)
dim(r3)
#> [1]  12 100

And the same using series_roi:

r4 <- series_roi(vec,vox)
r4
#> 
#>  === ROIVec Object === 
#> 
#> - Structure 
#>   Points:     100
#>   Features:   3 (300 total)
#>   Memory:     18.7 Kb
#> 
#> - Spatial Properties
#>   Parent Space: 64 x 64 x 25 x 12
#>   Centroid:     [27.5, 1.4, 1.0 mm]
#> 
#> - Value Properties
#>   Range:    [0.00, 0.00]
#> 
#> ======================================
#> 
#>  Access Methods: 
#>   .  Get Points:   coords(object) 
#>   .  Get Values:   as.matrix(object) 
#>   .  Subset:       object[1:10, ]

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.
Health stats visible at Monitor.