| Title: | Data Structures and Visualization for Surface-Based Neuroimaging Data |
|---|---|
| Description: | A comprehensive toolkit for working with surface-based neuroimaging data represented as triangle meshes. The package provides classes and methods for creating, manipulating, and visualizing 3D surface geometries (e.g., cortical surfaces), with support for various file formats including FreeSurfer and GIFTI. Key features include: surface smoothing, curvature computation, neighborhood graph construction, geodesic distance calculations, searchlight analysis for surface-based machine learning, and interactive 3D visualization via HTMLWidgets. The package facilitates advanced surface-based analyses through specialized data structures for representing surface geometry and associated functional data. |
| Authors: | Bradley R Buchsbaum [aut, cre, cph] |
| Maintainer: | Bradley R Buchsbaum <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.1.0 |
| Built: | 2026-06-03 18:30:44 UTC |
| Source: | https://github.com/bbuchsbaum/neurosurf |
Extracts all data from a NeuroSurfaceVector as a matrix.
## S4 method for signature 'NeuroSurfaceVector,missing,missing,ANY' x[i, j, ..., drop = TRUE]## S4 method for signature 'NeuroSurfaceVector,missing,missing,ANY' x[i, j, ..., drop = TRUE]
x |
the object |
i |
first index |
j |
second index |
... |
additional args |
drop |
dimension |
A numeric matrix containing all data
Extracts columns (time points) from a NeuroSurfaceVector.
## S4 method for signature 'NeuroSurfaceVector,missing,numeric,ANY' x[i, j, ..., drop = TRUE]## S4 method for signature 'NeuroSurfaceVector,missing,numeric,ANY' x[i, j, ..., drop = TRUE]
x |
the object |
i |
first index |
j |
second index |
... |
additional args |
drop |
dimension |
A numeric matrix or vector of extracted column data
Extracts rows (vertices) from a NeuroSurfaceVector.
## S4 method for signature 'NeuroSurfaceVector,numeric,missing,ANY' x[i, j, ..., drop = TRUE]## S4 method for signature 'NeuroSurfaceVector,numeric,missing,ANY' x[i, j, ..., drop = TRUE]
x |
the object |
i |
first index |
j |
second index |
... |
additional args |
drop |
dimension |
A numeric matrix or vector of extracted row data
Extracts a subset of data from a NeuroSurfaceVector.
## S4 method for signature 'NeuroSurfaceVector,numeric,numeric,ANY' x[i, j, ..., drop = TRUE]## S4 method for signature 'NeuroSurfaceVector,numeric,numeric,ANY' x[i, j, ..., drop = TRUE]
x |
the object |
i |
first index (rows/vertices) |
j |
second index (columns/time points) |
... |
additional args |
drop |
whether to drop dimensions |
A numeric matrix or vector of the extracted data subset
Subsets an 'ROISurface' object by selecting specific vertex indices.
## S4 method for signature 'ROISurface,numeric,missing,ANY' x[i, j, drop]## S4 method for signature 'ROISurface,numeric,missing,ANY' x[i, j, drop]
x |
The |
i |
A numeric vector specifying the indices within the ROI to select. |
j |
Missing (not used for this signature). |
drop |
Missing or ANY (ignored, always returns an |
A new ROISurface object containing only the selected vertices
and their associated data from the original ROI.
Extracts data from a NeuroSurfaceVector using bracket notation.
## S4 method for signature 'NeuroSurfaceVector,numeric' x[[i]]## S4 method for signature 'NeuroSurfaceVector,numeric' x[[i]]
x |
the object |
i |
first index |
A numeric vector of data values for the specified column
This helper adds an outline-only layer to an existing "neurosurf_plot"
object using ROI labels. It configures sensible defaults for boundary
aesthetics (including a light halo and a small depth offset) so that atlas
outlines remain legible over filled statistical maps.
add_atlas_outline( x, labels, rois = NULL, label = "atlas", outline_col = "black", outline_lwd = 1.5, outline_offset = 0.5, outline_halo = TRUE, outline_halo_col = "white", outline_halo_lwd = NULL, outline_lty = c("solid", "dashed"), ... )add_atlas_outline( x, labels, rois = NULL, label = "atlas", outline_col = "black", outline_lwd = 1.5, outline_offset = 0.5, outline_halo = TRUE, outline_halo_col = "white", outline_halo_lwd = NULL, outline_lty = c("solid", "dashed"), ... )
x |
A |
labels |
Numeric vector or list of vectors containing ROI labels for each vertex. If a single vector is supplied, it is split across hemispheres based on vertex counts. |
rois |
Optional numeric vector of ROI ids to outline. If |
label |
Optional character label for this outline layer. |
outline_col |
Colour to use for ROI boundaries. Defaults to |
outline_lwd |
Numeric line width for boundaries. Defaults to |
outline_offset |
Numeric depth offset along surface normals to avoid
z-fighting. Defaults to |
outline_halo |
Logical; if |
outline_halo_col |
Colour for the halo. Defaults to |
outline_halo_lwd |
Numeric line width for the halo. If |
outline_lty |
Line type for boundaries: |
... |
Additional arguments passed through to
|
A modified "neurosurf_plot" object.
fs <- load_fsaverage_std8("inflated") p <- surface_plot(fs$lh, fs$rh) # roi_labels <- ... # per-vertex ROI ids # p <- add_atlas_outline(p, roi_labels)fs <- load_fsaverage_std8("inflated") p <- surface_plot(fs$lh, fs$rh) # roi_labels <- ... # per-vertex ROI ids # p <- add_atlas_outline(p, roi_labels)
Add a data layer to a surface plot
add_surface_layer( x, data, cmap = "viridis", alpha = 1, irange = NULL, color_range = NULL, thresh = NULL, vertices = NULL, smoothing = c("auto", "nearest"), smoothing_steps = 20, as_outline = FALSE, zero_transparent = TRUE, show_colorbar = TRUE, label = NULL, outline_col = "black", outline_lwd = 1.5, outline_offset = 0, outline_halo = FALSE, outline_halo_col = NULL, outline_halo_lwd = NULL, outline_rois = NULL, outline_lty = c("solid", "dashed"), hemi = c("both", "left", "right") )add_surface_layer( x, data, cmap = "viridis", alpha = 1, irange = NULL, color_range = NULL, thresh = NULL, vertices = NULL, smoothing = c("auto", "nearest"), smoothing_steps = 20, as_outline = FALSE, zero_transparent = TRUE, show_colorbar = TRUE, label = NULL, outline_col = "black", outline_lwd = 1.5, outline_offset = 0, outline_halo = FALSE, outline_halo_col = NULL, outline_halo_lwd = NULL, outline_rois = NULL, outline_lty = c("solid", "dashed"), hemi = c("both", "left", "right") )
x |
A |
data |
Numeric vector or list specifying vertex-wise data. If a vector,
it should have length equal to the total number of vertices across
hemispheres and is split left-to-right. If a list, it may contain elements
named |
cmap |
Character string naming a colour map. The value is passed
through to |
alpha |
Numeric in |
irange |
Optional numeric vector of length 2 giving the minimum and
maximum data values to map to the colour scale. Alias for
|
color_range |
Optional numeric vector of length 2 giving the minimum
and maximum data values to map to the colour scale. If |
thresh |
Optional numeric threshold band passed to the colour mapper.
A scalar is expanded to |
vertices |
Optional vector or list of vertex ids corresponding to the
supplied |
smoothing |
One of |
smoothing_steps |
Integer number of smoothing iterations applied when
|
as_outline |
Logical; if |
zero_transparent |
Logical; if |
show_colorbar |
Logical; if |
label |
Optional character label identifying the layer (for legends and colour bars). |
outline_col |
Colour to use for ROI boundaries when
|
outline_lwd |
Numeric line width to use when drawing ROI boundaries for outline layers. Ignored for non-outline layers. |
outline_offset |
Numeric scalar giving a small depth offset applied to
boundary coordinates along the surface normals. This helps avoid
z-fighting with the underlying mesh. A value around |
outline_halo |
Logical; if |
outline_halo_col |
Colour used for the halo when
|
outline_halo_lwd |
Numeric line width for the halo. If |
outline_rois |
Optional numeric vector of ROI ids to plot boundaries
for when |
outline_lty |
Line type for boundaries, one of |
hemi |
One of |
A modified "neurosurf_plot" object.
# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # sp <- add_surface_layer(sp, data = rnorm(163842))# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # sp <- add_surface_layer(sp, data = rnorm(163842))
Add a vector field overlay
add_vector_layer( x, vectors, vertices = NULL, scale = NULL, color = "red", alpha = 0.8, lwd = 1.5, hemi = c("both", "left", "right") )add_vector_layer( x, vectors, vertices = NULL, scale = NULL, color = "red", alpha = 0.8, lwd = 1.5, hemi = c("both", "left", "right") )
x |
A |
vectors |
Matrix (n x 3) of XYZ vectors or a list with |
vertices |
Optional vector or list of vertex ids matching the rows of
|
scale |
Optional numeric scalar. If |
color |
Colour for the vectors (single value or vector). |
alpha |
Numeric in |
lwd |
Numeric line width for the glyphs. |
hemi |
One of |
A modified "neurosurf_plot" object.
# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # vectors <- matrix(rnorm(163842 * 3), ncol = 3) # sp <- add_vector_layer(sp, vectors = vectors)# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # vectors <- matrix(rnorm(163842 * 3), ncol = 3) # sp <- add_vector_layer(sp, vectors = vectors)
Get Adjacency Graph
adjacency(x, attr, ...) ## S4 method for signature 'SurfaceGeometry,numeric' adjacency(x, attr) ## S4 method for signature 'SurfaceGeometry,character' adjacency(x, attr) ## S4 method for signature 'SurfaceGeometry,missing' adjacency(x)adjacency(x, attr, ...) ## S4 method for signature 'SurfaceGeometry,numeric' adjacency(x, attr) ## S4 method for signature 'SurfaceGeometry,character' adjacency(x, attr) ## S4 method for signature 'SurfaceGeometry,missing' adjacency(x)
x |
Graph structure |
attr |
Character; edge attribute for weights in igraph object. If absent, weights are 0 or 1. |
... |
Additional arguments |
A sparse adjacency matrix of class dgCMatrix
This class supports the AFNI 1D file format for surface-based data
An object of class AFNISurfaceFileDescriptor.
Apply a precomputed surface sampler to a volume
apply_surface_sampler( sampler, vol, fun = c("avg", "nn", "mode"), sigma = 8, fill = 0 )apply_surface_sampler( sampler, vol, fun = c("avg", "nn", "mode"), sigma = 8, fill = 0 )
sampler |
A sampler object returned by |
vol |
A |
fun |
Aggregation function: "avg", "nn", or "mode". |
sigma |
Bandwidth for Gaussian weights when |
fill |
Value used when no valid voxels fall within |
NeuroSurface with mapped data.
# Requires surface sampler and volume data # sampler <- surface_sampler(geometry, vol) # result <- apply_surface_sampler(sampler, vol)# Requires surface sampler and volume data # sampler <- surface_sampler(geometry, vol) # result <- apply_surface_sampler(sampler, vol)
Arithmetic Operations for NeuroSurface Objects
## S4 method for signature 'NeuroSurface,NeuroSurface' Arith(e1, e2) ## S4 method for signature 'NeuroSurface,numeric' Arith(e1, e2) ## S4 method for signature 'numeric,NeuroSurface' Arith(e1, e2) ## S4 method for signature 'NeuroSurface,NeuroSurfaceVector' Arith(e1, e2)## S4 method for signature 'NeuroSurface,NeuroSurface' Arith(e1, e2) ## S4 method for signature 'NeuroSurface,numeric' Arith(e1, e2) ## S4 method for signature 'numeric,NeuroSurface' Arith(e1, e2) ## S4 method for signature 'NeuroSurface,NeuroSurfaceVector' Arith(e1, e2)
e1 |
the left operand |
e2 |
the right operand |
NeuroSurface object with arithmetic operation results
Arithmetic Operations for NeuroSurfaceVector Objects
## S4 method for signature 'NeuroSurfaceVector,NeuroSurfaceVector' Arith(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,numeric' Arith(e1, e2) ## S4 method for signature 'numeric,NeuroSurfaceVector' Arith(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,NeuroSurface' Arith(e1, e2)## S4 method for signature 'NeuroSurfaceVector,NeuroSurfaceVector' Arith(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,numeric' Arith(e1, e2) ## S4 method for signature 'numeric,NeuroSurfaceVector' Arith(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,NeuroSurface' Arith(e1, e2)
e1 |
NeuroSurfaceVector object or numeric value |
e2 |
NeuroSurfaceVector object or numeric value |
NeuroSurfaceVector object with arithmetic operation results
Methods to convert NeuroSurface objects to other types.
The converted object (e.g., a numeric vector when converting to "vector").
Converts surface data to a matrix representation.
## S4 method for signature 'ROISurfaceVector' as.matrix(x) ## S4 method for signature 'NeuroSurfaceVector' as.matrix(x) ## S4 method for signature 'BilatNeuroSurfaceVector' as.matrix(x)## S4 method for signature 'ROISurfaceVector' as.matrix(x) ## S4 method for signature 'NeuroSurfaceVector' as.matrix(x) ## S4 method for signature 'BilatNeuroSurfaceVector' as.matrix(x)
x |
the object to convert to a matrix |
A numeric matrix with vertices as rows and time points/features as columns
Converts surface data to a numeric vector.
## S4 method for signature 'NeuroSurface' as.vector(x)## S4 method for signature 'NeuroSurface' as.vector(x)
x |
the object to convert to a vector |
A numeric vector of surface data values
Represents surface data for both left and right hemispheres.
The BilatNeuroSurfaceVector class provides a convenient container for organizing and analyzing data from both hemispheres of the brain simultaneously. It holds two NeuroSurfaceVector objects, one for each hemisphere, allowing researchers to:
Analyze bilateral symmetric or asymmetric patterns in brain data
Compare corresponding regions across hemispheres
Represent whole-brain surface data with proper hemisphere separation
Apply operations to both hemispheres while maintaining their distinct identities
This class is particularly useful for studies examining interhemispheric differences, bilateral effects, or any analysis that requires maintaining separate representations of the two hemispheres while treating them as parts of a unified whole.
An object of class BilatNeuroSurfaceVector.
leftNeuroSurfaceVector instance for the left hemisphere
rightNeuroSurfaceVector instance for the right hemisphere
# Create two simple tetrahedron meshes (one for each hemisphere) # Left hemisphere lh_vertices <- c( 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 1 ) # Right hemisphere rh_vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d objects lh_mesh <- rgl::mesh3d(vertices = lh_vertices, triangles = triangles) rh_mesh <- rgl::mesh3d(vertices = rh_vertices, triangles = triangles) # Create graph representations edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) lh_graph <- igraph::graph_from_edgelist(edges) rh_graph <- igraph::graph_from_edgelist(edges) # Create SurfaceGeometry objects lh_geometry <- new("SurfaceGeometry", mesh = lh_mesh, graph = lh_graph, hemi = "left") rh_geometry <- new("SurfaceGeometry", mesh = rh_mesh, graph = rh_graph, hemi = "right") # Define indices for all vertices indices <- 1:4 # Create Matrix data for each hemisphere # Each has 4 vertices and 2 measures require(Matrix) lh_data <- Matrix( c(0.5, 1.2, 0.8, 0.6, # Measure 1 values 0.7, 0.3, 1.5, 0.9), # Measure 2 values nrow = 4, ncol = 2, byrow = FALSE ) rh_data <- Matrix( c(0.4, 1.1, 0.7, 0.5, # Measure 1 values (slightly different from left) 0.8, 0.4, 1.6, 1.0), # Measure 2 values (slightly different from left) nrow = 4, ncol = 2, byrow = FALSE ) # Create NeuroSurfaceVector objects for each hemisphere lh_nsv <- new("NeuroSurfaceVector", geometry = lh_geometry, indices = indices, data = lh_data) rh_nsv <- new("NeuroSurfaceVector", geometry = rh_geometry, indices = indices, data = rh_data) # Create the BilatNeuroSurfaceVector object bilat_nsv <- new("BilatNeuroSurfaceVector", left = lh_nsv, right = rh_nsv) # Now you can access each hemisphere separately: # bilat_nsv@left@data # Left hemisphere data # bilat_nsv@right@data # Right hemisphere data# Create two simple tetrahedron meshes (one for each hemisphere) # Left hemisphere lh_vertices <- c( 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 1 ) # Right hemisphere rh_vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d objects lh_mesh <- rgl::mesh3d(vertices = lh_vertices, triangles = triangles) rh_mesh <- rgl::mesh3d(vertices = rh_vertices, triangles = triangles) # Create graph representations edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) lh_graph <- igraph::graph_from_edgelist(edges) rh_graph <- igraph::graph_from_edgelist(edges) # Create SurfaceGeometry objects lh_geometry <- new("SurfaceGeometry", mesh = lh_mesh, graph = lh_graph, hemi = "left") rh_geometry <- new("SurfaceGeometry", mesh = rh_mesh, graph = rh_graph, hemi = "right") # Define indices for all vertices indices <- 1:4 # Create Matrix data for each hemisphere # Each has 4 vertices and 2 measures require(Matrix) lh_data <- Matrix( c(0.5, 1.2, 0.8, 0.6, # Measure 1 values 0.7, 0.3, 1.5, 0.9), # Measure 2 values nrow = 4, ncol = 2, byrow = FALSE ) rh_data <- Matrix( c(0.4, 1.1, 0.7, 0.5, # Measure 1 values (slightly different from left) 0.8, 0.4, 1.6, 1.0), # Measure 2 values (slightly different from left) nrow = 4, ncol = 2, byrow = FALSE ) # Create NeuroSurfaceVector objects for each hemisphere lh_nsv <- new("NeuroSurfaceVector", geometry = lh_geometry, indices = indices, data = lh_data) rh_nsv <- new("NeuroSurfaceVector", geometry = rh_geometry, indices = indices, data = rh_data) # Create the BilatNeuroSurfaceVector object bilat_nsv <- new("BilatNeuroSurfaceVector", left = lh_nsv, right = rh_nsv) # Now you can access each hemisphere separately: # bilat_nsv@left@data # Left hemisphere data # bilat_nsv@right@data # Right hemisphere data
Clear geodesic cache
clear_geodesic_cache()clear_geodesic_cache()
TRUE (invisibly)
clear_geodesic_cache()clear_geodesic_cache()
Apply Cluster-Extent Threshold to Surface Data
cluster_threshold(x, threshold, size, ...) ## S4 method for signature 'NeuroSurfaceVector' cluster_threshold(x, threshold, size = 10, index = 1) ## S4 method for signature 'NeuroSurface' cluster_threshold(x, threshold, size = 10)cluster_threshold(x, threshold, size, ...) ## S4 method for signature 'NeuroSurfaceVector' cluster_threshold(x, threshold, size = 10, index = 1) ## S4 method for signature 'NeuroSurface' cluster_threshold(x, threshold, size = 10)
x |
Object to threshold |
threshold |
the two-element threshold range to use to define connected components |
size |
the minimum size of the connected components to keep |
... |
Additional arguments |
index |
the index/column of the underlying data matrix to cluster |
A thresholded surface object of the same class as x
This function creates a ColorMappedNeuroSurface object, which represents a single set of data values associated with nodes on a surface geometry, with pre-defined color mapping parameters.
ColorMappedNeuroSurface(geometry, indices, data, cmap, irange, thresh)ColorMappedNeuroSurface(geometry, indices, data, cmap, irange, thresh)
geometry |
A |
indices |
An integer vector specifying the indices of valid surface nodes. |
data |
A numeric vector of data values corresponding to the surface nodes. |
cmap |
A character string specifying the colormap to use for mapping the data values. |
irange |
A numeric vector of length 2 specifying the range of values to map. |
thresh |
A numeric value specifying the threshold for the colormap. |
This object bundles the surface geometry, data, and specific color mapping parameters ('cmap', 'irange', 'thresh'). This is useful for ensuring consistent visualization across different plots or for saving a predefined view. The actual application of the color map happens during rendering (e.g., when using 'plot()”).
An instance of class ColorMappedNeuroSurface.
# Load a sample surface geometry surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Get vertex count and generate some random data n_verts <- nrow(coords(surf_geom)) set.seed(123) vertex_data <- rnorm(n_verts) # Define indices (all vertices in this case) vertex_indices <- 1:n_verts # Define color mapping parameters my_cmap <- colorRampPalette(c("blue", "white", "red"))(256) # Blue-white-red colormap my_irange <- c(-2, 2) # Map data values from -2 to 2 onto the colormap my_thresh <- c(-1, 1) # Define thresholds (e.g., for transparency later) # Create the ColorMappedNeuroSurface object mapped_surf <- ColorMappedNeuroSurface(geometry = surf_geom, indices = vertex_indices, data = vertex_data, cmap = my_cmap, irange = my_irange, thresh = my_thresh) # Print the object summary print(mapped_surf) # The object can now be plotted, and the plotting function will use # the stored cmap, irange, and thresh parameters by default. # plot(mapped_surf) # Requires rgl package# Load a sample surface geometry surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Get vertex count and generate some random data n_verts <- nrow(coords(surf_geom)) set.seed(123) vertex_data <- rnorm(n_verts) # Define indices (all vertices in this case) vertex_indices <- 1:n_verts # Define color mapping parameters my_cmap <- colorRampPalette(c("blue", "white", "red"))(256) # Blue-white-red colormap my_irange <- c(-2, 2) # Map data values from -2 to 2 onto the colormap my_thresh <- c(-1, 1) # Define thresholds (e.g., for transparency later) # Create the ColorMappedNeuroSurface object mapped_surf <- ColorMappedNeuroSurface(geometry = surf_geom, indices = vertex_indices, data = vertex_data, cmap = my_cmap, irange = my_irange, thresh = my_thresh) # Print the object summary print(mapped_surf) # The object can now be plotted, and the plotting function will use # the stored cmap, irange, and thresh parameters by default. # plot(mapped_surf) # Requires rgl package
A three-dimensional surface consisting of a set of triangle vertices with one value per vertex, mapped to colors using a specified colormap and range.
This class extends NeuroSurface by adding color mapping functionality.
The cmap slot contains a vector of hex color codes that define the colormap.
The irange slot specifies the range of data values to be mapped to the colormap.
The thresh slot defines the visibility thresholds: data values below thresh[1]
or above thresh[2] are visible, while values in between are not visible.
The color mapping process works as follows:
Data values are linearly mapped to the range [0,1] based on irange
These normalized values are used to interpolate colors from the cmap
Values falling between the thresholds in thresh are marked as invisible
This approach is particularly useful for visualizing statistical maps (e.g., t-statistics) where researchers are often interested in highlighting values above or below certain significance thresholds.
An object of class ColorMappedNeuroSurface
geometryThe surface geometry, an instance of SurfaceGeometry or SurfaceSet
indicesAn integer vector specifying the subset of valid surface nodes encoded in the geometry object
dataThe 1-D vector of data values at each vertex of the mesh
cmapA character vector of hex color codes representing the colormap
irangeA numeric vector of length 2 specifying the low and high values for color mapping
threshA numeric vector of length 2 specifying the low and high thresholds for visibility
# First create a simple tetrahedron mesh vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(-1.5, -0.5, 0.8, 2.0) # example values for the vertices # Define a simple colormap (blue to red) colormap <- c("#0000FF", "#FFFFFF", "#FF0000") # Define intensity range for mapping data to colors intensity_range <- c(-2.0, 2.0) # Define thresholds (values between -0.5 and 0.5 will be invisible) thresholds <- c(-0.5, 0.5) # Create the ColorMappedNeuroSurface object colored_surface <- new("ColorMappedNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, cmap = colormap, irange = intensity_range, thresh = thresholds) # In this example: # - Vertex 1 (-1.5) will be visible and colored blue (below lower threshold) # - Vertex 2 (-0.5) will be exactly at the lower threshold # - Vertex 3 (0.8) will be visible and colored light red (above upper threshold) # - Vertex 4 (2.0) will be visible and colored bright red (above upper threshold)# First create a simple tetrahedron mesh vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(-1.5, -0.5, 0.8, 2.0) # example values for the vertices # Define a simple colormap (blue to red) colormap <- c("#0000FF", "#FFFFFF", "#FF0000") # Define intensity range for mapping data to colors intensity_range <- c(-2.0, 2.0) # Define thresholds (values between -0.5 and 0.5 will be invisible) thresholds <- c(-0.5, 0.5) # Create the ColorMappedNeuroSurface object colored_surface <- new("ColorMappedNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, cmap = colormap, irange = intensity_range, thresh = thresholds) # In this example: # - Vertex 1 (-1.5) will be visible and colored blue (below lower threshold) # - Vertex 2 (-0.5) will be exactly at the lower threshold # - Vertex 3 (0.8) will be visible and colored light red (above upper threshold) # - Vertex 4 (2.0) will be visible and colored bright red (above upper threshold)
Comparison Operations for NeuroSurface Objects
## S4 method for signature 'NeuroSurface,NeuroSurface' Compare(e1, e2)## S4 method for signature 'NeuroSurface,NeuroSurface' Compare(e1, e2)
e1 |
NeuroSurface object |
e2 |
NeuroSurface object |
NeuroSurface object with comparison results
Comparison Operations for NeuroSurface Objects
## S4 method for signature 'NeuroSurface,numeric' Compare(e1, e2)## S4 method for signature 'NeuroSurface,numeric' Compare(e1, e2)
e1 |
the left operand |
e2 |
the right operand |
NeuroSurface object with comparison results
Comparison Operations for NeuroSurfaceVector Objects
## S4 method for signature 'NeuroSurfaceVector,NeuroSurfaceVector' Compare(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,numeric' Compare(e1, e2) ## S4 method for signature 'numeric,NeuroSurfaceVector' Compare(e1, e2)## S4 method for signature 'NeuroSurfaceVector,NeuroSurfaceVector' Compare(e1, e2) ## S4 method for signature 'NeuroSurfaceVector,numeric' Compare(e1, e2) ## S4 method for signature 'numeric,NeuroSurfaceVector' Compare(e1, e2)
e1 |
NeuroSurfaceVector object or numeric value |
e2 |
NeuroSurfaceVector object or numeric value |
NeuroSurfaceVector object with comparison results
Compute boundary hull points in world space (C++)
compute_hull_world_cpp(vol, dims, grid2world, thresh, n_points, mask)compute_hull_world_cpp(vol, dims, grid2world, thresh, n_points, mask)
vol |
flattened numeric array (dim = dims) |
dims |
integer vector length 3 (nx, ny, nz) |
grid2world |
4x4 matrix mapping voxel indices to world coords |
thresh |
intensity threshold |
n_points |
max number of hull points (approximate) |
mask |
optional logical vector same length as vol; if empty, ignored |
numeric matrix (n_points x 3) of (x,y,z) in world coords
This method identifies connected components on a NeuroSurface object based on a given threshold.
## S4 method for signature 'NeuroSurfaceVector' conn_comp(x, threshold, index = 1) ## S4 method for signature 'NeuroSurface' conn_comp(x, threshold)## S4 method for signature 'NeuroSurfaceVector' conn_comp(x, threshold, index = 1) ## S4 method for signature 'NeuroSurface' conn_comp(x, threshold)
x |
A |
threshold |
A numeric vector of length 2 specifying the lower and upper thresholds for including vertices in the components. |
index |
the index/column of the underlying data matrix to cluster |
This method computes connected components on the surface by:
Thresholding the surface data using the provided threshold values.
Creating a subgraph of the surface mesh containing only the vertices that pass the threshold.
Identifying connected components in this subgraph.
Assigning component indices and sizes to the original vertices.
Vertices that do not pass the threshold are assigned a value of 0 in both output surfaces.
A list containing two NeuroSurface objects:
index |
A |
size |
A |
# Load a sample surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Create random data for the surface with some clusters n_vertices <- nrow(coords(surf_geom)) set.seed(123) random_data <- rnorm(n_vertices, mean = 0, sd = 1) # Create a few clusters of higher values cluster_centers <- sample(1:n_vertices, 5) g <- graph(surf_geom) # For each cluster center, set nearby vertices to higher values for (center in cluster_centers) { # Get neighbors within 2 steps neighbors <- unlist(igraph::neighborhood(g, 2, center)) random_data[neighbors] <- random_data[neighbors] + 2 } # Create a NeuroSurface object neuro_surf <- NeuroSurface(geometry = surf_geom, indices = 1:n_vertices, data = random_data) # Find connected components with threshold c(-Inf, 1.5) # This will identify clusters where values are >= 1.5 components <- conn_comp(neuro_surf, c(-Inf, 1.5)) # Check the number of components found max(series(components$index, seq_len(n_vertices))) # Check the size of the largest component max(series(components$size, seq_len(n_vertices))) # Count vertices in components of size >= 10 sum(series(components$size, seq_len(n_vertices)) >= 10)# Load a sample surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Create random data for the surface with some clusters n_vertices <- nrow(coords(surf_geom)) set.seed(123) random_data <- rnorm(n_vertices, mean = 0, sd = 1) # Create a few clusters of higher values cluster_centers <- sample(1:n_vertices, 5) g <- graph(surf_geom) # For each cluster center, set nearby vertices to higher values for (center in cluster_centers) { # Get neighbors within 2 steps neighbors <- unlist(igraph::neighborhood(g, 2, center)) random_data[neighbors] <- random_data[neighbors] + 2 } # Create a NeuroSurface object neuro_surf <- NeuroSurface(geometry = surf_geom, indices = 1:n_vertices, data = random_data) # Find connected components with threshold c(-Inf, 1.5) # This will identify clusters where values are >= 1.5 components <- conn_comp(neuro_surf, c(-Inf, 1.5)) # Check the number of components found max(series(components$index, seq_len(n_vertices))) # Check the size of the largest component max(series(components$size, seq_len(n_vertices))) # Count vertices in components of size >= 10 sum(series(components$size, seq_len(n_vertices)) >= 10)
Extracts the 3D coordinates of vertices from a surface object.
## S4 method for signature 'ROISurface' coords(x) ## S4 method for signature 'SurfaceGeometry' coords(x) ## S4 method for signature 'igraph' coords(x) ## S4 method for signature 'NeuroSurfaceVector' coords(x) ## S4 method for signature 'NeuroSurface' coords(x)## S4 method for signature 'ROISurface' coords(x) ## S4 method for signature 'SurfaceGeometry' coords(x) ## S4 method for signature 'igraph' coords(x) ## S4 method for signature 'NeuroSurfaceVector' coords(x) ## S4 method for signature 'NeuroSurface' coords(x)
x |
the object to extract coordinates from |
A numeric matrix with three columns (x, y, z) and one row per vertex
This function maps a vector of surface curvature values (e.g., mean curvature) to a binary color scheme, typically used to distinguish gyri (outward folds) from sulci (inward folds) on a brain surface visualization.
curv_cols(vals, incol = "#B3B3B3", outcol = "#404040")curv_cols(vals, incol = "#B3B3B3", outcol = "#404040")
vals |
A numeric vector containing curvature values for each vertex on the surface. |
incol |
A character string specifying the hex color code to represent vertices with curvature values *greater than* the median curvature. Default is "#B3B3B3" (light gray). |
outcol |
A character string specifying the hex color code to represent vertices with curvature values *less than or equal to* the median curvature. Default is "#404040" (dark gray). |
Surface curvature provides information about the local shape of the surface. Mean curvature is often used, where positive values typically indicate outward curvature (gyri) and negative values indicate inward curvature (sulci). This function simplifies the curvature map into two colors based on whether the value is above or below the median curvature, providing a quick visual distinction between these features. Note the default coloring assigns 'incol' to values *above* the median and 'outcol' to values *at or below* the median. You might need to adjust 'incol' and 'outcol' depending on the specific interpretation of curvature values in your data (e.g., if positive values represent sulci).
A character vector of the same length as 'vals', containing hex color codes based on the binary classification of curvature values relative to the median.
# Generate some example curvature values set.seed(123) curvature_values <- rnorm(100, mean = 0, sd = 0.1) # Get binary colors using default light/dark gray gray_colors <- curv_cols(curvature_values) table(gray_colors) # Use different colors (e.g., red for above median, blue for below) red_blue_colors <- curv_cols(curvature_values, incol = "#FF0000", outcol = "#0000FF") table(red_blue_colors)# Generate some example curvature values set.seed(123) curvature_values <- rnorm(100, mean = 0, sd = 0.1) # Get binary colors using default light/dark gray gray_colors <- curv_cols(curvature_values) table(gray_colors) # Use different colors (e.g., red for above median, blue for below) red_blue_colors <- curv_cols(curvature_values, incol = "#FF0000", outcol = "#0000FF") table(red_blue_colors)
Maps surface curvature values to a continuous grayscale gradient, producing
a FreeSurfer-style sulcal shading that is visually smoother than the binary
mapping of curv_cols.
curv_cols_smooth( vals, light = "#C8C8C8", dark = "#4D4D4D", quantiles = c(0.05, 0.95), sharpness = 6 )curv_cols_smooth( vals, light = "#C8C8C8", dark = "#4D4D4D", quantiles = c(0.05, 0.95), sharpness = 6 )
vals |
A numeric vector of curvature values for each vertex. |
light |
Hex color for the lightest shade (gyral crowns).
Default |
dark |
Hex color for the darkest shade (sulcal fundi).
Default |
quantiles |
Length-2 numeric vector of lower and upper quantiles used
to clamp extreme values before rescaling. Default |
sharpness |
Non-negative number controlling how crisp the gyral/sulcal
split is. Larger values push vertices toward the |
Values are clamped to the range defined by quantiles to prevent
outliers from washing out the colour map. The clamped values are then
centred on their median (the gyral/sulcal boundary) and passed through a
logistic contrast curve governed by sharpness before being
interpolated between dark (sulcal fundi) and light
(gyral crowns).
A plain linear ramp leaves most vertices near mid-grey, so the fold pattern tends to disappear once surface lighting is applied. Pushing values toward the two extremes with a logistic curve keeps the sulci clearly dark and the gyri clearly light, which reads as anatomical folding under lighting much the way FreeSurfer / Connectome Workbench curvature overlays do.
A character vector of hex color codes the same length as vals.
curv_cols, curvature, view_surface
set.seed(1) curv <- rnorm(500, sd = 0.1) cols <- curv_cols_smooth(curv) head(cols) # Softer, more continuous gradient cols_soft <- curv_cols_smooth(curv, sharpness = 2)set.seed(1) curv <- rnorm(500, sd = 0.1) cols <- curv_cols_smooth(curv) head(cols) # Softer, more continuous gradient cols_soft <- curv_cols_smooth(curv, sharpness = 2)
Compute Surface Curvature Vector
curvature(x, ...) curvature(x, ...) ## S4 method for signature 'SurfaceGeometry' curvature(x)curvature(x, ...) curvature(x, ...) ## S4 method for signature 'SurfaceGeometry' curvature(x)
x |
Object to compute curvature from |
... |
Additional arguments |
A numeric vector of curvature values, one per vertex
Creates a column reader object for accessing surface data.
## S4 method for signature 'SurfaceGeometryMetaInfo' data_reader(x) ## S4 method for signature 'NIMLSurfaceDataMetaInfo' data_reader(x)## S4 method for signature 'SurfaceGeometryMetaInfo' data_reader(x) ## S4 method for signature 'NIMLSurfaceDataMetaInfo' data_reader(x)
x |
A SurfaceGeometryMetaInfo object |
A ColumnReader object for accessing surface data columns
This function helps diagnose issues with surfwidget rendering by checking common problems and providing debugging information.
debug_surfwidget(x, verbose = TRUE)debug_surfwidget(x, verbose = TRUE)
x |
The surface object you're trying to visualize |
verbose |
Logical, whether to print detailed information |
Invisibly returns a list of diagnostic information
# Load a surface and check it surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package="neurosurf") surf <- read_surf(surf_file) debug_surfwidget(surf)# Load a surface and check it surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package="neurosurf") surf <- read_surf(surf_file) debug_surfwidget(surf)
This is a convenience wrapper around render_surface_plot that
arranges rendered panels into a single static figure using the grid
graphics system. It supersamples, crops whitespace, and preserves per-panel
aspect ratios to avoid tiny or distorted brains when assembled.
draw_surface_plot( x, colorbar = TRUE, cbar_location = c("bottom", "right"), cbar_kws = list() )draw_surface_plot( x, colorbar = TRUE, cbar_location = c("bottom", "right"), cbar_kws = list() )
x |
A |
colorbar |
Logical; if |
cbar_location |
Location of colour bars relative to the panel layout.
Currently supports |
cbar_kws |
Optional list of graphical parameters for colour bars
(e.g., |
A grob object that can be drawn with grid::grid.draw().
# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # g <- draw_surface_plot(sp) # grid::grid.draw(g)# Requires FreeSurfer-like surface files # sp <- surface_plot(left = "lh.pial", right = "rh.pial") # g <- draw_surface_plot(sp) # grid::grid.draw(g)
Extracts the triangle faces from a surface object, providing a standardized interface across different surface representations.
faces(x, ...) ## S4 method for signature 'SurfaceGeometry' faces(x) ## S4 method for signature 'NeuroSurface' faces(x) ## S4 method for signature 'NeuroSurfaceVector' faces(x)faces(x, ...) ## S4 method for signature 'SurfaceGeometry' faces(x) ## S4 method for signature 'NeuroSurface' faces(x) ## S4 method for signature 'NeuroSurfaceVector' faces(x)
x |
An object representing a surface. |
... |
Additional arguments passed to methods. |
A matrix where each row represents a triangular face, containing the 1-based vertex indices that form the triangle.
geom <- example_surface_geometry() face_data <- faces(geom) num_faces <- nrow(face_data)geom <- example_surface_geometry() face_data <- faces(geom) num_faces <- nrow(face_data)
Identifies all neighboring nodes within a specified radius for a given surface mesh.
find_all_neighbors( surf, radius, edgeWeights, nodes = NULL, distance_type = c("euclidean", "geodesic", "spherical") )find_all_neighbors( surf, radius, edgeWeights, nodes = NULL, distance_type = c("euclidean", "geodesic", "spherical") )
surf |
A SurfaceGeometry object or igraph object representing the mesh |
radius |
Numeric; the spatial radius within which to search for neighbors. Must be positive. |
edgeWeights |
Numeric vector; weights for edges used in distance computation. Length must equal the number of edges. |
nodes |
Integer vector; subset of nodes to find neighbors for. If NULL, uses all nodes |
distance_type |
Character; type of distance metric to use: "euclidean", "geodesic", or "spherical" |
The function supports three distance metrics: Euclidean, geodesic, and spherical.
For spherical distances, the surface is assumed to be a sphere.
The internal k-nearest-neighbor search is capped at vcount(g) - 1 to avoid
requesting more neighbors than exist in the graph.
A list of matrices, each containing neighbor information:
i |
Source node index |
j |
Neighbor node index |
d |
Distance between nodes |
# Load a sample inflated surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf <- read_surf_geometry(surf_file) # Create edge weights (using uniform weights for simplicity) g <- graph(surf) edge_weights <- rep(1, length(igraph::E(g))) # Find neighbors within a 10mm radius for the first 5 vertices neighbors <- find_all_neighbors(surf, radius = 10, edgeWeights = edge_weights, nodes = 1:5, distance_type = "geodesic") # Check the number of neighbors found for the first vertex nrow(neighbors[[1]]) # Look at the first few neighbors of the first vertex head(neighbors[[1]])# Load a sample inflated surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf <- read_surf_geometry(surf_file) # Create edge weights (using uniform weights for simplicity) g <- graph(surf) edge_weights <- rep(1, length(igraph::E(g))) # Find neighbors within a 10mm radius for the first 5 vertices neighbors <- find_all_neighbors(surf, radius = 10, edgeWeights = edge_weights, nodes = 1:5, distance_type = "geodesic") # Check the number of neighbors found for the first vertex nrow(neighbors[[1]]) # Look at the first few neighbors of the first vertex head(neighbors[[1]])
Find the nearest surface vertex to a 3D point
find_nearest_vertex(surface, point)find_nearest_vertex(surface, point)
surface |
A |
point |
Numeric vector of length 3. |
Integer vertex index (1-based) of the closest vertex.
geom <- example_surface_geometry() find_nearest_vertex(geom, c(0.9, 0, 0))geom <- example_surface_geometry() find_nearest_vertex(geom, c(0.9, 0, 0))
This function identifies boundaries between regions of interest (ROIs)
defined on a triangular surface mesh. It is a translation of the core
parts of Stuart Oldham's findROIboundaries MATLAB function, adapted
for use with neurosurf objects.
find_roi_boundaries( vertices, faces, vertex_id, boundary_method = c("midpoint", "faces", "edge_vertices"), verbose = FALSE, use_cpp = TRUE )find_roi_boundaries( vertices, faces, vertex_id, boundary_method = c("midpoint", "faces", "edge_vertices"), verbose = FALSE, use_cpp = TRUE )
vertices |
Numeric matrix of vertex coordinates ( |
faces |
Integer matrix of face indices ( |
vertex_id |
Integer vector of ROI labels for each vertex (length |
boundary_method |
One of |
verbose |
Logical; if |
use_cpp |
Logical; if |
Three boundary representations are currently supported:
"midpoint" (default): returns crisp single-width contour
segments that run between differing labels, through the midpoints
of the mesh edges that separate them. This is the recommended method for
drawing clean ROI/atlas outlines: shared borders are drawn once (no
double lines) and adjacent segments join into continuous contours.
"faces": returns a logical vector indicating which faces lie
on a boundary between ROIs.
"edge_vertices": returns boundary polygons traced through
mesh vertices. Borders are traced along vertices on both sides of a
boundary, which can read as a thicker double line on coarse meshes.
A list with elements:
boundaryFor "faces": logical vector of length
nrow(faces) indicating boundary faces.
For "midpoint": list of coordinate matrices, one
per contour segment.
For "edge_vertices": list of coordinate matrices ()
giving boundary polygons for each connected ROI component.
boundary_roi_idInteger vector giving the ROI id associated
with each boundary polygon (empty for "faces").
roi_componentsInteger vector giving the number of connected
components for each ROI (indexed parallel to sort(unique(vertex_id))).
boundary_vertsFor "edge_vertices": list of integer
vectors giving the vertex ids used for each boundary polygon; NULL
for "faces".
# Simple cube mesh with two ROIs (bottom vs top) vertices <- matrix(c( 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 ), ncol = 3, byrow = TRUE) faces <- matrix(c( 1,2,3, 1,3,4, 5,6,7, 5,7,8, 1,2,6, 1,6,5, 3,4,8, 3,8,7, 1,4,8, 1,8,5, 2,3,7, 2,7,6 ), ncol = 3, byrow = TRUE) roi <- c(1,1,1,1, 2,2,2,2) b <- find_roi_boundaries(vertices, faces, roi, boundary_method = "edge_vertices") str(b$boundary)# Simple cube mesh with two ROIs (bottom vs top) vertices <- matrix(c( 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 ), ncol = 3, byrow = TRUE) faces <- matrix(c( 1,2,3, 1,3,4, 5,6,7, 5,7,8, 1,2,6, 1,6,5, 3,4,8, 3,8,7, 1,4,8, 1,8,5, 2,3,7, 2,7,6 ), ncol = 3, byrow = TRUE) roi <- c(1,1,1,1, 2,2,2,2) b <- find_roi_boundaries(vertices, faces, roi, boundary_method = "edge_vertices") str(b$boundary)
This generic function identifies boundaries between different regions or parcellations on a surface. The implementation depends on the class of the input object.
findBoundaries(x, method = "midpoint", ...) ## S4 method for signature 'NeuroSurface' findBoundaries(x, method = c("midpoint", "edge_vertices", "faces"), ...)findBoundaries(x, method = "midpoint", ...) ## S4 method for signature 'NeuroSurface' findBoundaries(x, method = c("midpoint", "edge_vertices", "faces"), ...)
x |
A |
method |
Boundary method passed to |
... |
Additional arguments passed to |
This function provides a high-level interface for finding boundaries between different regions on a surface mesh. It typically returns coordinates and metadata describing the boundaries between regions.
An object containing boundary information. The specific structure depends on the method implementation.
A list as returned by find_roi_boundaries.
# Requires surface with ROI labels # boundaries <- findBoundaries(labeled_surface)# Requires surface with ROI labels # boundaries <- findBoundaries(labeled_surface)
This class supports the Freesurfer Ascii file format for surface geometry
An object of class FreesurferAsciiSurfaceFileDescriptor.
# Create a FreesurferAsciiSurfaceFileDescriptor object fs_ascii_descriptor <- new("FreesurferAsciiSurfaceFileDescriptor") # This descriptor would typically be used when loading Freesurfer ASCII surfaces # Example of a path to a Freesurfer ASCII surface file: # fs_ascii_file <- "/path/to/subject/surf/lh.pial.asc" # In practice, this descriptor would be used in code like: # surface_geo <- loadSurfaceGeometry(fs_ascii_file, descriptor = fs_ascii_descriptor)# Create a FreesurferAsciiSurfaceFileDescriptor object fs_ascii_descriptor <- new("FreesurferAsciiSurfaceFileDescriptor") # This descriptor would typically be used when loading Freesurfer ASCII surfaces # Example of a path to a Freesurfer ASCII surface file: # fs_ascii_file <- "/path/to/subject/surf/lh.pial.asc" # In practice, this descriptor would be used in code like: # surface_geo <- loadSurfaceGeometry(fs_ascii_file, descriptor = fs_ascii_descriptor)
This class supports the Freesurfer binary file format for surface geometry
An object of class FreesurferBinarySurfaceFileDescriptor.
# Create a FreesurferBinarySurfaceFileDescriptor object fs_binary_descriptor <- new("FreesurferBinarySurfaceFileDescriptor") # This descriptor would typically be used when loading Freesurfer binary surfaces # Example of a path to a Freesurfer binary surface file: # fs_binary_file <- "/path/to/subject/surf/lh.pial" # In practice, this descriptor would be used in code like: # surface_geo <- loadSurfaceGeometry(fs_binary_file, descriptor = fs_binary_descriptor)# Create a FreesurferBinarySurfaceFileDescriptor object fs_binary_descriptor <- new("FreesurferBinarySurfaceFileDescriptor") # This descriptor would typically be used when loading Freesurfer binary surfaces # Example of a path to a Freesurfer binary surface file: # fs_binary_file <- "/path/to/subject/surf/lh.pial" # In practice, this descriptor would be used in code like: # surface_geo <- loadSurfaceGeometry(fs_binary_file, descriptor = fs_binary_descriptor)
The 'FreesurferSurfaceGeometryMetaInfo' class extends 'SurfaceGeometryMetaInfo' to specifically handle meta information for Freesurfer-formatted brain surface geometries.
This class inherits all slots from the parent 'SurfaceGeometryMetaInfo' class and is specialized for working with Freesurfer surface files (e.g., .asc, .pial, .white, .inflated). It maintains the same structure but is used specifically when the surface data originates from Freesurfer processing pipelines.
An object of class FreesurferSurfaceGeometryMetaInfo.
fs_meta <- new("FreesurferSurfaceGeometryMetaInfo", header_file = "lh.white.asc", data_file = "lh.white.asc", file_descriptor = new("FileFormat"), vertices = 140000L, faces = 279998L, embed_dimension = 3L, label = "white", hemi = "lh")fs_meta <- new("FreesurferSurfaceGeometryMetaInfo", header_file = "lh.white.asc", data_file = "lh.white.asc", file_descriptor = new("FileFormat"), vertices = 140000L, faces = 279998L, embed_dimension = 3L, label = "white", hemi = "lh")
Create per-vertex Gaussian falloff maps centred on coordinates or vertices. Distances can be measured either in straight-line Euclidean space or along the mesh using geodesic paths (Dijkstra on edge lengths).
gaussian_splat(surface, center, sigma, use_geodesic = FALSE) gaussian_splat_vertex(surface, vertex_idx, sigma, use_geodesic = FALSE) gaussian_splat_multi( surface, centers, sigmas, weights = NULL, use_geodesic = FALSE )gaussian_splat(surface, center, sigma, use_geodesic = FALSE) gaussian_splat_vertex(surface, vertex_idx, sigma, use_geodesic = FALSE) gaussian_splat_multi( surface, centers, sigmas, weights = NULL, use_geodesic = FALSE )
surface |
A |
center |
Numeric vector of length 3 giving the centre coordinate. |
sigma |
Positive numeric standard deviation of the Gaussian kernel. |
use_geodesic |
Logical; when |
vertex_idx |
Integer index (1-based) of the centre vertex. |
centers |
Numeric matrix with three columns; each row is a centre. |
sigmas |
Numeric vector of length 1 or |
weights |
Optional numeric vector of length 1 or
|
A NeuroSurface with values
at every vertex. For
gaussian_splat_multi the per-centre maps are summed (after
weighting).
geom <- example_surface_geometry() g1 <- gaussian_splat(geom, center = c(0, 0, 0), sigma = 1) v_idx <- find_nearest_vertex(geom, c(0.1, 0, 0)) g2 <- gaussian_splat_vertex(geom, vertex_idx = v_idx, sigma = 1) g_multi <- gaussian_splat_multi( geom, centers = rbind(c(0, 0, 0), c(1, 0, 0)), sigmas = c(0.5, 1) )geom <- example_surface_geometry() g1 <- gaussian_splat(geom, center = c(0, 0, 0), sigma = 1) v_idx <- find_nearest_vertex(geom, c(0.1, 0, 0)) g2 <- gaussian_splat_vertex(geom, vertex_idx = v_idx, sigma = 1) g_multi <- gaussian_splat_multi( geom, centers = rbind(c(0, 0, 0), c(1, 0, 0)), sigmas = c(0.5, 1) )
All-pairs geodesic distance matrix (chunked)
geodesic_distance_matrix( geometry, vertices = NULL, targets = NULL, weights = NULL, mode = c("sparse", "dense"), chunk_size = 2000, cache = TRUE, cache_key = NULL, algorithm = c("dijkstra") )geodesic_distance_matrix( geometry, vertices = NULL, targets = NULL, weights = NULL, mode = c("sparse", "dense"), chunk_size = 2000, cache = TRUE, cache_key = NULL, algorithm = c("dijkstra") )
geometry |
|
vertices |
Optional integer vector of source vertices. Defaults to all vertices. |
targets |
Optional integer vector of target vertices. Defaults to
|
weights |
Optional numeric edge weights (defaults to |
mode |
Output mode: |
chunk_size |
Number of source vertices per Dijkstra batch. |
cache |
Logical; cache symmetric results when |
cache_key |
Optional manual cache key. |
algorithm |
Only "dijkstra" is currently implemented. |
A distance matrix (sparse or dense) of size
length(vertices) x length(targets).
geom <- example_surface_geometry() dmat <- geodesic_distance_matrix(geom, vertices = 1:2)geom <- example_surface_geometry() dmat <- geodesic_distance_matrix(geom, vertices = 1:2)
Convenience wrapper returning a numeric vector/matrix.
geodesic_distances( geometry, sources, targets = NULL, weights = NULL, algorithm = c("dijkstra"), chunk_size = 2000 )geodesic_distances( geometry, sources, targets = NULL, weights = NULL, algorithm = c("dijkstra"), chunk_size = 2000 )
geometry |
|
sources |
Integer vector of source vertices. |
targets |
Optional target vertices (defaults to |
weights |
Optional numeric edge weights (defaults to |
algorithm |
Only "dijkstra" is currently implemented. |
chunk_size |
Number of source vertices per Dijkstra batch. |
Numeric vector if one source, otherwise a matrix.
geom <- example_surface_geometry() d <- geodesic_distances(geom, sources = 1, targets = 2:4)geom <- example_surface_geometry() d <- geodesic_distances(geom, sources = 1, targets = 2:4)
Extracts the geometric representation from a surface object.
geometry(x) ## S4 method for signature 'NeuroSurface' geometry(x) ## S4 method for signature 'NeuroSurfaceVector' geometry(x)geometry(x) ## S4 method for signature 'NeuroSurface' geometry(x) ## S4 method for signature 'NeuroSurfaceVector' geometry(x)
x |
A surface object |
A geometry object representing the surface structure
# Load a sample surface surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") surf <- read_surf_geometry(surf_file) # Create a NeuroSurface with some data ns <- NeuroSurface(surf, indices = 1:100, data = rnorm(100)) # Extract the geometry geom <- geometry(ns) class(geom)# Load a sample surface surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") surf <- read_surf_geometry(surf_file) # Create a NeuroSurface with some data ns <- NeuroSurface(surf, indices = 1:100, data = rnorm(100)) # Extract the geometry geom <- geometry(ns) class(geom)
Retrieve a geometry from a SurfaceSet
get_surface(x, label = NULL)get_surface(x, label = NULL)
x |
SurfaceSet |
label |
Label of the desired surface variant. Defaults to the set's default. |
A 'SurfaceGeometry' object.
geom <- example_surface_geometry() ss <- surface_set(inflated = geom) get_surface(ss, "inflated")geom <- example_surface_geometry() ss <- surface_set(inflated = geom) get_surface(ss, "inflated")
This class contains meta information for surface-based data for the GIFTI data format
An object of class GIFTISurfaceDataMetaInfo.
infothe underlying gifti object returned by
readgii
# First create a SurfaceDataMetaInfo parent object meta_info <- new("SurfaceDataMetaInfo", header_file = "rscan01_lh.gii", data_file = "rscan01_lh.gii", file_descriptor = new("FileFormat"), node_count = 40000L, nels = 1L, label = "thickness") # Use the example file included in the package example_gii_file <- system.file("extdata", "rscan01_lh.gii", package = "neurostyle") if (file.exists(example_gii_file) && requireNamespace("gifti", quietly = TRUE)) { # Load the actual GIFTI file gifti_obj <- gifti::readgii(example_gii_file) # Create GIFTISurfaceDataMetaInfo object with the real file gifti_data_meta <- new("GIFTISurfaceDataMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, node_count = meta_info@node_count, nels = meta_info@nels, label = meta_info@label, info = gifti_obj) }# First create a SurfaceDataMetaInfo parent object meta_info <- new("SurfaceDataMetaInfo", header_file = "rscan01_lh.gii", data_file = "rscan01_lh.gii", file_descriptor = new("FileFormat"), node_count = 40000L, nels = 1L, label = "thickness") # Use the example file included in the package example_gii_file <- system.file("extdata", "rscan01_lh.gii", package = "neurostyle") if (file.exists(example_gii_file) && requireNamespace("gifti", quietly = TRUE)) { # Load the actual GIFTI file gifti_obj <- gifti::readgii(example_gii_file) # Create GIFTISurfaceDataMetaInfo object with the real file gifti_data_meta <- new("GIFTISurfaceDataMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, node_count = meta_info@node_count, nels = meta_info@nels, label = meta_info@label, info = gifti_obj) }
This class supports the GIFTI file format for surface-based data
An object of class GIFTISurfaceFileDescriptor.
This class contains meta information for surface-based geometry for the GIFTI data format
An object of class GIFTISurfaceGeometryMetaInfo.
infothe underlying gifti object returned by
readgii
# First create a SurfaceGeometryMetaInfo parent object meta_info <- new("SurfaceGeometryMetaInfo", header_file = "rscan01_lh.gii", data_file = "rscan01_lh.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh") # Use the example file included in the package example_gii_file <- system.file("extdata", "rscan01_lh.gii", package = "neurostyle") if (file.exists(example_gii_file) && requireNamespace("gifti", quietly = TRUE)) { # Load the actual GIFTI file gifti_obj <- gifti::readgii(example_gii_file) # Create GIFTISurfaceGeometryMetaInfo object with the real file gifti_meta <- new("GIFTISurfaceGeometryMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, vertices = meta_info@vertices, faces = meta_info@faces, embed_dimension = meta_info@embed_dimension, label = meta_info@label, hemi = meta_info@hemi, info = gifti_obj) }# First create a SurfaceGeometryMetaInfo parent object meta_info <- new("SurfaceGeometryMetaInfo", header_file = "rscan01_lh.gii", data_file = "rscan01_lh.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh") # Use the example file included in the package example_gii_file <- system.file("extdata", "rscan01_lh.gii", package = "neurostyle") if (file.exists(example_gii_file) && requireNamespace("gifti", quietly = TRUE)) { # Load the actual GIFTI file gifti_obj <- gifti::readgii(example_gii_file) # Create GIFTISurfaceGeometryMetaInfo object with the real file gifti_meta <- new("GIFTISurfaceGeometryMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, vertices = meta_info@vertices, faces = meta_info@faces, embed_dimension = meta_info@embed_dimension, label = meta_info@label, hemi = meta_info@hemi, info = gifti_obj) }
igraph objectextract igraph object
graph(x, ...) ## S4 method for signature 'SurfaceGeometry' graph(x) ## S4 method for signature 'NeuroSurface' graph(x, ...) ## S4 method for signature 'NeuroSurfaceVector' graph(x, ...)graph(x, ...) ## S4 method for signature 'SurfaceGeometry' graph(x) ## S4 method for signature 'NeuroSurface' graph(x, ...) ## S4 method for signature 'NeuroSurfaceVector' graph(x, ...)
x |
the object to extract the graph from |
... |
extra args |
An igraph object representing the surface mesh connectivity
Extracts the vertex indices from surface objects.
## S4 method for signature 'ROISurface' indices(x) ## S4 method for signature 'ROISurfaceVector' indices(x) ## S4 method for signature 'NeuroSurfaceVector' indices(x) ## S4 method for signature 'NeuroSurface' indices(x)## S4 method for signature 'ROISurface' indices(x) ## S4 method for signature 'ROISurfaceVector' indices(x) ## S4 method for signature 'NeuroSurfaceVector' indices(x) ## S4 method for signature 'NeuroSurface' indices(x)
x |
the object to extract indices from |
An integer vector of vertex indices
Represents a 3D surface with labeled vertices, extending NeuroSurface.
The LabeledNeuroSurface class provides a way to represent anatomical parcellations or other categorical divisions of a brain surface. Each vertex is assigned a label based on its data value, which typically represents a region ID. The class maintains a mapping between these IDs and human-readable labels, along with colors for visualization.
This is particularly useful for displaying anatomical atlases or the results of clustering algorithms on the brain surface.
An object of class LabeledNeuroSurface.
labelsCharacter vector of label annotations
colsCharacter vector of hex color codes for labels
# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(1, 2, 1, 3) # Values representing region IDs # Define the unique labels for the regions labels <- c("Region A", "Region B", "Region C") # Define colors for each label (in the same order as labels) colors <- c("#FF0000", "#00FF00", "#0000FF") # Red, Green, Blue # Create the LabeledNeuroSurface object labeled_surface <- new("LabeledNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, labels = labels, cols = colors) # In this example, vertices are labeled as follows: # - Vertices 1 and 3 belong to "Region A" (Red) # - Vertex 2 belongs to "Region B" (Green) # - Vertex 4 belongs to "Region C" (Blue)# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(1, 2, 1, 3) # Values representing region IDs # Define the unique labels for the regions labels <- c("Region A", "Region B", "Region C") # Define colors for each label (in the same order as labels) colors <- c("#FF0000", "#00FF00", "#0000FF") # Red, Green, Blue # Create the LabeledNeuroSurface object labeled_surface <- new("LabeledNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, labels = labels, cols = colors) # In this example, vertices are labeled as follows: # - Vertices 1 and 3 belong to "Region A" (Red) # - Vertex 2 belongs to "Region B" (Green) # - Vertex 4 belongs to "Region C" (Blue)
Compute Graph Laplacian
laplacian(x, normalized, weights, ...) ## S4 method for signature 'SurfaceGeometry,missing,missing' laplacian(x) ## S4 method for signature 'SurfaceGeometry,missing,numeric' laplacian(x, weights)laplacian(x, normalized, weights, ...) ## S4 method for signature 'SurfaceGeometry,missing,missing' laplacian(x) ## S4 method for signature 'SurfaceGeometry,missing,numeric' laplacian(x, weights)
x |
Object to compute Laplacian from |
normalized |
Logical; whether to normalize the Laplacian |
weights |
Edge weights for weighted Laplacian matrix |
... |
Additional arguments |
A sparse Laplacian matrix of class dgCMatrix
Get Left Hemisphere
left(x) ## S4 method for signature 'BilatNeuroSurfaceVector' left(x)left(x) ## S4 method for signature 'BilatNeuroSurfaceVector' left(x)
x |
Surface object |
Left hemisphere of the surface
# Requires bilateral surface data # lh <- left(bilat_surface)# Requires bilateral surface data # lh <- left(bilat_surface)
Returns the number of vertices in a surface object.
## S4 method for signature 'ROISurface' length(x)## S4 method for signature 'ROISurface' length(x)
x |
the object to extract the length from |
An integer giving the number of vertices
Loads surface geometry data from a source object.
## S4 method for signature 'NeuroSurfaceVectorSource' load_data(x) ## S4 method for signature 'NeuroSurfaceSource' load_data(x) ## S4 method for signature 'FreesurferSurfaceGeometryMetaInfo' load_data(x) ## S4 method for signature 'GIFTISurfaceGeometryMetaInfo' load_data(x) ## S4 method for signature 'SurfaceGeometrySource' load_data(x)## S4 method for signature 'NeuroSurfaceVectorSource' load_data(x) ## S4 method for signature 'NeuroSurfaceSource' load_data(x) ## S4 method for signature 'FreesurferSurfaceGeometryMetaInfo' load_data(x) ## S4 method for signature 'GIFTISurfaceGeometryMetaInfo' load_data(x) ## S4 method for signature 'SurfaceGeometrySource' load_data(x)
x |
the object to load data from |
A SurfaceGeometry object containing the loaded mesh data
This is a high-level wrapper that mirrors the API of neuromaps'
fetch_fsaverage() but is currently limited to the "std.8"
decimated fsaverage surfaces that ship with neurosurf. The function name
uses "load" rather than "fetch" to follow common R idioms.
load_fsaverage( density = "std.8", surf = c("smoothwm", "pial", "inflated", "white", "sphere") )load_fsaverage( density = "std.8", surf = c("smoothwm", "pial", "inflated", "white", "sphere") )
density |
Character string specifying surface density. At present only
|
surf |
Character string specifying which surface to load. One of
|
A named list with elements "lh" and "rh", each a
SurfaceGeometry instance.
fs <- load_fsaverage(density = "std.8", surf = "inflated") if (interactive()) { show_surface_plot(fs$lh, fs$rh, views = c("lateral", "medial")) }fs <- load_fsaverage(density = "std.8", surf = "inflated") if (interactive()) { show_surface_plot(fs$lh, fs$rh, views = c("lateral", "medial")) }
Load a bundle of fsaverage surface variants as a SurfaceSet
load_fsaverage_bundle( density = "std.8", surfs = c("smoothwm", "pial", "inflated", "white", "sphere"), default_label = "smoothwm" )load_fsaverage_bundle( density = "std.8", surfs = c("smoothwm", "pial", "inflated", "white", "sphere"), default_label = "smoothwm" )
density |
Surface density; currently only |
surfs |
Character vector of surface labels to include (e.g.,
|
default_label |
Which label to treat as default when none is specified. |
A named list with elements \"lh\" and \"rh\", each a
SurfaceSet containing the requested variants.
bundle <- load_fsaverage_bundle() lh_set <- bundle$lh rh_set <- bundle$rhbundle <- load_fsaverage_bundle() lh_set <- bundle$lh rh_set <- bundle$rh
This convenience helper loads the FreeSurfer fsaverage surfaces that ship
with neurosurf (the std.8 decimated variant) and returns them as
SurfaceGeometry objects.
load_fsaverage_std8( surf = c("smoothwm", "pial", "inflated", "white", "sphere") )load_fsaverage_std8( surf = c("smoothwm", "pial", "inflated", "white", "sphere") )
surf |
Character string specifying which surface to load. One of
|
A named list with elements "lh" and "rh", each a
SurfaceGeometry instance for the requested surface type.
fs <- load_fsaverage_std8("smoothwm") if (interactive()) { show_surface_plot(fs$lh, fs$rh, views = c("lateral", "medial")) }fs <- load_fsaverage_std8("smoothwm") if (interactive()) { show_surface_plot(fs$lh, fs$rh, views = c("lateral", "medial")) }
load Freesurfer ascii surface
loadFSSurface(meta_info, surf_to_world = diag(4))loadFSSurface(meta_info, surf_to_world = diag(4))
meta_info |
instance of type |
surf_to_world |
Optional 4x4 affine transformation matrix from surface (tkr-RAS) coordinates to world (scanner RAS) coordinates. Defaults to identity. For proper alignment with volumes, this transform can be computed from FreeSurfer's vox2ras-tkr matrix (available in orig.mgz or via mri_info –vox2ras-tkr). |
requires rgl library
a class of type SurfaceGeometry
# Requires FreeSurfer surface file # meta <- read_meta_info(FreesurferAsciiSurfaceFileDescriptor(), "lh.pial.asc") # geom <- loadFSSurface(meta)# Requires FreeSurfer surface file # meta <- read_meta_info(FreesurferAsciiSurfaceFileDescriptor(), "lh.pial.asc") # geom <- loadFSSurface(meta)
Loads a GIFTI (.surf.gii) surface into a
SurfaceGeometry. The usual public entry point for
reading a surface from disk is read_surf_geometry /
read_surf; this function is the GIFTI-specific loader it
dispatches to. For convenience it also accepts a file path directly, in
which case the header is read internally.
loadGIFTISurface(meta_info)loadGIFTISurface(meta_info)
meta_info |
either a |
requires rgl library
a class of type SurfaceGeometry
# Either pass a path directly ... # geom <- loadGIFTISurface("lh.midthickness.surf.gii") # ... or go through the meta-info object: # meta <- read_meta_info(neurosurf:::GIFTI_SURFACE_DSET, "lh.midthickness.surf.gii") # geom <- loadGIFTISurface(meta)# Either pass a path directly ... # geom <- loadGIFTISurface("lh.midthickness.surf.gii") # ... or go through the meta-info object: # meta <- read_meta_info(neurosurf:::GIFTI_SURFACE_DSET, "lh.midthickness.surf.gii") # geom <- loadGIFTISurface(meta)
Map Values for NeuroSurface with List Lookup
## S4 method for signature 'NeuroSurface,list' map_values(x, lookup)## S4 method for signature 'NeuroSurface,list' map_values(x, lookup)
x |
a |
lookup |
a list of values to map |
A NeuroSurface object with remapped values
Map Values for NeuroSurface with Matrix Lookup
## S4 method for signature 'NeuroSurface,matrix' map_values(x, lookup)## S4 method for signature 'NeuroSurface,matrix' map_values(x, lookup)
x |
a |
lookup |
a |
A NeuroSurface object with remapped values
This function creates an igraph object representing the connectivity structure of a 3D mesh based on its vertices and triangular faces.
meshToGraph(vertices, nodes)meshToGraph(vertices, nodes)
vertices |
A numeric matrix with 3 columns representing the x, y, and z coordinates of vertices. Each row corresponds to a vertex. |
nodes |
A numeric matrix where each row represents a triangular face, containing 0-based indices of three vertices that form the face. |
The function converts a triangular mesh into a graph representation where:
Vertices of the graph correspond to vertices of the mesh
Edges of the graph correspond to the edges of triangular faces in the mesh
The function performs the following steps:
Extracts all unique edges from the triangular faces
Creates an undirected graph from these edges
Simplifies the graph to remove duplicate edges and loops
Calculates Euclidean distances between connected vertices
Adds vertex coordinates and edge distances as attributes to the graph
Note that the input nodes matrix should use 0-based indexing (starting from 0),
as the function will increment indices by 1 when creating the graph.
An igraph object representing the mesh connectivity. The graph has the following attributes:
Vertex attributes: "x", "y", and "z" coordinates from the vertices matrix
Edge attribute: "dist" (Euclidean distance between connected vertices)
SurfaceGeometry, graph_from_edgelist
# Create a simple cube mesh with 8 vertices vertices <- matrix(c( 0, 0, 0, # vertex 1 1, 0, 0, # vertex 2 1, 1, 0, # vertex 3 0, 1, 0, # vertex 4 0, 0, 1, # vertex 5 1, 0, 1, # vertex 6 1, 1, 1, # vertex 7 0, 1, 1 # vertex 8 ), ncol = 3, byrow = TRUE) # Define triangular faces with 0-based indices faces <- matrix(c( # bottom face (z=0) 0, 1, 2, 0, 2, 3, # top face (z=1) 4, 5, 6, 4, 6, 7, # front face (y=0) 0, 1, 5, 0, 5, 4, # back face (y=1) 2, 3, 7, 2, 7, 6, # left face (x=0) 0, 3, 7, 0, 7, 4, # right face (x=1) 1, 2, 6, 1, 6, 5 ), ncol = 3, byrow = TRUE) # Create the graph representation of the mesh graph <- meshToGraph(vertices, faces) # Examine the graph properties cat("Number of vertices:", igraph::vcount(graph), "\n") cat("Number of edges:", igraph::ecount(graph), "\n") # Plot the graph if igraph is available if (interactive() && requireNamespace("igraph", quietly = TRUE) && requireNamespace("rgl", quietly = TRUE)) { # First visualize the mesh rgl::open3d() mesh <- rgl::tmesh3d( vertices = t(vertices), indices = t(faces) + 1, # rgl uses 1-based indexing homogeneous = FALSE ) rgl::shade3d(mesh, col = "lightblue") rgl::title3d(main = "Original Mesh") # Visualize the graph connections using the 3D coordinates rgl::open3d() # Plot vertices rgl::points3d(vertices[,1], vertices[,2], vertices[,3], size = 10, col = "red") # Plot edges edges <- igraph::as_edgelist(graph) for (i in 1:nrow(edges)) { v1 <- edges[i, 1] v2 <- edges[i, 2] coords <- vertices[c(v1, v2), ] rgl::lines3d(coords[,1], coords[,2], coords[,3], col = "black", lwd = 2) } rgl::title3d(main = "Graph Representation") }# Create a simple cube mesh with 8 vertices vertices <- matrix(c( 0, 0, 0, # vertex 1 1, 0, 0, # vertex 2 1, 1, 0, # vertex 3 0, 1, 0, # vertex 4 0, 0, 1, # vertex 5 1, 0, 1, # vertex 6 1, 1, 1, # vertex 7 0, 1, 1 # vertex 8 ), ncol = 3, byrow = TRUE) # Define triangular faces with 0-based indices faces <- matrix(c( # bottom face (z=0) 0, 1, 2, 0, 2, 3, # top face (z=1) 4, 5, 6, 4, 6, 7, # front face (y=0) 0, 1, 5, 0, 5, 4, # back face (y=1) 2, 3, 7, 2, 7, 6, # left face (x=0) 0, 3, 7, 0, 7, 4, # right face (x=1) 1, 2, 6, 1, 6, 5 ), ncol = 3, byrow = TRUE) # Create the graph representation of the mesh graph <- meshToGraph(vertices, faces) # Examine the graph properties cat("Number of vertices:", igraph::vcount(graph), "\n") cat("Number of edges:", igraph::ecount(graph), "\n") # Plot the graph if igraph is available if (interactive() && requireNamespace("igraph", quietly = TRUE) && requireNamespace("rgl", quietly = TRUE)) { # First visualize the mesh rgl::open3d() mesh <- rgl::tmesh3d( vertices = t(vertices), indices = t(faces) + 1, # rgl uses 1-based indexing homogeneous = FALSE ) rgl::shade3d(mesh, col = "lightblue") rgl::title3d(main = "Original Mesh") # Visualize the graph connections using the 3D coordinates rgl::open3d() # Plot vertices rgl::points3d(vertices[,1], vertices[,2], vertices[,3], size = 10, col = "red") # Plot edges edges <- igraph::as_edgelist(graph) for (i in 1:nrow(edges)) { v1 <- edges[i, 1] v2 <- edges[i, 2] coords <- vertices[c(v1, v2), ] rgl::lines3d(coords[,1], coords[,2], coords[,3], col = "black", lwd = 2) } rgl::title3d(main = "Graph Representation") }
This generic function constructs a neighborhood graph from a surface mesh using edge weights. It allows for flexible definition of neighborhoods based on edge radius and custom edge weights.
neighbor_graph(x, radius, edgeWeights = missing(), nodes = missing(), ...) ## S4 method for signature 'igraph,numeric,missing,missing' neighbor_graph( x, radius, edgeWeights = NULL, nodes = NULL, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,missing,missing' neighbor_graph( x, radius, edgeWeights = NULL, nodes = NULL, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,numeric,missing' neighbor_graph( x, radius, edgeWeights, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,numeric,integer' neighbor_graph( x, radius, edgeWeights, nodes, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,missing,integer' neighbor_graph( x, radius, nodes, distance_type = c("geodesic", "euclidean", "spherical") )neighbor_graph(x, radius, edgeWeights = missing(), nodes = missing(), ...) ## S4 method for signature 'igraph,numeric,missing,missing' neighbor_graph( x, radius, edgeWeights = NULL, nodes = NULL, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,missing,missing' neighbor_graph( x, radius, edgeWeights = NULL, nodes = NULL, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,numeric,missing' neighbor_graph( x, radius, edgeWeights, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,numeric,integer' neighbor_graph( x, radius, edgeWeights, nodes, distance_type = c("geodesic", "euclidean", "spherical") ) ## S4 method for signature 'SurfaceGeometry,numeric,missing,integer' neighbor_graph( x, radius, nodes, distance_type = c("geodesic", "euclidean", "spherical") )
x |
An object representing a surface mesh. The specific class depends on the method implementation. |
radius |
Numeric. The edge radius defining the neighborhood extent. |
edgeWeights |
Numeric vector. Custom weights for edges, used to define edge distances. |
nodes |
Integer vector. The subset of nodes to use in graph construction. If NULL, all nodes are used. |
... |
Additional arguments passed to methods. |
distance_type |
the type of distance metric to use |
The neighborhood graph is constructed by considering edges within the specified radius and applying the provided edge weights. This function is particularly useful in neuroimaging analyses for defining local connectivity on brain surfaces.
An object representing the constructed neighborhood graph. The specific class depends on the method implementation.
geom <- example_surface_geometry() graph <- neighbor_graph(geom, radius = 1) igraph::vcount(graph) # Build a neighbor graph from a simple SurfaceGeometry geom <- example_surface_geometry() g_geom <- neighbor_graph(geom, radius = 1) igraph::vcount(g_geom)geom <- example_surface_geometry() graph <- neighbor_graph(geom, radius = 1) igraph::vcount(graph) # Build a neighbor graph from a simple SurfaceGeometry geom <- example_surface_geometry() g_geom <- neighbor_graph(geom, radius = 1) igraph::vcount(g_geom)
Data structures and IO for surface-based neuroimaging data.
Maintainer: Bradley R Buchsbaum [email protected] [copyright holder]
Useful links:
Report bugs at https://github.com/bbuchsbaum/neurosurf/issues
Downloads larger test data files that are not included in the CRAN package due to size constraints. These files are hosted on GitHub releases and are useful for running the full test suite or exploring additional file formats.
neurosurf_download_testdata( files = "all", destdir = NULL, overwrite = FALSE, quiet = FALSE )neurosurf_download_testdata( files = "all", destdir = NULL, overwrite = FALSE, quiet = FALSE )
files |
Character vector of files to download. Use
|
destdir |
Destination directory. Defaults to |
overwrite |
Logical; if |
quiet |
Logical; if |
The test data files are hosted on GitHub releases for the neurosurf package. This function requires an internet connection to download the files.
If you are running tests locally and want the full test suite, run
neurosurf_download_testdata("all") once after installing the package.
Invisibly returns the paths to downloaded files.
# Download all test data neurosurf_download_testdata("all") # Download only the GIFTI file neurosurf_download_testdata("rscan01_lh.gii")# Download all test data neurosurf_download_testdata("all") # Download only the GIFTI file neurosurf_download_testdata("rscan01_lh.gii")
This function creates a new NeuroSurface object, which represents a single set of data values associated with nodes on a surface geometry.
NeuroSurface(geometry, indices, data)NeuroSurface(geometry, indices, data)
geometry |
A |
indices |
An integer vector specifying the indices of valid surface nodes. |
data |
A numeric vector of data values corresponding to the surface nodes. |
The NeuroSurface object is designed to store and manipulate a single set of data values associated with nodes on a surface. This can represent various neuroimaging measures such as cortical thickness, functional activation, or any other node-wise metric.
The length of the data vector should match the length of the indices vector.
Nodes not included in the indices vector are considered to have no data or to be invalid.
A new object of class NeuroSurface containing:
geometry |
The input |
indices |
The input integer vector of valid node indices. |
data |
The input numeric vector of data values. |
SurfaceGeometry, NeuroSurfaceVector
surf_geom <- example_surface_geometry() indices <- seq_len(nrow(coords(surf_geom))) # all vertices data_values <- rnorm(length(indices)) # Example data neuro_surf <- NeuroSurface(surf_geom, indices, data_values)surf_geom <- example_surface_geometry() indices <- seq_len(nrow(coords(surf_geom))) # all vertices data_values <- rnorm(length(indices)) # Example data neuro_surf <- NeuroSurface(surf_geom, indices, data_values)
a three-dimensional surface consisting of a set of triangle vertices with one value per vertex.
The NeuroSurface class is a fundamental representation of surface-based neuroimaging data. It combines geometric information about a brain surface with data values mapped to each vertex of that surface.
The class consists of three core components:
geometry: The underlying 3D surface structure, containing vertex coordinates,
face definitions, and topological information
indices: Identifiers for the subset of vertices in the geometry that have
associated data values
data: A numeric vector containing one value per vertex, representing
measurements such as cortical thickness, functional activation, or any other
surface-mapped metric
This class serves as the foundation for more specialized surface representations like
ColorMappedNeuroSurface, VertexColoredNeuroSurface, and LabeledNeuroSurface.
It facilitates common operations such as visualization, statistical analysis, and spatial
processing of surface-based neuroimaging data.
An object of class NeuroSurface.
geometrythe surface geometry, an instance of SurfaceGeometry or SurfaceSet
indicesan integer vector specifying the subset of valid surface nodes encoded in the geometry object.
datathe 1-D vector of data value at each vertex of the mesh
# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(0.5, 1.2, 0.8, 1.5) # example values for the vertices # Create the NeuroSurface object neuro_surface <- new("NeuroSurface", geometry = geometry, indices = indices, data = vertex_data) # The data values are now mapped to the surface vertices # and can be visualized or analyzed# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create data values for each vertex vertex_data <- c(0.5, 1.2, 0.8, 1.5) # example values for the vertices # Create the NeuroSurface object neuro_surface <- new("NeuroSurface", geometry = geometry, indices = indices, data = vertex_data) # The data values are now mapped to the surface vertices # and can be visualized or analyzed
The 'NeuroSurfaceSource' class serves as a factory for creating
NeuroSurface instances. It encapsulates all necessary
information to construct a neuroimaging surface, including geometry,
metadata, and indexing information.
NeuroSurfaceSource( surface_geom, surface_data_name, colind = NULL, nodeind = NULL )NeuroSurfaceSource( surface_geom, surface_data_name, colind = NULL, nodeind = NULL )
surface_geom |
the name of the file containing the surface geometry or a |
surface_data_name |
the name of the file containing the data values to be mapped to the surface. |
colind |
the subset of column indices to load from surface data matrix (if provided) |
nodeind |
the subset of node indices to load from surface data matrix (if provided) |
This class is designed to facilitate the creation of NeuroSurface
objects by providing a standardized way to store and access all required components.
It combines geometric information, metadata, and indexing details necessary for
constructing a complete neuroimaging surface representation.
An object of class NeuroSurfaceSource or NeuroSurfaceVectorSource
that contains information about the surface geometry and associated data. If the data has multiple columns
(colind > 1), a NeuroSurfaceVectorSource is returned; otherwise, a NeuroSurfaceSource is returned.
These objects can be used to load and map neuroimaging data onto brain surfaces.
geometryAn object of class SurfaceGeometry
representing the underlying surface structure.
data_meta_infoAn object of class SurfaceDataMetaInfo
containing metadata about the surface data.
colindAn integer specifying the column index of the surface map to be loaded.
nodeindAn integer vector specifying the node indices of the surface map to be loaded.
NeuroSurface, SurfaceGeometry,
SurfaceDataMetaInfo
# Create a simple mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Create a SurfaceDataMetaInfo object data_meta_info <- new("SurfaceDataMetaInfo", header_file = "data_meta.txt", data_file = "surface_data.1D", file_descriptor = new("FileFormat"), node_count = 4L, nels = 1L, label = "thickness") # Create a NeuroSurfaceSource object neuro_source <- new("NeuroSurfaceSource", geometry = geometry, data_meta_info = data_meta_info, colind = 1L, nodeind = 1:4)# Create a simple mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Create a SurfaceDataMetaInfo object data_meta_info <- new("SurfaceDataMetaInfo", header_file = "data_meta.txt", data_file = "surface_data.1D", file_descriptor = new("FileFormat"), node_count = 4L, nels = 1L, label = "thickness") # Create a NeuroSurfaceSource object neuro_source <- new("NeuroSurfaceSource", geometry = geometry, data_meta_info = data_meta_info, colind = 1L, nodeind = 1:4)
construct a new NeuroSurfaceVector
NeuroSurfaceVector(geometry, indices, mat)NeuroSurfaceVector(geometry, indices, mat)
geometry |
a |
indices |
an integer vector specifying the valid surface nodes. |
mat |
a |
A NeuroSurfaceVector object containing the geometry, node indices, and data matrix.
Represents a 3D surface with multiple values per vertex.
The NeuroSurfaceVector class extends the concept of NeuroSurface to handle multiple measurements for each vertex across the entire surface. Unlike NeuroSurface which stores a single value per vertex, NeuroSurfaceVector stores a matrix of values where columns represent different measures and rows correspond to vertices.
This structure is particularly useful for:
Time series data where each column represents a different timepoint
Multi-modal data where each column represents a different imaging modality
Statistical results where columns represent different statistical parameters
Feature vectors for machine learning applications
The data matrix organization (vertices as rows, measures as columns) facilitates efficient vertex-wise operations and analyses. This is in contrast to ROISurfaceVector where the matrix is transposed (measures as rows, vertices as columns).
An object of class NeuroSurfaceVector
geometrySurfaceGeometry instance representing the surface structure
indicesInteger vector of valid surface node indices
dataMatrix of values, where columns represent different measures and rows correspond to surface nodes
The number of rows in 'data' must match the number of nodes in 'geometry'.
# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create a Matrix with multiple measures for each vertex # Each row corresponds to a vertex, each column to a different measure require(Matrix) vertex_data <- Matrix( c(0.5, 1.2, 0.8, # Measure 1 values for vertices 1-4 0.7, 0.3, 1.5, 0.9, # Measure 2 values for vertices 1-4 1.1, 0.6, 0.4, 1.3), # Measure 3 values for vertices 1-4 nrow = 4, ncol = 3, byrow = FALSE ) # Create the NeuroSurfaceVector object neuro_surface_vector <- new("NeuroSurfaceVector", geometry = geometry, indices = indices, data = vertex_data) # The data matrix now maps multiple values to each surface vertex # Vertex 1 has values: 0.5, 0.7, 1.1 # Vertex 2 has values: 1.2, 0.3, 0.6 # etc.# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create a Matrix with multiple measures for each vertex # Each row corresponds to a vertex, each column to a different measure require(Matrix) vertex_data <- Matrix( c(0.5, 1.2, 0.8, # Measure 1 values for vertices 1-4 0.7, 0.3, 1.5, 0.9, # Measure 2 values for vertices 1-4 1.1, 0.6, 0.4, 1.3), # Measure 3 values for vertices 1-4 nrow = 4, ncol = 3, byrow = FALSE ) # Create the NeuroSurfaceVector object neuro_surface_vector <- new("NeuroSurfaceVector", geometry = geometry, indices = indices, data = vertex_data) # The data matrix now maps multiple values to each surface vertex # Vertex 1 has values: 0.5, 0.7, 1.1 # Vertex 2 has values: 1.2, 0.3, 0.6 # etc.
A class that is used to produce a NeuroSurfaceVector instance
An object of class NeuroSurfaceVectorSource.
geometrya SurfaceGeometry instance
data_meta_infoa SurfaceDataMetaInfo instance
colindthe column indices vector of the surface maps to be loaded
This class contains meta information for surface-based data for the NIML data format
An object of class NIMLSurfaceDataMetaInfo.
datathe numeric data matrix of surface values (rows = nodes, columns=surface vectors)
node_indicesthe indices of the nodes for mapping to associated surface geometry.
meta_info <- new("SurfaceDataMetaInfo", header_file = "data_header.txt", data_file = "surface_data.niml.dset", file_descriptor = new("FileFormat"), node_count = length(nodes(geometry)), nels = 2L, label = "thickness") surface_data <- matrix(rnorm(meta_info@node_count * meta_info@nels), nrow = meta_info@node_count, ncol = meta_info@nels) niml_meta <- new("NIMLSurfaceDataMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, node_count = meta_info@node_count, nels = meta_info@nels, label = meta_info@label, data = surface_data, node_indices = seq_len(meta_info@node_count))meta_info <- new("SurfaceDataMetaInfo", header_file = "data_header.txt", data_file = "surface_data.niml.dset", file_descriptor = new("FileFormat"), node_count = length(nodes(geometry)), nels = 2L, label = "thickness") surface_data <- matrix(rnorm(meta_info@node_count * meta_info@nels), nrow = meta_info@node_count, ncol = meta_info@nels) niml_meta <- new("NIMLSurfaceDataMetaInfo", header_file = meta_info@header_file, data_file = meta_info@data_file, file_descriptor = meta_info@file_descriptor, node_count = meta_info@node_count, nels = meta_info@nels, label = meta_info@label, data = surface_data, node_indices = seq_len(meta_info@node_count))
This class supports the NIML file format for surface-based data
An object of class NIMLSurfaceFileDescriptor.
Retrieves the node numbers from a surface object.
nodes(x) ## S4 method for signature 'SurfaceGeometry' nodes(x) ## S4 method for signature 'NeuroSurface' nodes(x) ## S4 method for signature 'NeuroSurfaceVector' nodes(x)nodes(x) ## S4 method for signature 'SurfaceGeometry' nodes(x) ## S4 method for signature 'NeuroSurface' nodes(x) ## S4 method for signature 'NeuroSurfaceVector' nodes(x)
x |
An object representing a surface. |
A vector of node numbers.
geom <- example_surface_geometry() nodes(geom)geom <- example_surface_geometry() nodes(geom)
Parcel boundary contact matrix
parcel_boundary_contact( labeled_surface, component_policy = c("error", "largest", "each", "merge"), counts = FALSE )parcel_boundary_contact( labeled_surface, component_policy = c("error", "largest", "each", "merge"), counts = FALSE )
labeled_surface |
A |
component_policy |
Fragment handling policy. |
counts |
If TRUE, return edge counts; otherwise logical contact matrix. |
Matrix (logical or integer) indicating parcel-unit boundary contacts.
# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # contact <- parcel_boundary_contact(lsurf)# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # contact <- parcel_boundary_contact(lsurf)
Parcel centroids using geodesic medoids
parcel_geodesic_centroid( labeled_surface, method = c("medoid", "euclidean"), component_policy = c("error", "largest", "each", "merge"), weights = NULL, chunk_size = 2000, cache = TRUE )parcel_geodesic_centroid( labeled_surface, method = c("medoid", "euclidean"), component_policy = c("error", "largest", "each", "merge"), weights = NULL, chunk_size = 2000, cache = TRUE )
labeled_surface |
A |
method |
|
component_policy |
How to handle fragmented parcels:
|
weights |
Optional numeric edge weights (defaults to |
chunk_size |
Number of source vertices per Dijkstra batch. |
cache |
Logical; cache symmetric results when |
Data frame with one row per parcel unit:
unit, parcel_id, component, size,
centroid_vertex, and Cartesian coordinates.
# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # centroids <- parcel_geodesic_centroid(lsurf)# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # centroids <- parcel_geodesic_centroid(lsurf)
Parcel-to-parcel geodesic distances
parcel_geodesic_distance_matrix( labeled_surface, metric = c("centroid", "min"), component_policy = c("error", "largest", "each", "merge"), weights = NULL, chunk_size = 2000, cache = TRUE )parcel_geodesic_distance_matrix( labeled_surface, metric = c("centroid", "min"), component_policy = c("error", "largest", "each", "merge"), weights = NULL, chunk_size = 2000, cache = TRUE )
labeled_surface |
A |
metric |
|
component_policy |
Fragment handling policy. |
weights |
Optional numeric edge weights (defaults to |
chunk_size |
Number of source vertices per Dijkstra batch. |
cache |
Logical; cache symmetric results when |
A numeric matrix with parcel-unit names as dimnames.
# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # dmat <- parcel_geodesic_distance_matrix(lsurf)# Requires a LabeledNeuroSurface # lsurf <- read_freesurfer_annot("lh.aparc.annot", geom) # dmat <- parcel_geodesic_distance_matrix(lsurf)
Plot Surface as an HTMLWidget
plot_js(x, width = NULL, height = NULL, ...) ## S4 method for signature 'SurfaceGeometry' plot_js(x, width = NULL, height = NULL, ...)plot_js(x, width = NULL, height = NULL, ...) ## S4 method for signature 'SurfaceGeometry' plot_js(x, width = NULL, height = NULL, ...)
x |
Surface object to plot |
width |
The width of the widget (optional) |
height |
The height of the widget (optional) |
... |
Additional arguments passed to the plotting function |
An HTMLWidget object
geom <- example_surface_geometry() widget <- plot_js(geom)geom <- example_surface_geometry() widget <- plot_js(geom)
Renders a surface object using the interactive viewer.
## S4 method for signature 'SurfaceGeometry,missing' plot( x, vals = NA, cmap = grDevices::gray(seq(0, 1, length.out = 255)), vert_clrs = NULL, irange = range(vals), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'NeuroSurface,missing' plot( x, cmap = grDevices::gray(seq(0, 1, length.out = 255)), vert_clrs = NULL, irange = range(x@data, na.rm = TRUE), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'LabeledNeuroSurface,missing' plot( x, cmap = x@cols, vert_clrs = NULL, irange = range(x@data, na.rm = TRUE), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'ColorMappedNeuroSurface,missing' plot( x, vert_clrs = NULL, alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'VertexColoredNeuroSurface,missing' plot(x, alpha = 1, specular = "black", bgcol = "lightgray", ...)## S4 method for signature 'SurfaceGeometry,missing' plot( x, vals = NA, cmap = grDevices::gray(seq(0, 1, length.out = 255)), vert_clrs = NULL, irange = range(vals), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'NeuroSurface,missing' plot( x, cmap = grDevices::gray(seq(0, 1, length.out = 255)), vert_clrs = NULL, irange = range(x@data, na.rm = TRUE), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'LabeledNeuroSurface,missing' plot( x, cmap = x@cols, vert_clrs = NULL, irange = range(x@data, na.rm = TRUE), thresh = c(0, 0), alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'ColorMappedNeuroSurface,missing' plot( x, vert_clrs = NULL, alpha = 1, specular = "black", bgcol = "lightgray", ... ) ## S4 method for signature 'VertexColoredNeuroSurface,missing' plot(x, alpha = 1, specular = "black", bgcol = "lightgray", ...)
x |
the surface to plot |
vals |
An optional numeric vector containing data values for each vertex on the surface. If provided and 'vert_clrs' is NULL, these values are mapped to colors using 'cmap' and 'irange'. |
cmap |
A vector of colors (e.g., hex codes) defining the color map used when 'vals' is provided and 'vert_clrs' is NULL. Defaults to 'rainbow(256)'. |
vert_clrs |
An optional character vector of hex color codes for each vertex. If provided, these colors directly override any coloring derived from 'vals' and 'cmap'. The length should match the number of vertices in 'surfgeom'. |
irange |
An optional numeric vector of length 2, 'c(min, max)'. Specifies the range of 'vals' to map onto the 'cmap'. Values outside this range will be clamped to the min/max colors. Defaults to the full range of 'vals'. |
thresh |
An optional numeric vector of length 2, 'c(lower, upper)'. Vertices with 'vals' *outside* this range (i.e., '< lower' or '> upper') are made fully transparent. This is applied *after* the general 'alpha'. Defaults to NULL (no thresholding). |
alpha |
A numeric value between 0 (fully transparent) and 1 (fully opaque) controlling the overall transparency of the surface. Defaults to 1. |
specular |
The color of specular highlights on the surface, affecting its shininess. Can be a color name (e.g., "white") or hex code. Defaults to "black" for a matte look. Set to a brighter colour for a glossier appearance. |
bgcol |
A single hex color code or a vector of hex color codes used as the base color for the surface. If 'vals' or 'vert_clrs' are provided, this color is blended with the data/vertex colors. Defaults to "lightgray". |
... |
extra args to send to |
An htmlwidget object for interactive visualization
This is a convenience wrapper that renders a multi-panel surface layout and draws it to a new grid device.
## S3 method for class 'neurosurf_plot' plot(x, ...)## S3 method for class 'neurosurf_plot' plot(x, ...)
x |
A |
... |
Additional arguments passed to |
Invisibly returns the input neurosurf_plot object.
Plot method for SurfaceGeometry objects
## S3 method for class 'SurfaceGeometry' plot(x, y, ...)## S3 method for class 'SurfaceGeometry' plot(x, y, ...)
x |
A |
y |
Ignored (for S3 method compatibility). |
... |
Additional arguments passed to |
Invisibly returns the object ID(s) from the RGL scene.
geom <- example_surface_geometry() if (interactive()) { plot(geom) }geom <- example_surface_geometry() if (interactive()) { plot(geom) }
Plot method for SurfaceSet objects
## S3 method for class 'SurfaceSet' plot(x, y, label = NULL, ...)## S3 method for class 'SurfaceSet' plot(x, y, label = NULL, ...)
x |
A |
y |
Ignored (for S3 compatibility). |
label |
Optional surface label to display; defaults to the set's default. |
... |
Additional arguments passed to |
Invisibly returns the object ID(s) from the RGL scene.
geom <- example_surface_geometry() ss <- surface_set(inflated = geom) if (interactive()) { plot(ss) }geom <- example_surface_geometry() ss <- surface_set(inflated = geom) if (interactive()) { plot(ss) }
Print Method for Searchlight Iterator
## S3 method for class 'Searchlight' print(x, ...)## S3 method for class 'Searchlight' print(x, ...)
x |
An object of class "Searchlight" |
... |
Additional arguments (not used) |
Invisibly returns the Searchlight object (called for side effect).
This function projects a set of 3D coordinates onto a given surface and creates a NeuroSurface object with the smoothed values.
The projection is performed by finding the closest points on the surface, and then a kernel density smoother is applied locally to produce the final values.
projectCoordinates(surfgeom, points, sigma = 5, ...)projectCoordinates(surfgeom, points, sigma = 5, ...)
surfgeom |
A |
points |
A numeric matrix with three columns (x, y, z) representing the 3D coordinates to be projected onto the surface. |
sigma |
A numeric value specifying the smoothing radius for the kernel density smoother. Default is 5. |
... |
Additional arguments passed to the smoothing function. |
The function first projects each 3D coordinate onto the closest point on the surface defined by surfgeom.
The values at these projected points are then smoothed using a kernel density smoother, where the sigma parameter controls the extent of the smoothing.
The result is a NeuroSurface object containing the smoothed values, suitable for further analysis or visualization.
A NeuroSurface object with the smoothed values mapped onto the surface.
# Load a sample surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surfgeom <- read_surf_geometry(surf_file) # Get the surface coordinates surf_coords <- coords(surfgeom) # Create some sample 3D coordinates to project # We'll use a subset of the surface vertices with small random offsets set.seed(123) sample_indices <- sample(1:nrow(surf_coords), 50) sample_coords <- surf_coords[sample_indices, ] + matrix(rnorm(150, 0, 0.5), ncol = 3) # Project these coordinates onto the surface projected_surface <- projectCoordinates(surfgeom, sample_coords, sigma = 3) # Check the result vals <- series(projected_surface, indices(projected_surface)) max(vals) # Maximum density value sum(vals > 0) # Number of vertices with non-zero values# Load a sample surface from the package surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surfgeom <- read_surf_geometry(surf_file) # Get the surface coordinates surf_coords <- coords(surfgeom) # Create some sample 3D coordinates to project # We'll use a subset of the surface vertices with small random offsets set.seed(123) sample_indices <- sample(1:nrow(surf_coords), 50) sample_coords <- surf_coords[sample_indices, ] + matrix(rnorm(150, 0, 0.5), ncol = 3) # Project these coordinates onto the surface projected_surface <- projectCoordinates(surfgeom, sample_coords, sigma = 3) # Check the result vals <- series(projected_surface, indices(projected_surface)) max(vals) # Maximum density value sum(vals > 0) # Number of vertices with non-zero values
Creates an iterator that randomly samples searchlight regions on a surface mesh using geodesic distance to define regions.
RandomSurfaceSearchlight( surfgeom, radius = 8, nodeset = NULL, as_deflist = FALSE )RandomSurfaceSearchlight( surfgeom, radius = 8, nodeset = NULL, as_deflist = FALSE )
surfgeom |
A |
radius |
Numeric, radius of the searchlight as a geodesic distance in mm. Must be a positive numeric scalar. |
nodeset |
Integer vector, optional subset of surface node indices to use. If supplied, must contain more than one index. |
as_deflist |
Logical, whether to return a deflist object. |
On each call to nextElem, a set of surface nodes is returned.
These nodes index into the vertices of the igraph instance.
When as_deflist=TRUE, the random ordering of centers is fixed when the
object is created. Use set.seed before construction for reproducible
sequences.
An iterator object of class "RandomSurfaceSearchlight".
file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") geom <- read_surf(file) searchlight <- RandomSurfaceSearchlight(geom, 12) set.seed(42) dl <- RandomSurfaceSearchlight(geom, 12, as_deflist=TRUE) attr(dl[[1]], "center") nodes <- searchlight$nextElem() length(nodes) > 1file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") geom <- read_surf(file) searchlight <- RandomSurfaceSearchlight(geom, 12) set.seed(42) dl <- RandomSurfaceSearchlight(geom, 12, as_deflist=TRUE) attr(dl[[1]], "center") nodes <- searchlight$nextElem() length(nodes) > 1
Reads a Freesurfer annotation file and creates a LabeledNeuroSurface object.
read_freesurfer_annot(file_name, geometry)read_freesurfer_annot(file_name, geometry)
file_name |
Character string; path to the '.annot' file |
geometry |
A SurfaceGeometry object representing the surface structure |
This function reads binary data from a FreeSurfer annotation file, which includes vertex labels, color information, and label names. It then constructs a LabeledNeuroSurface object using this information along with the provided surface geometry.
A LabeledNeuroSurface object containing:
indices |
Integer vector of vertex indices |
data |
Numeric vector of label codes |
labels |
Character vector of label names |
cols |
Character vector of label colors in hex format |
# Read a FreeSurfer annotation file (requires actual annotation file) geom <- example_surface_geometry() # labeled_surface <- read_freesurfer_annot("lh.aparc.annot", geom)# Read a FreeSurfer annotation file (requires actual annotation file) geom <- example_surface_geometry() # labeled_surface <- read_freesurfer_annot("lh.aparc.annot", geom)
Generic function to read image meta info given a file and a
FileFormat instance from neuroim2.
## S4 method for signature 'AFNISurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'NIMLSurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'FreesurferAsciiSurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'FreesurferBinarySurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'GIFTISurfaceFileDescriptor' read_meta_info(x, file_name)## S4 method for signature 'AFNISurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'NIMLSurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'FreesurferAsciiSurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'FreesurferBinarySurfaceFileDescriptor' read_meta_info(x, file_name) ## S4 method for signature 'GIFTISurfaceFileDescriptor' read_meta_info(x, file_name)
x |
the file descriptor object |
file_name |
the name of the file containing meta information. |
A meta info object containing header information from the surface file
A metadata information object describing the surface file structure
This function reads surface data from a file in one of the supported formats.
read_surf( surface_name, surface_data_name = NULL, colind = NULL, nodeind = NULL )read_surf( surface_name, surface_data_name = NULL, colind = NULL, nodeind = NULL )
surface_name |
the name of the file containing the surface geometry. |
surface_data_name |
the name of the file containing the values to be mapped to the surface (optional). |
colind |
the columns/samples to load (optional), only if |
nodeind |
the subset of node indices to load |
The function supports reading surface data from various formats including:
Freesurfer ASCII (.asc)
Freesurfer binary
GIFTI (.gii)
NIML Surface Dataset (.niml.dset)
The format is determined automatically from the file extension.
an instance of the class:
SurfaceGeometry
or NeuroSurface
or NeuroSurfaceVector
# Find the path to the example surface file in the package surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") # Check if the file exists if (file.exists(surf_file)) { # Read the surface geometry (returns SurfaceGeometry for geometry-only files) surf <- read_surf(surf_file) # Display basic information about the surface print(surf) # Get vertex coordinates head(coords(surf)) }# Find the path to the example surface file in the package surf_file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") # Check if the file exists if (file.exists(surf_file)) { # Read the surface geometry (returns SurfaceGeometry for geometry-only files) surf <- read_surf(surf_file) # Display basic information about the surface print(surf) # Get vertex coordinates head(coords(surf)) }
SurfaceGeometry
load surface data and link to SurfaceGeometry
read_surf_data(geometry, surface_data_name, colind = NULL, nodeind = NULL)read_surf_data(geometry, surface_data_name, colind = NULL, nodeind = NULL)
geometry |
a |
surface_data_name |
the name of the file containing the values to be mapped to the surface. |
colind |
the subset column indices of surface dataset to load (optional) |
nodeind |
the subset node indices of surface dataset to include (optional) |
an instance of the class NeuroSurface or NeuroSurfaceVector
# Load geometry and surface data file # geom <- read_surf_geometry("lh.white") # surf_data <- read_surf_data(geom, "lh.thickness")# Load geometry and surface data file # geom <- read_surf_geometry("lh.white") # surf_data <- read_surf_data(geom, "lh.thickness")
Load one or more surface datasets for both left and right hemispheres.
read_surf_data_seq(leftGeometry, rightGeometry, leftDataNames, rightDataNames)read_surf_data_seq(leftGeometry, rightGeometry, leftDataNames, rightDataNames)
leftGeometry |
a |
rightGeometry |
a |
leftDataNames |
a |
rightDataNames |
a |
A list of BilatNeuroSurfaceVector objects, one per pair of data files
This function loads a supported surface geometry from a file and returns a SurfaceGeometry object.
read_surf_geometry(surface_name)read_surf_geometry(surface_name)
surface_name |
A character string specifying the name of the file containing the surface geometry. |
This function supports loading surface geometries from the following file formats:
Freesurfer ASCII (.asc)
Freesurfer binary
GIFTI (.gii)
The appropriate loader is automatically selected based on the file extension or content.
A SurfaceGeometry object representing the loaded surface.
asc_path <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") lh_surface <- read_surf_geometry(asc_path)asc_path <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") lh_surface <- read_surf_geometry(asc_path)
This function applies uniform remeshing to a SurfaceGeometry object, creating a new mesh with more regular face sizes and improved quality.
remeshSurface(surfgeom, voxel_size = 2, ...)remeshSurface(surfgeom, voxel_size = 2, ...)
surfgeom |
A |
voxel_size |
Numeric value specifying the target edge length in the remeshed output. Smaller values create finer meshes with more faces. |
... |
Additional arguments to pass to |
Remeshing is a process that reconstructs the mesh to improve its quality and/or adjust its resolution. Uniform remeshing creates a new mesh where the edge lengths are approximately equal throughout the surface, which is often desirable for analysis and visualization.
The voxel_size parameter controls the resolution of the output mesh:
Smaller values create denser meshes with more vertices and faces
Larger values create coarser meshes with fewer vertices and faces
Common reasons to remesh a surface include:
Simplifying high-resolution meshes for faster processing
Creating more uniform triangle sizes for better numerical stability
Preparing meshes for specific analyses that require regular structures
Fixing mesh defects and improving the overall quality
This function uses the VCG library (via the Rvcg package) to perform the remeshing operation, which is a robust and widely-used algorithm for mesh processing.
A new SurfaceGeometry object with the remeshed surface.
SurfaceGeometry, vcgUniformRemesh
# Create a simple cube mesh vertices <- matrix(c( 0, 0, 0, # vertex 1 1, 0, 0, # vertex 2 1, 1, 0, # vertex 3 0, 1, 0, # vertex 4 0, 0, 1, # vertex 5 1, 0, 1, # vertex 6 1, 1, 1, # vertex 7 0, 1, 1 # vertex 8 ), ncol = 3, byrow = TRUE) # Define faces (12 triangular faces making a cube) # Note indices are 0-based faces <- matrix(c( # bottom face (z=0) 0, 1, 2, 0, 2, 3, # top face (z=1) 4, 5, 6, 4, 6, 7, # front face (y=0) 0, 1, 5, 0, 5, 4, # back face (y=1) 2, 3, 7, 2, 7, 6, # left face (x=0) 0, 3, 7, 0, 7, 4, # right face (x=1) 1, 2, 6, 1, 6, 5 ), ncol = 3, byrow = TRUE) # Create the SurfaceGeometry object surf_geom <- SurfaceGeometry(vertices, faces, "lh") # Remesh with a coarse voxel size - fewer triangles coarse_remesh <- remeshSurface(surf_geom, voxel_size = 0.5) # Remesh with a fine voxel size - more triangles fine_remesh <- remeshSurface(surf_geom, voxel_size = 0.2) # Visualize the meshes if rgl is available if(interactive() && requireNamespace("rgl", quietly = TRUE)) { # Original mesh rgl::open3d() rgl::shade3d(surf_geom@mesh, col = "red") rgl::title3d(main = "Original Mesh") # Coarse remesh rgl::open3d() rgl::shade3d(coarse_remesh@mesh, col = "green") rgl::title3d(main = "Coarse Remesh (voxel_size = 0.5)") # Fine remesh rgl::open3d() rgl::shade3d(fine_remesh@mesh, col = "blue") rgl::title3d(main = "Fine Remesh (voxel_size = 0.2)") # Compare the number of faces in each mesh cat("Original mesh faces:", ncol(surf_geom@mesh$it), "\n") cat("Coarse remesh faces:", ncol(coarse_remesh@mesh$it), "\n") cat("Fine remesh faces:", ncol(fine_remesh@mesh$it), "\n") }# Create a simple cube mesh vertices <- matrix(c( 0, 0, 0, # vertex 1 1, 0, 0, # vertex 2 1, 1, 0, # vertex 3 0, 1, 0, # vertex 4 0, 0, 1, # vertex 5 1, 0, 1, # vertex 6 1, 1, 1, # vertex 7 0, 1, 1 # vertex 8 ), ncol = 3, byrow = TRUE) # Define faces (12 triangular faces making a cube) # Note indices are 0-based faces <- matrix(c( # bottom face (z=0) 0, 1, 2, 0, 2, 3, # top face (z=1) 4, 5, 6, 4, 6, 7, # front face (y=0) 0, 1, 5, 0, 5, 4, # back face (y=1) 2, 3, 7, 2, 7, 6, # left face (x=0) 0, 3, 7, 0, 7, 4, # right face (x=1) 1, 2, 6, 1, 6, 5 ), ncol = 3, byrow = TRUE) # Create the SurfaceGeometry object surf_geom <- SurfaceGeometry(vertices, faces, "lh") # Remesh with a coarse voxel size - fewer triangles coarse_remesh <- remeshSurface(surf_geom, voxel_size = 0.5) # Remesh with a fine voxel size - more triangles fine_remesh <- remeshSurface(surf_geom, voxel_size = 0.2) # Visualize the meshes if rgl is available if(interactive() && requireNamespace("rgl", quietly = TRUE)) { # Original mesh rgl::open3d() rgl::shade3d(surf_geom@mesh, col = "red") rgl::title3d(main = "Original Mesh") # Coarse remesh rgl::open3d() rgl::shade3d(coarse_remesh@mesh, col = "green") rgl::title3d(main = "Coarse Remesh (voxel_size = 0.5)") # Fine remesh rgl::open3d() rgl::shade3d(fine_remesh@mesh, col = "blue") rgl::title3d(main = "Fine Remesh (voxel_size = 0.2)") # Compare the number of faces in each mesh cat("Original mesh faces:", ncol(surf_geom@mesh$it), "\n") cat("Coarse remesh faces:", ncol(coarse_remesh@mesh$it), "\n") cat("Fine remesh faces:", ncol(fine_remesh@mesh$it), "\n") }
Render a neurosurf plot using rgl
render_surface_plot(x, offscreen = TRUE, scale = c(2, 2), crop = TRUE)render_surface_plot(x, offscreen = TRUE, scale = c(2, 2), crop = TRUE)
x |
A |
offscreen |
Logical; if |
scale |
Numeric vector of length 2 giving a supersampling factor for
the offscreen snapshot. Values above 1 render at higher resolution before
downscaling for smoother edges. Defaults to |
crop |
Logical; if |
A list containing rendered panel images (with aspect ratios) and layout information. This is a low-level helper intended to be wrapped by higher-level figure drawing utilities.
surface_plot, add_surface_layer,
view_surface
geom <- example_surface_geometry() p <- surface_plot(geom) if (interactive()) { rendered <- render_surface_plot(p) }geom <- example_surface_geometry() p <- surface_plot(geom) if (interactive()) { rendered <- render_surface_plot(p) }
Get Right Hemisphere
right(x) ## S4 method for signature 'BilatNeuroSurfaceVector' right(x)right(x) ## S4 method for signature 'BilatNeuroSurfaceVector' right(x)
x |
Surface object |
Right hemisphere of the surface
# Requires bilateral surface data # rh <- right(bilat_surface)# Requires bilateral surface data # rh <- right(bilat_surface)
ROISurface
Create an instance of class ROISurface
ROISurface(geometry, indices, data)ROISurface(geometry, indices, data)
geometry |
the parent geometry: an instance of class |
indices |
the parent surface indices |
data |
the data values, numeric |
an instance of class ROISurface
verts <- matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, byrow=TRUE) faces <- matrix(c(0L,1L,2L), ncol=3, byrow=TRUE) geom <- SurfaceGeometry(verts, faces, "lh") ROISurface(geom, 1L, 1) try(ROISurface(geom, 4L, 1)) # out of range try(ROISurface(geom, 1.5, 1)) # non-integerverts <- matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, byrow=TRUE) faces <- matrix(c(0L,1L,2L), ncol=3, byrow=TRUE) geom <- SurfaceGeometry(verts, faces, "lh") ROISurface(geom, 1L, 1) try(ROISurface(geom, 4L, 1)) # out of range try(ROISurface(geom, 1.5, 1)) # non-integer
A class that represents a surface-based region of interest
The ROISurface class provides a way to represent a specific subset of vertices on a brain surface along with their associated data values. This is particularly useful for analyzing or visualizing specific anatomical or functional regions on the cortical surface.
The class maintains a reference to the complete parent surface geometry while storing
only the relevant subset of vertices, their coordinates, and their data values. The
indices slot allows mapping back to the original vertex indices in the parent
surface.
Typical use cases include:
Extracting and analyzing data from anatomical regions of interest
Working with functional clusters identified in analyses
Isolating specific surface features for detailed investigation
Statistical analysis of data within defined surface regions
An object of class ROISurface.
geometrythe geometry of the parent surface: a SurfaceGeometry instance
datathe vector-valued numeric data stored in ROI
coordsthe surface-based coordinates of the data
indicesthe node indices of the parent surface stored in the geometry field.
# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define the ROI - just using vertices 1 and 2 as an example roi_indices <- c(1L, 2L) # Extract coordinates for these vertices roi_coords <- matrix( c(0, 0, 0, # coordinates for vertex 1 1, 0, 0), # coordinates for vertex 2 ncol = 3, byrow = TRUE ) # Create data values for the ROI vertices roi_data <- c(0.75, 1.25) # example values for the two vertices # Create the ROISurface object roi <- new("ROISurface", geometry = geometry, data = roi_data, coords = roi_coords, indices = roi_indices)# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define the ROI - just using vertices 1 and 2 as an example roi_indices <- c(1L, 2L) # Extract coordinates for these vertices roi_coords <- matrix( c(0, 0, 0, # coordinates for vertex 1 1, 0, 0), # coordinates for vertex 2 ncol = 3, byrow = TRUE ) # Create data values for the ROI vertices roi_data <- c(0.75, 1.25) # example values for the two vertices # Create the ROISurface object roi <- new("ROISurface", geometry = geometry, data = roi_data, coords = roi_coords, indices = roi_indices)
ROISurfaceVector
Create an instance of class ROISurfaceVector
ROISurfaceVector(geometry, indices, data)ROISurfaceVector(geometry, indices, data)
geometry |
the parent geometry: an instance of class |
indices |
the parent surface indices |
data |
the data values, a |
an instance of class ROISurfaceVector
verts <- matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, byrow=TRUE) faces <- matrix(c(0L,1L,2L), ncol=3, byrow=TRUE) geom <- SurfaceGeometry(verts, faces, "lh") vec <- matrix(c(0.5, 1.5), nrow=1) ROISurfaceVector(geom, c(1L,2L), vec) try(ROISurfaceVector(geom, c(1L,4L), vec)) # out of range try(ROISurfaceVector(geom, c(1,2.5), vec)) # non-integerverts <- matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, byrow=TRUE) faces <- matrix(c(0L,1L,2L), ncol=3, byrow=TRUE) geom <- SurfaceGeometry(verts, faces, "lh") vec <- matrix(c(0.5, 1.5), nrow=1) ROISurfaceVector(geom, c(1L,2L), vec) try(ROISurfaceVector(geom, c(1L,4L), vec)) # out of range try(ROISurfaceVector(geom, c(1,2.5), vec)) # non-integer
A class that represents a surface-based region of interest
The ROISurfaceVector class extends the concept of ROISurface to handle multiple measurements for each vertex in the region of interest. While ROISurface stores a single value per vertex, ROISurfaceVector stores a matrix of values where each row represents a different measure and each column corresponds to a vertex.
This structure is particularly useful for multivariate analyses of specific brain regions, allowing researchers to:
Store time series data for each vertex in an ROI
Maintain multiple modalities of data for the same surface region
Perform multivariate statistical analyses on regional surface data
Compare different metrics within the same anatomical region
The data matrix is organized with rows representing different measures and columns representing different vertices, which facilitates efficient access to all measurements for a particular vertex or all vertices for a particular measurement.
An object of class ROISurfaceVector.
geometrythe geometry of the parent surface: a SurfaceGeometry instance
datamatrix data stored in ROI with number of columns equal to number of coordinates in ROI.
coordsthe surface-based coordinates of the data
indicesthe nodes of the parent surface stored in the geometry field.
# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define the ROI - just using vertices 1 and 2 as an example roi_indices <- c(1L, 2L) # Extract coordinates for these vertices roi_coords <- matrix( c(0, 0, 0, # coordinates for vertex 1 1, 0, 0), # coordinates for vertex 2 ncol = 3, byrow = TRUE ) # Create data matrix for the ROI vertices - 3 different measures # Each row represents a different measure, each column a different vertex roi_data <- matrix( c(0.75, 1.25, # values for measure 1 0.50, 0.80, # values for measure 2 0.30, 0.60), # values for measure 3 nrow = 3, ncol = 2 ) # Create the ROISurfaceVector object roi_vector <- new("ROISurfaceVector", geometry = geometry, data = roi_data, coords = roi_coords, indices = roi_indices)# Create a simple tetrahedron mesh for the example vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define the ROI - just using vertices 1 and 2 as an example roi_indices <- c(1L, 2L) # Extract coordinates for these vertices roi_coords <- matrix( c(0, 0, 0, # coordinates for vertex 1 1, 0, 0), # coordinates for vertex 2 ncol = 3, byrow = TRUE ) # Create data matrix for the ROI vertices - 3 different measures # Each row represents a different measure, each column a different vertex roi_data <- matrix( c(0.75, 1.25, # values for measure 1 0.50, 0.80, # values for measure 2 0.30, 0.60), # values for measure 3 nrow = 3, ncol = 2 ) # Create the ROISurfaceVector object roi_vector <- new("ROISurfaceVector", geometry = geometry, data = roi_data, coords = roi_coords, indices = roi_indices)
Converts a precomputed 'surface_sampler' into sparse matrix triplet format (i, j, x) suitable for constructing a dgCMatrix or for interop with other packages (e.g., neurofunctor). The triplets represent a vertices × voxels projection matrix with normalized Gaussian weights.
sampler_to_triplets( sampler, sigma = NULL, normalize = TRUE, min_weight = 1e-10 )sampler_to_triplets( sampler, sigma = NULL, normalize = TRUE, min_weight = 1e-10 )
sampler |
A sampler object returned by |
sigma |
Bandwidth for Gaussian kernel weights. If NULL, uses the default from the sampler's dthresh (dthresh/2). |
normalize |
Logical; if TRUE (default), weights for each vertex sum to 1. |
min_weight |
Minimum weight threshold; entries below this are dropped. Default is 1e-10 to remove numerical noise. |
The output triplets define a sparse matrix P where P[i,j] is the weight
for vertex i from voxel j. The actual volume voxel index is
voxel_indices[j]. To construct a dgCMatrix in R:
Matrix::sparseMatrix(i = triplets$i, j = triplets$j, x = triplets$x,
dims = triplets$dims)
A list with class "vol2surf_triplets" containing:
Integer vector of vertex indices (1-based row indices)
Integer vector of voxel indices (1-based column indices into the volume's linear index space, corresponding to sampler$indices)
Numeric vector of weights
Integer vector c(n_vertices, n_voxels) for matrix dimensions
The sampler$indices mapping j values to volume positions
Number of surface vertices
Number of candidate voxels
Number of non-zero entries
List of parameters used (sigma, normalize, min_weight, dthresh)
surface_sampler, apply_surface_sampler
# Requires a surface sampler # sampler <- surface_sampler(wm, pial, template_vol) # triplets <- sampler_to_triplets(sampler)# Requires a surface sampler # sampler <- surface_sampler(wm, pial, template_vol) # triplets <- sampler_to_triplets(sampler)
Extracts time series data from a region of interest in a surface vector.
## S4 method for signature 'NeuroSurfaceVector,numeric' series_roi(x, i) ## S4 method for signature 'NeuroSurfaceVector,ROISurface' series_roi(x, i)## S4 method for signature 'NeuroSurfaceVector,numeric' series_roi(x, i) ## S4 method for signature 'NeuroSurfaceVector,ROISurface' series_roi(x, i)
x |
the object to extract the series from |
i |
the indices of the series to extract |
An ROISurfaceVector containing the extracted time series
Extracts time series data from specific vertices in a surface vector.
## S4 method for signature 'NeuroSurfaceVector,numeric' series(x, i) ## S4 method for signature 'NeuroSurfaceVector,integer' series(x, i) ## S4 method for signature 'NeuroSurfaceVector,ROISurface' series(x, i) ## S4 method for signature 'NeuroSurface,numeric' series(x, i)## S4 method for signature 'NeuroSurfaceVector,numeric' series(x, i) ## S4 method for signature 'NeuroSurfaceVector,integer' series(x, i) ## S4 method for signature 'NeuroSurfaceVector,ROISurface' series(x, i) ## S4 method for signature 'NeuroSurface,numeric' series(x, i)
x |
the object to extract the series from |
i |
the indices of the series to extract |
A matrix where columns are time points and rows are vertex indices
This is a convenience wrapper around surface_plot,
add_surface_layer, and plot.neurosurf_plot.
It is intended for quick inspection and simple publication-style plots.
show_surface_plot( lh, rh = NULL, data = NULL, views = c("lateral", "medial"), layout = c("grid", "row", "column"), cmap = "viridis", irange = NULL, color_range = NULL, thresh = NULL, show_colorbar = TRUE, outline = FALSE, file = NULL, width = 1200, height = 900, ... )show_surface_plot( lh, rh = NULL, data = NULL, views = c("lateral", "medial"), layout = c("grid", "row", "column"), cmap = "viridis", irange = NULL, color_range = NULL, thresh = NULL, show_colorbar = TRUE, outline = FALSE, file = NULL, width = 1200, height = 900, ... )
lh, rh
|
Either |
data |
Optional numeric vector or list of vectors containing
vertex-wise data to plot. If a single numeric vector is supplied, it is
split across hemispheres in left-to-right order based on the vertex
counts of the surfaces. If |
views |
Character vector of named views to display for each hemisphere.
See |
layout |
One of |
cmap |
Character string naming a colour map for the data layer. |
irange |
Optional numeric vector of length 2 giving the minimum and
maximum values for the colour scale. Alias for |
color_range |
Optional numeric vector of length 2 giving the minimum and maximum values for the colour scale. |
thresh |
Optional numeric threshold band. A length-2 value is passed to
the colour mapper as |
show_colorbar |
Logical; if |
outline |
Logical; if |
file |
Optional PNG output path. If supplied, the plot is drawn to this file instead of the active graphics device. |
width, height
|
Pixel dimensions used when |
... |
Additional arguments passed through to |
Invisibly returns the underlying "neurosurf_plot" object.
The plot is drawn as a side-effect.
geom <- example_surface_geometry() if (interactive()) { show_surface_plot(geom, data = rnorm(nrow(coords(geom)))) }geom <- example_surface_geometry() if (interactive()) { show_surface_plot(geom, data = rnorm(nrow(coords(geom)))) }
This is a convenience wrapper around surfwidget for quick,
interactive inspection of a single surface. It returns an HTML widget that
can be used in R Markdown documents or Shiny applications.
show_surface_widget(x, data = NULL, ...)show_surface_widget(x, data = NULL, ...)
x |
A |
data |
Optional numeric vector of data values for each vertex when
|
... |
Additional arguments passed on to |
An htmlwidget object.
fs <- load_fsaverage_std8("inflated") show_surface_widget(fs$lh)fs <- load_fsaverage_std8("inflated") show_surface_widget(fs$lh)
Prints a human-readable summary of surface objects to the console.
## S4 method for signature 'SurfaceGeometryMetaInfo' show(object) ## S4 method for signature 'SurfaceDataMetaInfo' show(object) ## S4 method for signature 'ROISurface' show(object) ## S4 method for signature 'SurfaceGeometry' show(object) ## S4 method for signature 'NeuroSurfaceVector' show(object) ## S4 method for signature 'NeuroSurface' show(object)## S4 method for signature 'SurfaceGeometryMetaInfo' show(object) ## S4 method for signature 'SurfaceDataMetaInfo' show(object) ## S4 method for signature 'ROISurface' show(object) ## S4 method for signature 'SurfaceGeometry' show(object) ## S4 method for signature 'NeuroSurfaceVector' show(object) ## S4 method for signature 'NeuroSurface' show(object)
object |
The surface object to display |
Invisibly returns NULL. Called for its side effect of printing.
The smooth function is a generic function designed to apply smoothing operations to various surface objects. The specific behavior of the function depends on the class of the object passed as the x argument. It can be used to smooth the geometry of a surface, the data associated with a surface, or other related operations depending on the method implemented for the object's class.
This method applies smoothing to a brain surface geometry object of class SurfaceGeometry using various algorithms. Smoothing is useful for removing noise and creating a more continuous surface.
smooth(x, ...) ## S4 method for signature 'SurfaceGeometry' smooth( x, type = c("taubin", "laplace", "HClaplace", "fujiLaplace", "angWeight", "surfPreserveLaplace"), lambda = 0.7, mu = -0.53, delta = 0.1, iteration = 5 )smooth(x, ...) ## S4 method for signature 'SurfaceGeometry' smooth( x, type = c("taubin", "laplace", "HClaplace", "fujiLaplace", "angWeight", "surfPreserveLaplace"), lambda = 0.7, mu = -0.53, delta = 0.1, iteration = 5 )
x |
A |
... |
Additional arguments passed to the specific method for smoothing the surface object. |
type |
A character string specifying the smoothing algorithm to use. Available options are:
|
lambda |
A numeric value that controls the amount of smoothing. Higher values lead to more aggressive smoothing. This parameter is particularly relevant for Taubin and Laplacian smoothing methods. |
mu |
A numeric value used in Taubin smoothing to control shrinkage. A value close to zero reduces shrinkage, while a negative value can help in shape preservation. |
delta |
A numeric value used in certain smoothing algorithms to adjust the influence of smoothing (e.g., in surface-preserving methods). |
iteration |
An integer specifying the number of smoothing iterations to apply. More iterations result in a smoother surface but can also lead to excessive flattening. |
The smooth function provides a common interface for smoothing operations on different types of surface objects. The actual smoothing process varies based on the class of the object provided:
For SurfaceGeometry objects, the function smooths the surface geometry, modifying the shape of the mesh to reduce noise.
For NeuroSurface objects, the function smooths the data values associated with each vertex, preserving the surface geometry but producing a smoother dataset.
Users should refer to the specific method documentation for the class of object they are working with to understand the exact behavior and parameters.
The function returns the smoothed SurfaceGeometry object with the updated mesh.
smooth,SurfaceGeometry-method, smooth,NeuroSurface-method
vcgSmooth for more details on the underlying smoothing algorithms.
sg <- example_surface_geometry() smoothed_geom <- smooth(sg, type="taubin", lambda=0.7, iteration=10) # Load a surface file from the extdata directory surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surface <- read_surf_geometry(surf_file) # Apply Taubin smoothing to the brain surface smoothed_surface1 <- smooth(surface, type = "taubin", lambda = 0.5, mu = -0.5, iteration = 10) # Apply surface-preserving Laplacian smoothing smoothed_surface2 <- smooth(surface, type = "surfPreserveLaplace", iteration = 5)sg <- example_surface_geometry() smoothed_geom <- smooth(sg, type="taubin", lambda=0.7, iteration=10) # Load a surface file from the extdata directory surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surface <- read_surf_geometry(surf_file) # Apply Taubin smoothing to the brain surface smoothed_surface1 <- smooth(surface, type = "taubin", lambda = 0.5, mu = -0.5, iteration = 10) # Apply surface-preserving Laplacian smoothing smoothed_surface2 <- smooth(surface, type = "surfPreserveLaplace", iteration = 5)
This method applies smoothing to the data values associated with a NeuroSurface object. Unlike the geometric smoothing applied to SurfaceGeometry, this function smooths the scalar values (e.g., intensity or activation) associated with each vertex on the surface.
## S4 method for signature 'NeuroSurface' smooth(x, sigma = 5, ...)## S4 method for signature 'NeuroSurface' smooth(x, sigma = 5, ...)
x |
A |
sigma |
A numeric value specifying the smoothing radius. This defines the neighborhood around each vertex used to compute the smoothed value. Default is 5. |
... |
Additional arguments passed to the smoothing function. |
The smoothing process involves averaging the data values within a geodesic
neighbourhood of each vertex. For every vertex the function uses
find_all_neighbors to locate all vertices within the radius
specified by sigma. The smoothed value is the mean of the vertex's own
value and those of its neighbours. Increasing sigma results in
broader smoothing because more neighbours are included in the average.
The smoothing is particularly useful when working with noisy data or when a smoother representation of the underlying signal is desired. It is commonly applied in neuroimaging to enhance visualization or prepare data for further analysis.
A new NeuroSurface object with the smoothed data values. The geometry remains unchanged.
smooth,SurfaceGeometry-method for smoothing the geometry of a surface.
# Create a tiny example surface and data surface <- example_surface_geometry() n_vertices <- nrow(coords(surface)) random_data <- rnorm(n_vertices) neuro_surf <- NeuroSurface(geometry = surface, indices = seq_len(n_vertices), data = random_data) # Apply smoothing with different radii smoothed_small <- smooth(neuro_surf, sigma = 1) smoothed_large <- smooth(neuro_surf, sigma = 2) # The original geometry is preserved, but the data is smoothed head(series(smoothed_large, indices(smoothed_large)))# Create a tiny example surface and data surface <- example_surface_geometry() n_vertices <- nrow(coords(surface)) random_data <- rnorm(n_vertices) neuro_surf <- NeuroSurface(geometry = surface, indices = seq_len(n_vertices), data = random_data) # Apply smoothing with different radii smoothed_small <- smooth(neuro_surf, sigma = 1) smoothed_large <- smooth(neuro_surf, sigma = 2) # The original geometry is preserved, but the data is smoothed head(series(smoothed_large, indices(smoothed_large)))
Convenience helper for vignettes and reports: renders a surface with
view_surface() onto an off-screen rgl device and saves a PNG.
When rgl.useNULL() is TRUE (headless builds), a proper snapshot
requires the webshot2 package; otherwise a blank image is likely and an
empty path is returned.
snapshot_surface(surfgeom, file = NULL, width = 1200, height = 900, ...)snapshot_surface(surfgeom, file = NULL, width = 1200, height = 900, ...)
surfgeom |
A |
file |
Output path for the PNG. Defaults to the current knitr figure path when knitting, otherwise a temporary file. |
width, height
|
Device size in pixels (controls render resolution). |
... |
Additional arguments passed to |
The file path (invisibly). Callers can use
knitr::include_graphics() or read the image via png::readPNG().
In headless mode without webshot2, an empty character vector is returned.
fs <- load_fsaverage_std8("inflated") if (interactive()) { img <- snapshot_surface(fs$lh, viewpoint = "lateral", specular = "black") }fs <- load_fsaverage_std8("inflated") if (interactive()) { img <- snapshot_surface(fs$lh, viewpoint = "lateral", specular = "black") }
Retrieves the 4x4 affine transformation matrix that converts surface coordinates to world (scanner RAS) coordinates.
surf_to_world(x) ## S4 method for signature 'SurfaceGeometry' surf_to_world(x)surf_to_world(x) ## S4 method for signature 'SurfaceGeometry' surf_to_world(x)
x |
An object containing surface geometry (e.g., |
The surface-to-world transform handles coordinate system conventions (e.g., RAS vs LPI), reference space alignment (e.g., MNI305 vs MNI152), and any embedded transforms from file formats (e.g., GIFTI CoordinateSystemTransformMatrix).
To transform surface vertices to world coordinates:
world_coords = surf_to_world(geom) %*% rbind(t(vertices), 1)
A 4x4 numeric matrix representing the affine transformation.
surf_to_world<-, SurfaceGeometry-class
surf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") geom <- read_surf_geometry(surf_file) xform <- surf_to_world(geom) print(xform)surf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") geom <- read_surf_geometry(surf_file) xform <- surf_to_world(geom) print(xform)
Sets the 4x4 affine transformation matrix that converts surface coordinates to world (scanner RAS) coordinates.
surf_to_world(x) <- value ## S4 replacement method for signature 'SurfaceGeometry,matrix' surf_to_world(x) <- valuesurf_to_world(x) <- value ## S4 replacement method for signature 'SurfaceGeometry,matrix' surf_to_world(x) <- value
x |
An object containing surface geometry (e.g., |
value |
A 4x4 numeric matrix representing the affine transformation. |
The modified object with the updated transform.
surf_to_world, SurfaceGeometry-class
surf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") geom <- read_surf_geometry(surf_file) new_xform <- diag(4) surf_to_world(geom) <- new_xformsurf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") geom <- read_surf_geometry(surf_file) new_xform <- diag(4) surf_to_world(geom) <- new_xform
List available surface labels
surface_labels(x)surface_labels(x)
x |
SurfaceSet |
Character vector of labels
geom <- example_surface_geometry() ss <- surface_set(inflated = geom, pial = geom) surface_labels(ss)geom <- example_surface_geometry() ss <- surface_set(inflated = geom, pial = geom) surface_labels(ss)
Renders several surface views as one figure: a row (the default) or grid of panels. It is designed for R Markdown / pkgdown documents, where it replaces the repetitive "snapshot each panel, check it, otherwise fall back to an interactive widget" boilerplate with a single call.
When the session can produce static snapshots (an interactive 'rgl' device,
or a headless build with webshot2 installed) the panels are captured
and tiled into one PNG. When knitting this is returned via
include_graphics; otherwise the composed image is
written to file. If snapshots are unavailable, the panels are drawn
into a single mfrow3d scene and returned as one
rglwidget (a single combined widget, never one widget per
panel).
surface_montage( panels, ncol = NULL, nrow = NULL, width = 600, height = 450, file = NULL, ... )surface_montage( panels, ncol = NULL, nrow = NULL, width = 600, height = 450, file = NULL, ... )
panels |
A list of panels. Each element is either a surface object
( |
ncol, nrow
|
Integer layout controls. If both are |
width, height
|
Pixel dimensions used when snapshotting each panel. |
file |
Optional output path for the composed PNG. When knitting, a
figure path is generated automatically and this is ignored. When called
interactively, supplying |
... |
Shared display arguments forwarded to every panel (e.g.
|
Each static panel is rendered in its own fresh rgl scene, so lighting
is computed independently and panels never share or clobber one another's
lights. Panels are centred on equally sized white cells so differing
silhouettes stay aligned.
When knitting, a knitr image object (static path) or a single
rglwidget (fallback). When called interactively, the composed file
path (if file is given) or invisible(NULL) after drawing an
interactive mfrow3d window.
view_surface, snapshot_surface,
surface_plot
geom <- example_surface_geometry() set.seed(1) vals <- rnorm(nrow(coords(geom))) ns <- smooth(NeuroSurface(geom, indices = seq_along(vals), data = vals)) out <- tempfile(fileext = ".png") if (interactive()) { surface_montage( list( ns, list(ns, thresh = c(-0.5, 0.5)), list(ns, thresh = c(-1, 1)) ), cmap = grDevices::rainbow(100), irange = c(-2, 2), ncol = 3, file = out ) }geom <- example_surface_geometry() set.seed(1) vals <- rnorm(nrow(coords(geom))) ns <- smooth(NeuroSurface(geom, indices = seq_along(vals), data = vals)) out <- tempfile(fileext = ".png") if (interactive()) { surface_montage( list( ns, list(ns, thresh = c(-0.5, 0.5)), list(ns, thresh = c(-1, 1)) ), cmap = grDevices::rainbow(100), irange = c(-2, 2), ncol = 3, file = out ) }
Create a surface plot specification
surface_plot( lh, rh = NULL, views = c("lateral", "medial"), layout = c("grid", "row", "column"), mirror_views = FALSE, flip = FALSE, zoom = 2, background = "white", brightness = 0.5 )surface_plot( lh, rh = NULL, views = c("lateral", "medial"), layout = c("grid", "row", "column"), mirror_views = FALSE, flip = FALSE, zoom = 2, background = "white", brightness = 0.5 )
lh, rh
|
Either |
views |
Character vector of named views to display for each hemisphere.
Valid values include |
layout |
One of |
mirror_views |
Logical; if |
flip |
Logical; if |
zoom |
Numeric zoom factor passed through to the underlying
|
background |
Background colour for the rgl scene. |
brightness |
Baseline brightness for a plain surface when no layers are
added. Value in |
An object of class "neurosurf_plot" that can be further
modified with add_surface_layer() and rendered with
render_surface_plot() or draw_surface_plot().
geom <- example_surface_geometry() p <- surface_plot(geom) p <- add_surface_layer(p, data = rnorm(nrow(coords(geom))))geom <- example_surface_geometry() p <- surface_plot(geom) p <- add_surface_layer(p, data = rnorm(nrow(coords(geom))))
Precompute voxel neighbors and distances for each surface vertex so that repeated volume-to-surface projections (e.g., 4D time series) can be done quickly without rebuilding nearest-neighbor searches.
surface_sampler( surf_wm, surf_pial, vol_template, mask = NULL, sampling = c("midpoint", "normal_line", "thickness"), n_samples = NULL, depth = NULL, radius = 3, knn = 6, dthresh = 16 )surface_sampler( surf_wm, surf_pial, vol_template, mask = NULL, sampling = c("midpoint", "normal_line", "thickness"), n_samples = NULL, depth = NULL, radius = 3, knn = 6, dthresh = 16 )
surf_wm |
White-matter (inner) surface, |
surf_pial |
Pial (outer) surface, |
vol_template |
A |
mask |
Optional mask limiting candidate voxels; if |
sampling |
How to place sample points relative to the white/pial pair. Options are:
|
n_samples |
Number of samples per vertex for |
depth |
Optional numeric vector controlling sampling positions; interpreted as fractions of thickness (for "thickness") or multiples of |
radius |
Radius (in voxel units) for normal-line sampling when
|
knn |
The number of nearest neighbors to consider for mapping (default: 6). |
dthresh |
The maximum distance threshold for valid mapping. A voxel is only considered if it is less than |
A list with class "surface_sampler" containing precomputed
neighbor indices and distances for each vertex.
# Requires white and pial surfaces plus a template volume # wm <- read_surf_geometry("lh.white") # pial <- read_surf_geometry("lh.pial") # template_vol <- neuroim2::read_vol("template.nii") # sampler <- surface_sampler(wm, pial, template_vol)# Requires white and pial surfaces plus a template volume # wm <- read_surf_geometry("lh.white") # pial <- read_surf_geometry("lh.pial") # template_vol <- neuroim2::read_vol("template.nii") # sampler <- surface_sampler(wm, pial, template_vol)
Construct a SurfaceSet
surface_set(..., hemi = NULL, default_label = NULL)surface_set(..., hemi = NULL, default_label = NULL)
... |
Named 'SurfaceGeometry' objects, or a single named list of them. |
hemi |
Hemisphere code; defaults to the hemi of the first geometry. |
default_label |
Optional default label; defaults to the first provided label. |
A 'SurfaceSet' instance.
# Create a simple SurfaceSet with a single geometry geom <- example_surface_geometry() ss <- surface_set(inflated = geom) surface_labels(ss)# Create a simple SurfaceSet with a single geometry geom <- example_surface_geometry() ss <- surface_set(inflated = geom) surface_labels(ss)
This class contains meta information for surface-based data (the values that map to a surface geometry)
An object of class SurfaceDataMetaInfo.
header_filename of the file containing meta information
data_filename of the file containing data
file_descriptordescriptor of image file format
node_countthe number of nodes for which surface data exists
nelsthe number of data vectors (typically the number of columns in the surface data matrix; nels = 1 for a single surface data set)
labela label indicating the type of surface (e.g. white, pial, inflated, flat, spherical)
meta_info <- new("SurfaceDataMetaInfo", header_file = "data_header.txt", data_file = "surface_data.1D", file_descriptor = new("FileFormat"), node_count = length(nodes(geometry)), nels = 1L, label = "thickness")meta_info <- new("SurfaceDataMetaInfo", header_file = "data_header.txt", data_file = "surface_data.1D", file_descriptor = new("FileFormat"), node_count = length(nodes(geometry)), nels = 1L, label = "thickness")
Creates a Region on a Surface from a radius and surface
SurfaceDisk(surf, index, radius, max_order = NULL)SurfaceDisk(surf, index, radius, max_order = NULL)
surf |
a |
index |
the index of the central surface node. Must be a numeric
integer value within |
radius |
the size in mm of the geodesic radius. Must be a single positive numeric value. |
max_order |
maximum number of edges to traverse. default is computed based on average edge length. |
The igraph associated with surf must have an edge
attribute named dist containing numeric weights with no
NA values.
An ROISurfaceVector if surf is a BrainSurface or
BrainSurfaceVector, otherwise an ROISurface containing the
vertices within the specified geodesic radius.
This function creates a new SurfaceGeometry object from vertex coordinates and face indices.
SurfaceGeometry( vert, faces, hemi, label = NA_character_, surf_to_world = diag(4) )SurfaceGeometry( vert, faces, hemi, label = NA_character_, surf_to_world = diag(4) )
vert |
A numeric matrix with 3 columns representing the x, y, and z coordinates of vertices. |
faces |
An integer matrix where each row represents a face, containing indices of vertices that form the face. |
hemi |
A character string indicating the hemisphere ("lh" for left, "rh" for right, or other identifier). |
label |
Optional character string describing the surface type (e.g., "pial", "white", "inflated", "sphere"). |
surf_to_world |
Optional 4x4 affine transformation matrix from surface coordinates to world (scanner RAS) coordinates. Defaults to identity matrix. This transform handles coordinate system conventions (e.g., RAS vs LPI) and reference space alignment (e.g., MNI305 vs MNI152). |
This function constructs a SurfaceGeometry object by creating a mesh and a graph representation of the surface. It uses the rgl package for 3D visualization and the igraph package for graph operations.
The vertex indices in the faces matrix should be 0-based (starting from 0), as they get incremented by 1 when passed to the rgl mesh function.
A new object of class "SurfaceGeometry" containing:
mesh |
An rgl mesh object representing the surface. |
graph |
An igraph object representing the mesh connectivity. |
hemi |
The hemisphere identifier. |
surf_to_world |
The 4x4 affine transformation matrix. |
# Create a simple icosahedron-like mesh with 12 vertices set.seed(123) vertices <- matrix(rnorm(36), ncol=3) # Create faces with 0-based indices (0 to 11) # Each face connects three vertices faces <- matrix(sample(0:11, 60, replace=TRUE), ncol=3) # Create the SurfaceGeometry object surf_geom <- SurfaceGeometry(vertices, faces, "lh") # Visualize the mesh if rgl is available if(interactive() && requireNamespace("rgl", quietly = TRUE)) { rgl::open3d() rgl::shade3d(surf_geom@mesh, col="lightblue") }# Create a simple icosahedron-like mesh with 12 vertices set.seed(123) vertices <- matrix(rnorm(36), ncol=3) # Create faces with 0-based indices (0 to 11) # Each face connects three vertices faces <- matrix(sample(0:11, 60, replace=TRUE), ncol=3) # Create the SurfaceGeometry object surf_geom <- SurfaceGeometry(vertices, faces, "lh") # Visualize the mesh if rgl is available if(interactive() && requireNamespace("rgl", quietly = TRUE)) { rgl::open3d() rgl::shade3d(surf_geom@mesh, col="lightblue") }
The 'SurfaceGeometry' class represents a three-dimensional surface consisting of a set of triangle vertices. It encapsulates the mesh structure, graph representation, and hemisphere information of a brain surface.
This class is fundamental for representing brain surface geometries in neuroimaging analyses. The mesh slot contains the vertex and face information, while the graph slot provides a network representation of the surface topology. The hemi slot specifies which hemisphere the surface represents.
The surf_to_world transform enables proper projection between surface and volume spaces:
world_pos = surf_to_world %*% c(vertex_pos, 1), then
voxel_ijk = world_to_vox %*% world_pos.
An object of class SurfaceGeometry.
meshAn object of class mesh3d representing the underlying 3D mesh structure.
graphAn object of class igraph representing the underlying graph structure of the surface.
hemiA character string indicating the hemisphere of the surface ("left", "right", or "both").
labelA character string describing the surface type (e.g., "pial", "white", "inflated", "sphere").
surf_to_worldA 4x4 numeric matrix representing the affine transformation from surface coordinates to world (scanner RAS) coordinates. This handles coordinate system conventions (e.g., RAS vs LPI), reference space alignment (e.g., MNI305 vs MNI152), and any embedded transforms from file formats (e.g., GIFTI CoordinateSystemTransformMatrix). Defaults to the identity matrix (surface coordinates are assumed to be in world space).
geometry <- example_surface_geometry()geometry <- example_surface_geometry()
The 'SurfaceGeometryMetaInfo' class encapsulates meta information for brain surface geometry. It stores details about the file locations, surface properties, and spatial characteristics.
This class is crucial for maintaining metadata about brain surface geometries. It provides a structured way to store information about file locations, surface properties, and spatial characteristics, which is essential for proper handling and processing of brain surface data in neuroimaging analyses.
An object of class SurfaceGeometryMetaInfo.
header_fileA character string specifying the name of the file containing meta information.
data_fileA character string specifying the name of the file containing the actual surface data.
file_descriptorAn object of class 'FileFormat' describing the image file format.
verticesAn integer indicating the number of surface vertices.
facesAn integer indicating the number of faces in the surface mesh.
embed_dimensionAn integer specifying the dimensionality of the embedding (typically 3 for 3D surfaces).
labelA character string indicating the type of surface (e.g., "white", "pial", "inflated", "flat", "spherical").
hemiA character string indicating the hemisphere ("lh" for left, "rh" for right, or "unknown").
meta_info <- new("SurfaceGeometryMetaInfo", header_file = "surface_meta.txt", data_file = "surface_data.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh")meta_info <- new("SurfaceGeometryMetaInfo", header_file = "surface_meta.txt", data_file = "surface_data.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh")
The 'SurfaceGeometrySource' class serves as a factory for creating
SurfaceGeometry instances. It encapsulates the
meta information required to construct a surface geometry.
This class is designed to facilitate the creation of SurfaceGeometry
objects by providing a standardized way to store and access the required metadata.
It acts as an intermediate step in the process of loading and constructing
surface geometries from various file formats and sources.
An object of class SurfaceGeometrySource.
meta_infoAn object of class SurfaceGeometryMetaInfo
containing the metadata necessary for creating a surface geometry.
SurfaceGeometry, SurfaceGeometryMetaInfo
# Create a SurfaceGeometryMetaInfo object meta_info <- new("SurfaceGeometryMetaInfo", header_file = "surface_meta.txt", data_file = "surface_data.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh") # Create a SurfaceGeometrySource object geom_source <- new("SurfaceGeometrySource", meta_info = meta_info) # Use geom_source to create a SurfaceGeometry object (hypothetical function) # surface_geometry <- createSurfaceGeometry(geom_source)# Create a SurfaceGeometryMetaInfo object meta_info <- new("SurfaceGeometryMetaInfo", header_file = "surface_meta.txt", data_file = "surface_data.gii", file_descriptor = new("FileFormat"), vertices = 40000L, faces = 79998L, embed_dimension = 3L, label = "white", hemi = "lh") # Create a SurfaceGeometrySource object geom_source <- new("SurfaceGeometrySource", meta_info = meta_info) # Use geom_source to create a SurfaceGeometry object (hypothetical function) # surface_geometry <- createSurfaceGeometry(geom_source)
Creates an iterator that systematically samples searchlight regions on a surface mesh using geodesic distance to define regions.
SurfaceSearchlight( surfgeom, radius = 8, nodeset = NULL, distance_type = c("euclidean", "geodesic", "spherical"), as_deflist = FALSE )SurfaceSearchlight( surfgeom, radius = 8, nodeset = NULL, distance_type = c("euclidean", "geodesic", "spherical"), as_deflist = FALSE )
surfgeom |
A |
radius |
Numeric, radius of the searchlight as a geodesic distance in mm. Must be a positive, length-one value. |
nodeset |
Integer vector, optional subset of surface node indices to use. If provided, the vector must contain at least one node index. |
distance_type |
Character, the distance metric to use: "euclidean", "geodesic", or "spherical". |
as_deflist |
Logical, whether to return a deflist object. |
Create a Searchlight iterator for surface mesh using geodesic distance to define regions.
This function creates a systematic searchlight iterator, which visits each node of the surface mesh in order. The searchlight region for each node is defined by the specified radius and distance metric.
An iterator object of class "Searchlight".
file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") geom <- read_surf(file) searchlight <- SurfaceSearchlight(geom, 12, distance_type = "geodesic") nodes <- searchlight$nextElem()file <- system.file("extdata", "std.8_lh.smoothwm.asc", package = "neurosurf") geom <- read_surf(file) searchlight <- SurfaceSearchlight(geom, 12, distance_type = "geodesic") nodes <- searchlight$nextElem()
A 'SurfaceSet' keeps several 'SurfaceGeometry' variants (e.g., pial, white, inflated, sphere) for the same hemisphere together with a default choice.
## S4 method for signature 'SurfaceSet' geometry(x) ## S4 method for signature 'SurfaceSet' vertices(x, ...) ## S4 method for signature 'SurfaceSet' faces(x, ...) ## S4 method for signature 'SurfaceSet' nodes(x) ## S4 method for signature 'SurfaceSet' graph(x, ...) ## S4 method for signature 'SurfaceSet' curvature(x, ...)## S4 method for signature 'SurfaceSet' geometry(x) ## S4 method for signature 'SurfaceSet' vertices(x, ...) ## S4 method for signature 'SurfaceSet' faces(x, ...) ## S4 method for signature 'SurfaceSet' nodes(x) ## S4 method for signature 'SurfaceSet' graph(x, ...) ## S4 method for signature 'SurfaceSet' curvature(x, ...)
x |
a 'SurfaceSet' |
... |
additional arguments forwarded to the underlying geometry method |
An S4 object of class SurfaceSet. Use surface_set
to construct instances.
hemiCharacter string for hemisphere (e.g., "lh" or "rh").
surfacesNamed list of 'SurfaceGeometry' objects keyed by their label.
default_labelCharacter string giving the label to use by default.
This generic function creates a widget for visualizing surface data, allowing for different implementations based on the type of surface object.
Create a surfwidget to display brain surface data.
surfwidget(x, width = NULL, height = NULL, ...) ## S4 method for signature 'SurfaceGeometry' surfwidget( x, width = NULL, height = NULL, data = NULL, cmap = jet_colors(256), irange = NULL, thresh = c(0, 0), vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'NeuroSurface' surfwidget( x, width = NULL, height = NULL, cmap = jet_colors(256), irange = range(x@data), thresh = c(0, 0), vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'ColorMappedNeuroSurface' surfwidget( x, width = NULL, height = NULL, thresh = NULL, vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'VertexColoredNeuroSurface' surfwidget( x, width = NULL, height = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... )surfwidget(x, width = NULL, height = NULL, ...) ## S4 method for signature 'SurfaceGeometry' surfwidget( x, width = NULL, height = NULL, data = NULL, cmap = jet_colors(256), irange = NULL, thresh = c(0, 0), vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'NeuroSurface' surfwidget( x, width = NULL, height = NULL, cmap = jet_colors(256), irange = range(x@data), thresh = c(0, 0), vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'ColorMappedNeuroSurface' surfwidget( x, width = NULL, height = NULL, thresh = NULL, vertexColors = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... ) ## S4 method for signature 'VertexColoredNeuroSurface' surfwidget( x, width = NULL, height = NULL, alpha = 1, curvature = NULL, colorbar = TRUE, colorbar_label = NULL, layers = NULL, config = list(), ... )
x |
A SurfaceGeometry, NeuroSurface, ColorMappedNeuroSurface, or VertexColoredNeuroSurface object |
width |
The width of the widget |
height |
The height of the widget |
... |
Additional arguments for customizing the widget appearance and behavior. |
data |
Optional. Numeric vector of data values for each vertex. |
cmap |
Optional. Color map for data visualization. |
irange |
Optional. Intensity range for data visualization. |
thresh |
Optional. Threshold range for data visualization. |
vertexColors |
Optional. Vector of colors for each vertex. |
alpha |
Opacity of the surface (0 to 1). |
curvature |
Optional numeric vector of curvature values for each vertex.
If not supplied for a |
colorbar |
Logical; if |
colorbar_label |
Optional character label shown alongside the colorbar. |
layers |
Optional list of additional data layers to display on the surface.
Each layer should be a list with elements such as |
config |
A list of configuration options for the surface rendering:
Unknown elements in |
The surfwidget function creates an interactive widget for visualizing surface data, such as brain surfaces. The specific implementation depends on the class of the object provided, allowing for customized behavior for different types of surface representations.
An HTMLWidget object representing the surface visualization.
An HTMLWidget object
plot_js, SurfaceGeometry, NeuroSurface
geom <- example_surface_geometry() surfwidget(geom)geom <- example_surface_geometry() surfwidget(geom)
Change the color map used by an existing surfwidget.
updateColorMap(widget, colorMap)updateColorMap(widget, colorMap)
widget |
A surfwidget object as returned by |
colorMap |
A vector of colors defining the new color map. |
The modified surfwidget object (invisibly).
Extracts the data values associated with vertices in a surface object.
## S4 method for signature 'ROISurface' values(x, ...) ## S4 method for signature 'ROISurfaceVector' values(x, ...) ## S4 method for signature 'NeuroSurface' values(x, ...)## S4 method for signature 'ROISurface' values(x, ...) ## S4 method for signature 'ROISurfaceVector' values(x, ...) ## S4 method for signature 'NeuroSurface' values(x, ...)
x |
the object to extract the values from |
... |
additional arguments |
A numeric vector or matrix of data values
This function creates a VertexColoredNeuroSurface object, which represents a surface with explicit colors assigned to each vertex.
VertexColoredNeuroSurface(geometry, indices, colors, data = NULL)VertexColoredNeuroSurface(geometry, indices, colors, data = NULL)
geometry |
A |
indices |
An integer vector specifying the indices of valid surface nodes. |
colors |
A character vector of hex color codes for each vertex. |
data |
An optional numeric vector of data values. If not provided, defaults to zeros.
This parameter exists for compatibility with the parent NeuroSurface class but is not
used for coloring (colors are specified directly via the |
This object represents a surface where each vertex has an explicitly assigned color, bypassing any data-to-color mapping. This is useful when you want direct control over vertex colors, such as when displaying parcellation results or pre-computed color schemes.
A VertexColoredNeuroSurface object containing the surface geometry
with explicit vertex colors.
SurfaceGeometry, NeuroSurface, ColorMappedNeuroSurface
# Load a sample surface geometry surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Get first 100 vertices for this example n_verts <- min(100, nrow(coords(surf_geom))) vertex_indices <- 1:n_verts # Create colors based on vertex coordinates (x-position) x_coords <- coords(surf_geom)[vertex_indices, 1] vertex_colors <- ifelse(x_coords > median(x_coords), "#FF6B6B", "#4ECDC4") # Create the VertexColoredNeuroSurface object colored_surf <- VertexColoredNeuroSurface(geometry = surf_geom, indices = vertex_indices, colors = vertex_colors) # Print the object summary print(colored_surf) # The object can now be plotted with the specified colors # plot(colored_surf) # Requires rgl package# Load a sample surface geometry surf_file <- system.file("extdata", "std.8_lh.inflated.asc", package = "neurosurf") surf_geom <- read_surf_geometry(surf_file) # Get first 100 vertices for this example n_verts <- min(100, nrow(coords(surf_geom))) vertex_indices <- 1:n_verts # Create colors based on vertex coordinates (x-position) x_coords <- coords(surf_geom)[vertex_indices, 1] vertex_colors <- ifelse(x_coords > median(x_coords), "#FF6B6B", "#4ECDC4") # Create the VertexColoredNeuroSurface object colored_surf <- VertexColoredNeuroSurface(geometry = surf_geom, indices = vertex_indices, colors = vertex_colors) # Print the object summary print(colored_surf) # The object can now be plotted with the specified colors # plot(colored_surf) # Requires rgl package
A three-dimensional surface consisting of a set of triangle vertices with one color per vertex.
This class extends NeuroSurface by adding per-vertex coloring functionality.
The colors slot contains a vector of hex color codes that define the color for each vertex.
Unlike ColorMappedNeuroSurface, this class does not use a colormap or data mapping,
but instead directly specifies colors for each vertex.
An object of class VertexColoredNeuroSurface.
geometryThe surface geometry, an instance of SurfaceGeometry or SurfaceSet
indicesAn integer vector specifying the subset of valid surface nodes encoded in the geometry object
colorsA character vector of hex color codes representing the color of each vertex
# First create a simple tetrahedron mesh vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create placeholder data (required by NeuroSurface parent class) vertex_data <- c(0, 0, 0, 0) # Not used for coloring # Define explicit colors for each vertex vertex_colors <- c( "#FF0000", # Red for vertex 1 "#00FF00", # Green for vertex 2 "#0000FF", # Blue for vertex 3 "#FFFF00" # Yellow for vertex 4 ) # Create the VertexColoredNeuroSurface object colored_vertices <- new("VertexColoredNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, colors = vertex_colors) # In this example, each vertex has an explicit color: # - Vertex 1 is red # - Vertex 2 is green # - Vertex 3 is blue # - Vertex 4 is yellow# First create a simple tetrahedron mesh vertices <- c( 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 ) triangles <- c( 1, 2, 3, 1, 2, 4, 1, 3, 4, 2, 3, 4 ) # Create mesh3d object mesh <- rgl::mesh3d(vertices = vertices, triangles = triangles) # Create a graph representation edges <- rbind( c(1,2), c(1,3), c(1,4), c(2,3), c(2,4), c(3,4) ) graph <- igraph::graph_from_edgelist(edges) # Create a SurfaceGeometry object geometry <- new("SurfaceGeometry", mesh = mesh, graph = graph, hemi = "left") # Define indices for all vertices indices <- 1:4 # Create placeholder data (required by NeuroSurface parent class) vertex_data <- c(0, 0, 0, 0) # Not used for coloring # Define explicit colors for each vertex vertex_colors <- c( "#FF0000", # Red for vertex 1 "#00FF00", # Green for vertex 2 "#0000FF", # Blue for vertex 3 "#FFFF00" # Yellow for vertex 4 ) # Create the VertexColoredNeuroSurface object colored_vertices <- new("VertexColoredNeuroSurface", geometry = geometry, indices = indices, data = vertex_data, colors = vertex_colors) # In this example, each vertex has an explicit color: # - Vertex 1 is red # - Vertex 2 is green # - Vertex 3 is blue # - Vertex 4 is yellow
A set of arbitrary vertices associated with a data table
The VertexData class provides a flexible way to associate arbitrary data with specific vertices in a brain surface. Unlike ROISurface and similar classes, VertexData does not require or maintain a reference to surface geometry, making it lighter and more versatile for storing and manipulating vertex-specific information.
This class is particularly useful for:
Storing heterogeneous data (different data types) associated with vertices
Maintaining analysis results like statistical outcomes for specific vertices
Tracking vertex-specific annotations or classifications
Creating lookup tables for vertex properties that can be joined with other data
The data slot contains a data frame where each row corresponds to a vertex
in the same order as the indices slot. This structure allows storing multiple attributes
of different types (numeric, character, logical) for each vertex, and facilitates
standard data frame operations like filtering, sorting, and joining.
An object of class VertexData.
indicesthe node indices
datathe associated table with nrow(data) == length(indices)
# Create a set of vertex indices vertex_indices <- c(10L, 25L, 50L, 100L, 200L) # Create a data frame with information for each vertex # Each row corresponds to one vertex in the same order as indices vertex_data <- data.frame( value = c(0.5, 1.2, 0.8, 1.5, 0.3), label = c("A", "B", "A", "C", "B"), significant = c(TRUE, FALSE, TRUE, TRUE, FALSE) ) # Create the VertexData object vd <- new("VertexData", indices = vertex_indices, data = vertex_data) # Access the data # vd@data$value # vd@data$label[vd@data$significant] # vd@indices[vd@data$label == "A"]# Create a set of vertex indices vertex_indices <- c(10L, 25L, 50L, 100L, 200L) # Create a data frame with information for each vertex # Each row corresponds to one vertex in the same order as indices vertex_data <- data.frame( value = c(0.5, 1.2, 0.8, 1.5, 0.3), label = c("A", "B", "A", "C", "B"), significant = c(TRUE, FALSE, TRUE, TRUE, FALSE) ) # Create the VertexData object vd <- new("VertexData", indices = vertex_indices, data = vertex_data) # Access the data # vd@data$value # vd@data$label[vd@data$significant] # vd@indices[vd@data$label == "A"]
Extracts the vertices from a surface object, providing a standardized interface across different surface representations.
vertices(x, ...) ## S4 method for signature 'SurfaceGeometry' vertices(x, indices) ## S4 method for signature 'NeuroSurface' vertices(x) ## S4 method for signature 'NeuroSurfaceVector' vertices(x, indices)vertices(x, ...) ## S4 method for signature 'SurfaceGeometry' vertices(x, indices) ## S4 method for signature 'NeuroSurface' vertices(x) ## S4 method for signature 'NeuroSurfaceVector' vertices(x, indices)
x |
An object representing a surface. |
... |
Additional arguments passed to methods. |
indices |
a vector of indices specifying the valid surface nodes. |
A matrix or data structure containing vertex information.
vertex_data <- vertices(example_surface_geometry()) num_vertices <- nrow(vertex_data)vertex_data <- vertices(example_surface_geometry()) num_vertices <- nrow(vertex_data)
Renders a 3D brain surface mesh using the 'rgl' package. This function provides flexible options for coloring the surface based on data values or predefined colors, adjusting transparency, controlling lighting, setting viewpoints, and overlaying spherical markers.
view_surface( surfgeom, vals = NA, cmap = grDevices::rainbow(256, alpha = 1), vert_clrs = NULL, bgcol = "lightgray", alpha = 1, add_normals = TRUE, thresh = NULL, irange = NULL, specular = "black", lit = NULL, viewpoint = c("lateral", "medial", "ventral", "dorsal", "anterior", "posterior"), new_window = TRUE, offset = c(0, 0, 0), zoom = 1, spheres = NULL, spheres_map_surface = NULL, spheres_map_label = NULL, spheres_as_vertices = FALSE, vectors = NULL, vector_vertices = NULL, vector_scale = NULL, vector_color = "red", vector_alpha = 0.8, vector_lwd = 1.5, vals_vertices = NULL, vals_smoothing = c("auto", "nearest"), vals_smoothing_steps = 20, label = NULL, ... )view_surface( surfgeom, vals = NA, cmap = grDevices::rainbow(256, alpha = 1), vert_clrs = NULL, bgcol = "lightgray", alpha = 1, add_normals = TRUE, thresh = NULL, irange = NULL, specular = "black", lit = NULL, viewpoint = c("lateral", "medial", "ventral", "dorsal", "anterior", "posterior"), new_window = TRUE, offset = c(0, 0, 0), zoom = 1, spheres = NULL, spheres_map_surface = NULL, spheres_map_label = NULL, spheres_as_vertices = FALSE, vectors = NULL, vector_vertices = NULL, vector_scale = NULL, vector_color = "red", vector_alpha = 0.8, vector_lwd = 1.5, vals_vertices = NULL, vals_smoothing = c("auto", "nearest"), vals_smoothing_steps = 20, label = NULL, ... )
surfgeom |
A |
vals |
An optional numeric vector containing data values for each vertex on the surface. If provided and 'vert_clrs' is NULL, these values are mapped to colors using 'cmap' and 'irange'. |
cmap |
A vector of colors (e.g., hex codes) defining the color map used when 'vals' is provided and 'vert_clrs' is NULL. Defaults to 'rainbow(256)'. |
vert_clrs |
An optional character vector of hex color codes for each vertex. If provided, these colors directly override any coloring derived from 'vals' and 'cmap'. The length should match the number of vertices in 'surfgeom'. |
bgcol |
A single hex color code or a vector of hex color codes used as the base color for the surface. If 'vals' or 'vert_clrs' are provided, this color is blended with the data/vertex colors. Defaults to "lightgray". |
alpha |
A numeric value between 0 (fully transparent) and 1 (fully opaque) controlling the overall transparency of the surface. Defaults to 1. |
add_normals |
Logical. If TRUE (default), surface normals are calculated and added to the mesh, which improves the appearance of lighting effects. |
thresh |
An optional numeric vector of length 2, 'c(lower, upper)'. Vertices with 'vals' *outside* this range (i.e., '< lower' or '> upper') are made fully transparent. This is applied *after* the general 'alpha'. Defaults to NULL (no thresholding). |
irange |
An optional numeric vector of length 2, 'c(min, max)'. Specifies the range of 'vals' to map onto the 'cmap'. Values outside this range will be clamped to the min/max colors. Defaults to the full range of 'vals'. |
specular |
The color of specular highlights on the surface, affecting its shininess. Can be a color name (e.g., "white") or hex code. Defaults to "black" for a matte look. Set to a brighter colour for a glossier appearance. |
lit |
Logical. If |
viewpoint |
A character string specifying a predefined view (e.g., "lateral", "medial", "ventral", "dorsal", "anterior", "posterior"). The actual view depends on the hemisphere ('surfgeom@hemi', e.g., "left_lateral"). Alternatively, a 4x4 transformation matrix defining a custom view. Defaults to "lateral". |
new_window |
Logical. If TRUE (default), opens a new 'rgl' window for the plot. If FALSE, attempts to plot in the currently active 'rgl' window (useful for updates or within Shiny apps). |
offset |
A numeric vector of length 3 specifying a translation offset 'c(x, y, z)' applied to the surface coordinates before rendering. Defaults to 'c(0, 0, 0)'. |
zoom |
A numeric value controlling the camera zoom level. Defaults to 1 (no zoom). Values > 1 zoom in, < 1 zoom out. |
spheres |
An optional data frame to draw spheres at specific locations on
or near the surface. Must contain columns 'x', 'y', 'z' (coordinates), and
'radius'. Can optionally include a 'color' column (hex codes or color names)
for individual sphere colors (defaults to black). Alternatively, supply a
'vertex' column (1-based vertex ids) and set |
spheres_map_surface |
Optional |
spheres_map_label |
Optional surface label to use when
|
spheres_as_vertices |
Logical; if |
vectors |
Optional matrix (n x 3) of XYZ vectors to draw as line glyphs. |
vector_vertices |
Optional vertex ids matching rows of |
vector_scale |
Optional numeric scale factor for vectors. If |
vector_color |
Colour for the vectors (single value or vector). |
vector_alpha |
Opacity for the vectors (0–1). |
vector_lwd |
Numeric line width for vector glyphs. |
vals_vertices |
Optional integer vector of 1-based vertex ids corresponding to 'vals' when 'length(vals) < n_vertices'. Enables sparse data inputs. |
vals_smoothing |
One of '"auto"' (default) or '"nearest"'. When using sparse data, '"auto"' diffuses values with neighbor averaging after nearest fill; '"nearest"' performs nearest-neighbour fill only. |
vals_smoothing_steps |
Integer number of smoothing iterations applied when 'vals_smoothing = "auto"'. Ignored otherwise. |
label |
Optional surface label to select when 'surfgeom' is a
|
... |
Additional arguments passed directly to 'rgl::shade3d' for fine-grained control over rendering (e.g., 'lit', 'smooth'). |
**Coloring:** Surface vertex colors are determined by the following priority: 1. 'vert_clrs': If provided, these specific hex colors are used. 2. 'vals' & 'cmap': If 'vals' is provided and 'vert_clrs' is NULL, 'vals' are mapped to 'cmap' based on 'irange'. 3. 'bgcol': If neither 'vert_clrs' nor 'vals' are used for coloring, 'bgcol' is applied uniformly. If 'bgcol' is specified alongside 'vert_clrs' or 'vals', the colors are blended based on the 'alpha' parameter.
**Transparency:** Overall transparency is set by 'alpha'. Additional threshold-based transparency can be applied using 'thresh' when 'vals' are provided. Vertices with values outside the 'thresh' range become fully transparent.
**Lighting:** 'add_normals=TRUE' is recommended for realistic lighting. The 'specular' parameter controls the shininess.
**Viewpoint:** Predefined viewpoints ('"lateral"', '"medial"', etc.) are automatically adjusted based on the hemisphere specified in 'surfgeom@hemi' (e.g., "lh" results in "left_lateral"). If 'hemi' is unknown, the current 'rgl' view is used unless a custom 4x4 matrix is provided.
**Performance:** Rendering very large surfaces or surfaces with complex coloring/transparency can be computationally intensive.
Invisibly returns the object ID(s) of the shape(s) added to the RGL scene by 'rgl::shade3d'. This can be useful for modifying the scene later.
shade3d, spheres3d, view3d, SurfaceGeometry
surf_geom <- example_surface_geometry() if (interactive()) { view_surface(surf_geom, viewpoint = "lateral") }surf_geom <- example_surface_geometry() if (interactive()) { view_surface(surf_geom, viewpoint = "lateral") }
This function maps values from a 3D volume to a surface representation, allowing for different mapping strategies.
vol_to_surf( surf_wm, surf_pial, vol, mask = NULL, fun = c("avg", "nn", "mode"), knn = 6, sigma = 8, dthresh = sigma * 2, fill = 0, sampling = c("midpoint", "normal_line", "thickness"), n_samples = NULL, depth = NULL, radius = 3, sampler = NULL )vol_to_surf( surf_wm, surf_pial, vol, mask = NULL, fun = c("avg", "nn", "mode"), knn = 6, sigma = 8, dthresh = sigma * 2, fill = 0, sampling = c("midpoint", "normal_line", "thickness"), n_samples = NULL, depth = NULL, radius = 3, sampler = NULL )
surf_wm |
The white matter (inner) surface, typically of class |
surf_pial |
The pial (outer) surface, typically of class |
vol |
An image volume of type |
mask |
A mask defining the valid voxels in the image volume. If NULL, all non-zero voxels are considered valid. |
fun |
The mapping function to use. Options are:
|
knn |
The number of nearest neighbors to consider for mapping (default: 6). |
sigma |
The bandwidth of the smoothing kernel for the "avg" mapping function (default: 8). |
dthresh |
The maximum distance threshold for valid mapping. A voxel is only considered if it is less than |
fill |
Value used when no nearby voxels are found (default: 0 to preserve previous behavior). |
sampling |
How to place sample points relative to the white/pial pair. Options are:
|
n_samples |
Number of samples per vertex for |
depth |
Optional numeric vector controlling sampling positions; interpreted as fractions of thickness (for "thickness") or multiples of |
radius |
Radius (in voxel units) for normal-line sampling when
|
sampler |
Optional surface sampler object created by |
A NeuroSurface object containing the mapped values.
# Load standard white and pial surfaces from the package wm_surf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") pial_surf_file <- system.file("extdata", "std.8_lh.pial.asc", package = "neurosurf") surf_wm <- read_surf_geometry(wm_surf_file) surf_pial <- read_surf_geometry(pial_surf_file) # Create a dummy volume for demonstration purposes bb <- matrix(c(-80, 80, -120, 80, -60, 90), 3, 2, byrow = TRUE) spacing <- c(1, 1, 1) dims <- ceiling(abs(bb[,2] - bb[,1]) / spacing) origin <- bb[,1] sp <- neuroim2::NeuroSpace(dims, spacing, origin) vol <- neuroim2::NeuroVol(rnorm(prod(dims)), sp) # Map volume to surface using average mapping mapped_surf <- vol_to_surf(surf_wm, surf_pial, vol, fun = "avg") print(mapped_surf)# Load standard white and pial surfaces from the package wm_surf_file <- system.file("extdata", "std.8_lh.white.asc", package = "neurosurf") pial_surf_file <- system.file("extdata", "std.8_lh.pial.asc", package = "neurosurf") surf_wm <- read_surf_geometry(wm_surf_file) surf_pial <- read_surf_geometry(pial_surf_file) # Create a dummy volume for demonstration purposes bb <- matrix(c(-80, 80, -120, 80, -60, 90), 3, 2, byrow = TRUE) spacing <- c(1, 1, 1) dims <- ceiling(abs(bb[,2] - bb[,1]) / spacing) origin <- bb[,1] sp <- neuroim2::NeuroSpace(dims, spacing, origin) vol <- neuroim2::NeuroVol(rnorm(prod(dims)), sp) # Map volume to surface using average mapping mapped_surf <- vol_to_surf(surf_wm, surf_pial, vol, fun = "avg") print(mapped_surf)
This wrapper estimates a rigid transform from the input volume to the
template surface space using a signed distance field (SDF), then reuses
vol_to_surf() for the actual sampling in volume space.
vol_to_surf_sdf( surf_wm, surf_pial, vol, sdf_vol, mask = NULL, n_hull = 2000L, thresh = NULL, init_par = rep(0, 6), outside_penalty = 20, method = "L-BFGS-B", ... )vol_to_surf_sdf( surf_wm, surf_pial, vol, sdf_vol, mask = NULL, n_hull = 2000L, thresh = NULL, init_par = rep(0, 6), outside_penalty = 20, method = "L-BFGS-B", ... )
surf_wm |
White-matter (inner) surface in template space |
surf_pial |
Pial (outer) surface in template space |
vol |
NeuroVol in (approximate) template/MNI space |
sdf_vol |
NeuroVol SDF of the template cortical surface |
mask |
optional mask for hull extraction and mapping |
n_hull |
number of hull points to retain (approximate) |
thresh |
optional intensity threshold for hull computation |
init_par |
optional initial parameters (tx, ty, tz, rx, ry, rz) |
outside_penalty |
value used when SDF sampling is outside the grid |
method |
optimization method passed to roptim (default "L-BFGS-B") |
... |
passed through to |
A NeuroSurface with values mapped from vol
# Requires surfaces and volumes in template space # wm <- read_surf_geometry("lh.white") # pial <- read_surf_geometry("lh.pial") # vol <- neuroim2::read_vol("mydata.nii") # sdf <- neuroim2::read_vol("template_sdf.nii") # result <- vol_to_surf_sdf(wm, pial, vol, sdf)# Requires surfaces and volumes in template space # wm <- read_surf_geometry("lh.white") # pial <- read_surf_geometry("lh.pial") # vol <- neuroim2::read_vol("mydata.nii") # sdf <- neuroim2::read_vol("template_sdf.nii") # result <- vol_to_surf_sdf(wm, pial, vol, sdf)
This function writes surface data from a NeuroSurface or NeuroSurfaceVector object to a .1D.dset file.
write_surf_data(surf, outstem, hemi = "")write_surf_data(surf, outstem, hemi = "")
surf |
An object of class |
outstem |
A character string specifying the base name for the output file (without extension). |
hemi |
A character string specifying the hemisphere ("lh" for left, "rh" for right). Default is an empty string. |
The function writes the surface data to a .1D.dset file, which is a tabular data format.
The output file contains node indices in the first column, followed by data values in subsequent columns.
The file name is constructed by combining outstem, hemi (if provided), and the extension ".1D.dset".
For NeuroSurfaceVector objects, all columns of data are written. For NeuroSurface objects, only the single data vector is written.
The data is written without row names, column names, or quotes.
This function does not return a value. It writes the data to a .1D.dset file as a side effect.
sg <- example_surface_geometry() nv <- nrow(vertices(sg)) ns <- NeuroSurface(geometry = sg, indices = seq_len(nv), data = rnorm(nv)) write_surf_data(ns, file.path(tempdir(), "output_data"), "lh")sg <- example_surface_geometry() nv <- nrow(vertices(sg)) ns <- NeuroSurface(geometry = sg, indices = seq_len(nv), data = rnorm(nv)) write_surf_data(ns, file.path(tempdir(), "output_data"), "lh")