SOCR ≫ TCIU Website ≫ TCIU GitHub ≫

1 fMRI Space-kime Example

1.1 Figure 5.3

In this example, we demonstrate spacekime data analytics using real 4D fMRI data (\(x=64 \times y=64\times z=21\times t=180\)). For simplicity of the presentation, analysis, and visualization, we will focus on a 2D time-series of the entire 4D fMRI hypervolume. In other words, we’ll (artificially) reduce the native 3D space (\({\bf{x}}=(x,y,z)\in R^3\)) to 2D (\({\bf{x}}=(x,y)\in R^2\subseteq R^3\)) by focusing only on mid-axial/transverse slice through the brain (\(z=11\)). More details are provided in DSPA Chapter 3.

## NIfTI-1 format
##   Type            : nifti
##   Data Type       : 4 (INT16)
##   Bits per Pixel  : 16
##   Slice Code      : 0 (Unknown)
##   Intent Code     : 0 (None)
##   Qform Code      : 1 (Scanner_Anat)
##   Sform Code      : 0 (Unknown)
##   Dimension       : 64 x 64 x 21 x 180
##   Pixel Dimension : 4 x 4 x 6 x 3
##   Voxel Units     : mm
##   Time Units      : sec
## [1]  64  64  21 180
## [1]  64  64 180

Suppose the 2D fMRI time-series is represented analytically by \(f({\bf{x}},t)=f(x,y,t):R^2\times R^+ \longrightarrow R\) and computationally as a 3D array. Then each of these are also 3D (complex-valued) arrays: \(\hat{f}\), magnitude of the FT (\(|\hat{f}|=\sqrt{Re(\hat{f})^2+Im(\hat{f})^2}\)), and the phase-angles, \(\theta = \arctan \left (\frac{Im(\hat{f})}{Re(\hat{f})}\right )\).

We will focus on the function \(\hat{f}=(f_1, f_2, f_3)\) where the 3-rd dimension correponds to time. Specifically, we will consider the magnitude of its 3-rd dimension as \(time=|f_3|\) and we will pretend its phase is unknown, i.e., \(\theta_3 =0\). Thus, inverting the FT of the modified function \(\tilde{\hat{f}}\), where \(\theta_3 =0\), we get an estimate of kime for the original 2D fMRI time-series as \(\hat{\tilde{\hat{f}}}\).

As an observable, the time is measurable and the phase angles can either be estimated from other similar data, provided by an oracle, or fixed according to some experimental conditions. For simplicity, we’ll consider two specific instance:

  • When the time-dimension phases are indeed the actual FT phases, which are in general unknown, however, in our fMRI simulation example, they are actually computed from the original space-time fMRI time-series via the Fourier transformation, and
  • When the time-dimension phases are provided by the investigator, e.g., trivial (nil) phases or phases derived from other similar datasets.
## [1]  64  64 180

1.2 Figure 3.11B

## 
## Attaching package: 'abind'
## The following object is masked from 'package:EBImage':
## 
##     abind

2 Appendix: Functions Used

2.1 fftshift()

# FFT SHIFT
#' This function is useful for visualizing the Fourier transform with the zero-frequency 
#' component in the middle of the spectrum.
#' 
#' @param img_ff A Fourier transform of a 1D signal, 2D image, or 3D volume.
#' @param dim Number of dimensions (-1, 1, 2, 3).
#' @return A properly shifted FT of the array.
#' 
fftshift <- function(img_ff, dim = -1) {

  rows <- dim(img_ff)[1]    
  cols <- dim(img_ff)[2]
  # planes <- dim(img_ff)[3]

  swap_up_down <- function(img_ff) {
    rows_half <- ceiling(rows/2)
    return(rbind(img_ff[((rows_half+1):rows), (1:cols)], img_ff[(1:rows_half), (1:cols)]))
  }

  swap_left_right <- function(img_ff) {
    cols_half <- ceiling(cols/2)
    return(cbind(img_ff[1:rows, ((cols_half+1):cols)], img_ff[1:rows, 1:cols_half]))
  }
  
  #swap_side2side <- function(img_ff) {
  #  planes_half <- ceiling(planes/2)
  #  return(cbind(img_ff[1:rows, 1:cols, ((planes_half+1):planes)], img_ff[1:rows, 1:cols, 1:planes_half]))
  #}

  if (dim == -1) {
    img_ff <- swap_up_down(img_ff)
    return(swap_left_right(img_ff))
  }
  else if (dim == 1) {
    return(swap_up_down(img_ff))
  }
  else if (dim == 2) {
    return(swap_left_right(img_ff))
  }
  else if (dim == 3) {
    # Use the `abind` package to bind along any dimension a pair of multi-dimensional arrays
    # install.packages("abind")
    library(abind)
    
    planes <- dim(img_ff)[3]
    rows_half <- ceiling(rows/2)
    cols_half <- ceiling(cols/2)
    planes_half <- ceiling(planes/2)
    
    img_ff <- abind(img_ff[((rows_half+1):rows), (1:cols), (1:planes)], 
                    img_ff[(1:rows_half), (1:cols), (1:planes)], along=1)
    img_ff <- abind(img_ff[1:rows, ((cols_half+1):cols), (1:planes)], 
                    img_ff[1:rows, 1:cols_half, (1:planes)], along=2)
    img_ff <- abind(img_ff[1:rows, 1:cols, ((planes_half+1):planes)], 
                    img_ff[1:rows, 1:cols, 1:planes_half], along=3)
    return(img_ff)
  }
  else {
    stop("Invalid dimension parameter")
  }
}

2.2 ifftshift()

# IFFT SHIFT
#' This function is useful for moving back the zero-frequency component in the middle of the spectrum
#' back to (0,0,0).  It rearranges in reverse (relative to fftshift()) the indices appropriately,
#' so that the image can be correctly reconstructed by the IFT in spacetime
#' 
#' @param img_ff An Inverse Fourier transform of a 1D signal, 2D image, or 3D volume.
#' @param dim Number of dimensions (-1, 1, 2, 3).
#' @return A properly shifted IFT of the input array.
#' 
ifftshift <- function(img_ff, dim = -1) {

  rows <- dim(img_ff)[1]    
  cols <- dim(img_ff)[2]    

  swap_up_down <- function(img_ff) {
    rows_half <- floor(rows/2)
    return(rbind(img_ff[((rows_half+1):rows), (1:cols)], img_ff[(1:rows_half), (1:cols)]))
  }

  swap_left_right <- function(img_ff) {
    cols_half <- floor(cols/2)
    return(cbind(img_ff[1:rows, ((cols_half+1):cols)], img_ff[1:rows, 1:cols_half]))
  }

  if (dim == -1) {
    img_ff <- swap_left_right(img_ff)
    return(swap_up_down(img_ff))
  }
  else if (dim == 1) {
    return(swap_up_down(img_ff))
  }
  else if (dim == 2) {
    return(swap_left_right(img_ff))
  }
  else if (dim == 3) {
    # Use the `abind` package to bind along any dimension a pair of multi-dimensional arrays
    # install.packages("abind")
    library(abind)
    
    planes <- dim(img_ff)[3]
    rows_half <- floor(rows/2)
    cols_half <- floor(cols/2)
    planes_half <- floor(planes/2)
    
    img_ff <- abind(img_ff[1:rows, 1:cols, ((planes_half+1):planes)], 
                    img_ff[1:rows, 1:cols, 1:planes_half], along=3)
    img_ff <- abind(img_ff[1:rows, ((cols_half+1):cols), (1:planes)], 
                    img_ff[1:rows, 1:cols_half, (1:planes)], along=2)
    img_ff <- abind(img_ff[((rows_half+1):rows), (1:cols), (1:planes)], 
                    img_ff[(1:rows_half), (1:cols), (1:planes)], along=1)
    return(img_ff)
  }
  else {
    stop("Invalid dimension parameter")
  }
}
SOCR Resource Visitor number SOCR Email