Author: John Muschelli
Date: 2026-01-13

# Working with CIFTI Files

#### John Muschelli

#### 2026-01-13

    library(gifti)
    library(cifti)
    library(rgl)

    Warning: package 'rgl' was built under R version 4.4.1

    library(matrixStats)

    Warning: package 'matrixStats' was built under R version 4.4.1

    left_gii = "Q1-Q6_R440.L.inflated.32k_fs_LR.surf.gii"
    right_gii = "Q1-Q6_R440.R.inflated.32k_fs_LR.surf.gii"
    file = "curvature.32k_fs_LR.dscalar.nii"

    left_gii = system.file("extdata", left_gii, package = "cifti")
    right_gii = system.file("extdata", right_gii, package = "cifti")
    file = system.file("extdata", file, package = "cifti")

    #####################################
    # Getting the Left coordinates/value mapping for cifti
    #####################################
    left = cifti_coords_gifti(
      file,
      gii_file = left_gii,
      structure = "CIFTI_STRUCTURE_CORTEX_LEFT")

    Parsing Volume Data

    Parsing Surface Data

    Parsing Parcel Data

    Parsing Named Map Data

    Parsing Brain Model Data

    Warning in read_cifti(file): Dimensions of the data > 2, so no transposing
    done!

    # gifti surface
    left_surf = surf_triangles(left_gii)

    #####################################
    # Getting the Right coordinates/value mapping for cifti
    #####################################
    right = cifti_coords_gifti(
      file,
      gii_file = right_gii,
      structure = "CIFTI_STRUCTURE_CORTEX_RIGHT")

    Parsing Volume Data

    Parsing Surface Data

    Parsing Parcel Data

    Parsing Named Map Data

    Parsing Brain Model Data

    Warning in read_cifti(file): Dimensions of the data > 2, so no transposing
    done!

    right_surf = surf_triangles(right_gii)

    all_vals = rbind(as.matrix(left$values), as.matrix(right$values))
    vals = all_vals[,1]
    ncol = 99
    breaks = seq(
      min(vals, na.rm = TRUE),
      max(vals, na.rm = TRUE),
      len = ncol + 1)

    ii <- cut(left$values,
              breaks,
              include.lowest = TRUE)
    ## Use bin indices, ii, to select color from vector of
    # n-1 equally spaced colors
    # ramp_cols = brewer.pal(11, "Spectral")
    # ramp_cols = hotmetal()
    # ramp_cols = c("red", "blue")
    # ramp_cols = gray(0:64/64)
    # ramp_cols = c("white", "black")
    ramp_cols = c("black", "white")

    colors <- colorRampPalette(
      ramp_cols
      )(ncol)[ii]

    rgl::triangles3d(left_surf$pointset, color = colors)

    ii <- cut(right$values,
              breaks,
              include.lowest = TRUE)
    ## Use bin indices, ii, to select color from vector of
    # n-1 equally spaced colors
    # colors <- colorRampPalette(
    #   c("red", "blue"))(ncol)[ii]
    rgl::triangles3d(right_surf$pointset, color = colors)

    # rgl.close()

    rgl::open3d()

    glX
      2

    rgl::triangles3d(left_surf$pointset, color = colors)

    left_mid = colMeans(left_surf$pointset)
    left_ranges = colRanges(left_surf$pointset)
    size_left = rowDiffs(left_ranges)
    left_text = left_mid
    left_text[3] = left_ranges[3,2] + size_left[3]/4
    rgl::texts3d(x = left_text, text = "Left")

    right_mid = colMeans(right_surf$pointset)
    right_surf$pointset[,2] = right_surf$pointset[,2] + size_left[2] * 1.25
    right_surf$pointset[,1] = -1 * right_surf$pointset[,1]
    right_surf$pointset[,2] = -1 * right_surf$pointset[,2]

    right_mid = colMeans(right_surf$pointset)
    right_text = right_mid
    right_text[3] =  left_text[3]

    rgl::triangles3d(right_surf$pointset, color = colors)
    rgl::texts3d(x = right_text, text = "Right")
    rgl::view3d(0, -70)
    play3d(spin3d(), duration = 3)