| Title: | Your Advanced 3D Brain Visualization |
|---|---|
| Description: | A fast, interactive cross-platform, and easy to share 'WebGL'-based 3D brain viewer that visualizes 'FreeSurfer' and/or 'AFNI/SUMA' surfaces. The viewer widget can be either standalone or embedded into 'R-shiny' applications. The standalone version only require a web browser with 'WebGL2' support (for example, 'Chrome', 'Firefox', 'Safari'), and can be inserted into any websites. The 'R-shiny' support allows the 3D viewer to be dynamically generated from reactive user inputs. Please check the publication by Wang, Magnotti, Zhang, and Beauchamp (2023, <doi:10.1523/ENEURO.0328-23.2023>) for electrode localization. This viewer has been fully adopted by 'RAVE' <https://rave.wiki>, an interactive toolbox to analyze 'iEEG' data by Magnotti, Wang, and Beauchamp (2020, <doi:10.1016/j.neuroimage.2020.117341>). Please check citation("threeBrain") for details. |
| Authors: | Zhengjia Wang [aut, cre, cph], Xiang Zhang [ctb, res], Brian Metzger [res], Elizabeth Nesbitt [res], Meng Li [ths], John Magnotti [ctb, res], Michael Beauchamp [ths, ctb, dtc] |
| Maintainer: | Zhengjia Wang <[email protected]> |
| License: | MPL-2.0 |
| Version: | 1.3.0.37 |
| Built: | 2026-06-02 18:45:59 UTC |
| Source: | https://github.com/dipterix/threeBrain |
Base class inherited by all geometry types in the three-brain viewer. Provides common fields for position, layer visibility, transformation, click response, and animation clips.
nameUnique character name of the geometry object.
typeGeometry type string used by the JavaScript engine.
render_orderRendering priority; higher values render on top.
time_stampDeprecated; use the keyframes field instead.
Numeric vector of animation time points.
valueDeprecated; use the keyframes field instead.
Numeric or character animation values.
keyframesNamed list of KeyFrame objects that store
animation clip data for this geometry.
positionNumeric vector of length 3: object origin in world space.
trans_matOptional 4-by-4 transformation matrix
(NULL = identity).
disable_trans_matLogical; when TRUE the transformation
matrix is ignored.
groupGeomGroup that owns this geometry, or NULL.
clickableLogical; whether the geometry responds to mouse clicks in the viewer.
layerCamera layer(s); 0 = main camera only, 1 = all cameras, 13 = invisible.
use_cacheLogical; whether to read/write data from a file cache.
custom_infoOptional character string for additional annotation.
subject_codeSubject identifier string, or NULL.
animation_typesCharacter vector of animation clip names attached to this geometry.
AbstractGeom$new()Create a new abstract geometry. Subclasses call this via
super$initialize().
AbstractGeom$new( name, position = c(0, 0, 0), group = NULL, layer = 0, trans_mat = NULL, ... )
nameUnique character name.
positionNumeric vector of length 3: object origin.
Default c(0, 0, 0).
groupGeomGroup to attach this geometry to, or
NULL.
layerCamera layer(s), 0-13. Default 0.
trans_matOptional 4-by-4 numeric transformation matrix.
...Reserved for subclass use.
AbstractGeom$set_position()Set the world-space position of the geometry.
AbstractGeom$set_position(...)
...Numeric values that together form a length-3 vector
c(x, y, z).
AbstractGeom$set_value()Attach animation data to this geometry as an animation clip.
AbstractGeom$set_value( value = NULL, time_stamp = NULL, name = "Value", target = ".material.color", ... )
valueNumeric or character vector of animation values.
time_stampNumeric vector of time points matching value.
nameCharacter clip name. Defaults to "Value".
targetJavaScript property path to animate.
...Additional arguments passed to KeyFrame.
AbstractGeom$to_list()Serialize the geometry to a named list for JSON export.
AbstractGeom$to_list()
AbstractGeom$get_data()Retrieve a data value from this geometry or its owning group.
AbstractGeom$get_data(key = "value", force_reload = FALSE, ifnotfound = NULL)
keyField name or group data key to retrieve. Default
"value".
force_reloadLogical; reload from the file cache even when an
in-memory copy exists. Default FALSE.
ifnotfoundValue returned when key is not found.
Default NULL.
AbstractGeom$animation_time_range()Return the time range of a named animation clip.
AbstractGeom$animation_time_range(ani_name)
ani_nameName of the animation clip.
AbstractGeom$animation_value_range()Return the value range of a named continuous animation clip.
AbstractGeom$animation_value_range(ani_name)
ani_nameName of the animation clip.
AbstractGeom$animation_value_names()Return the category level names of a named discrete animation clip.
AbstractGeom$animation_value_names(ani_name)
ani_nameName of the animation clip.
AbstractGeom$clone()The objects of this class are cloneable with this method.
AbstractGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
No-op geometry used when only shared group data needs to be uploaded to the viewer. The geometry renders nothing and is assigned to an invisible camera layer (31).
AbstractGeom -> BlankGeom
valueReserved; always NULL for blank geometry.
typeGeometry type string used by the JavaScript engine.
clickableLogical; whether the geometry responds to mouse clicks in the viewer.
BlankGeom$set_value()No-op value setter; blank geometry accepts no data.
BlankGeom$set_value(...)
...Ignored.
BlankGeom$new()Create a new blank geometry.
BlankGeom$new( group, name = paste(sample(c(LETTERS, letters, 0:9), 16), collapse = ""), ... )
groupGeomGroup to attach this geometry to.
nameUnique character name. Defaults to a random 16-character alphanumeric string.
...Additional arguments forwarded to AbstractGeom.
BlankGeom$to_list()Serialize the blank geometry to a named list for JSON export.
BlankGeom$to_list()
BlankGeom$clone()The objects of this class are cloneable with this method.
BlankGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Shiny Proxy for Viewer
brain_proxy(outputId, session = shiny::getDefaultReactiveDomain())brain_proxy(outputId, session = shiny::getDefaultReactiveDomain())
outputId |
shiny output ID |
session |
shiny session, default is current session (see |
R6 class ViewerProxy
Setup Package, Install Environment
brain_setup(continued = FALSE, show_example = TRUE, ...)brain_setup(continued = FALSE, show_example = TRUE, ...)
continued |
logical, there are two phases of setting up environment. You probably need to restart R session after the first phase and continue setting up. |
show_example |
whether to show example of 'N27' subject at the end. |
... |
ignored |
Zhengjia Wang
Calculate rotation matrix from non-zero vectors
calculate_rotation(vec_from, vec_to)calculate_rotation(vec_from, vec_to)
vec_from |
original vector, length of 3 |
vec_to |
vector after rotation, length of 3 |
A four-by-four transform matrix
Function to check whether 'FreeSurfer' folder has everything we need
check_freesurfer_path( fs_subject_folder, autoinstall_template = FALSE, return_path = FALSE, check_volume = FALSE, check_surface = FALSE )check_freesurfer_path( fs_subject_folder, autoinstall_template = FALSE, return_path = FALSE, check_volume = FALSE, check_surface = FALSE )
fs_subject_folder |
character, path to 'fs' project directory or 'RAVE' subject directory |
autoinstall_template |
logical, whether 'N27' brain should be installed if missing |
return_path |
logical, whether to return 'FreeSurfer' path |
check_volume |
logical, whether to check volume data |
check_surface |
logical, whether to check surface data (not implemented yet) |
logical whether the directory is valid or, if return_path is true,
return 'FreeSurfer' path
'FreeSurfer' wayReproduces conform algorithm used by 'FreeSurfer' to conform
'NIfTI' and 'MGH' images.
conform_volume(x, save_to, dim = c(256, 256, 256))conform_volume(x, save_to, dim = c(256, 256, 256))
x |
path to the image file |
save_to |
path where the conformed image will be saved, must ends with
|
dim |
positive integers of length three, the conformed dimension;
by default 'FreeSurfer' conform images to |
Nothing; the result will be save to save_to
Create a geometry group containing multiple geometries
create_group(name, position = c(0, 0, 0), layer = 1)create_group(name, position = c(0, 0, 0), layer = 1)
name |
string, name of the geometry |
position |
x,y,z location of the group |
layer |
layer of the group. reserved |
A geometry group is a container of multiple geometries. The geometries within the same group share the same shift and rotations (see example 1). In ECoG/iEEG world, you might have 'MRI', 'CT', 'FreeSurfer' that have different orientations. For example, if you want to align MRI to FreeSurfer, Instead of calculating the position of each geometries, you can just put all MRI components into a group, and then set transform of this group, making the group aligned to FreeSurfer.
GeomGroup also can be used to store large data. To generate 3D viewer, 'threeBrain' needs to dynamically serialize data into JSON format, which can be read by browsers. However, a FreeSurfer brain might be ~30 MB. This is a very large size and might take ~5 seconds to serialize. To solve this problem, GeomGroup supports cache in its 'set_group_data' method. This method supports caching static serialized data into a JSON file, and allows the files to be loaded as static data objects. By "static", I mean the data is not supposed to be dynamic, and it should be "read-only". In JavaScript code, I also optimized such that you don't need to load these large datasets repeatedly. And this allows you to load multiple subjects' brain in a short time.
a GeomGroup instance
Zhengjia Wang
# Example 1: relative position # create group g = create_group('Group A') # create two spheres at 10,0,0, but s2 is relative to group A s1 = geom_sphere('Sphere 1', radius = 2, position = c(10,0,0)) s2 = geom_sphere('Sphere 2', radius = 2, position = c(10,0,0), group = g) # set transform (rotation) g$set_transform(matrix(c( 0,1,0,0, 1,0,0,0, 0,0,1,0, 0,0,0,1 ), byrow = TRUE, ncol = 4)) # global position for s2 is 0,10,0 if( interactive() ) { threejs_brain(s1, s2) } # Example 2: cache ## Not run: # download N27 brain # Make sure you have N27 brain downloaded to `default_template_directory()` # download_N27() template_dir <- default_template_directory() dat = freesurferformats::read.fs.surface( file.path(template_dir, 'N27/surf/lh.pial') ) vertex = dat$vertices[,1:3] face = dat$faces[,1:3] # 1. dynamically serialize mesh = geom_freemesh('lh', vertex = vertex, face = face, layer = 1) # 2. cache # Create group, all geometries in this group are relatively positioned tmp_file = tempfile() mesh = geom_freemesh('Left Hemisphere cached', vertex = vertex, face = face, cache_file = tmp_file) ## End(Not run)# Example 1: relative position # create group g = create_group('Group A') # create two spheres at 10,0,0, but s2 is relative to group A s1 = geom_sphere('Sphere 1', radius = 2, position = c(10,0,0)) s2 = geom_sphere('Sphere 2', radius = 2, position = c(10,0,0), group = g) # set transform (rotation) g$set_transform(matrix(c( 0,1,0,0, 1,0,0,0, 0,0,1,0, 0,0,0,1 ), byrow = TRUE, ncol = 4)) # global position for s2 is 0,10,0 if( interactive() ) { threejs_brain(s1, s2) } # Example 2: cache ## Not run: # download N27 brain # Make sure you have N27 brain downloaded to `default_template_directory()` # download_N27() template_dir <- default_template_directory() dat = freesurferformats::read.fs.surface( file.path(template_dir, 'N27/surf/lh.pial') ) vertex = dat$vertices[,1:3] face = dat$faces[,1:3] # 1. dynamically serialize mesh = geom_freemesh('lh', vertex = vertex, face = face, layer = 1) # 2. cache # Create group, all geometries in this group are relatively positioned tmp_file = tempfile() mesh = geom_freemesh('Left Hemisphere cached', vertex = vertex, face = face, cache_file = tmp_file) ## End(Not run)
Calculate cross-product of two vectors in '3D'
cross_prod(x, y)cross_prod(x, y)
x, y
|
3-dimensional vectors |
A '3D' vector that is the cross-product of x and y
Volumetric data cube geometry for rendering 3D scalar volumes as voxel
data. Stores a flat value array and its 3D dimensions in the owning
GeomGroup for JSON export to the three-brain viewer.
AbstractGeom -> DataCubeGeom
typeGeometry type string ("datacube").
clickableLogical; always FALSE for volume geometry.
DataCubeGeom$new()Create a new data cube geometry.
DataCubeGeom$new( name, value, dim = dim(value), group = GeomGroup$new(name = "default"), position = c(0, 0, 0), cache_file = NULL, layer = 13, digest = TRUE, ... )
nameUnique character name.
valueNumeric vector or array of voxel values.
dimInteger vector of length 3: dimensions of the volume
(c(nx, ny, nz)).
groupGeomGroup used to store the voxel data.
positionNumeric vector of length 3: geometry origin.
Default c(0, 0, 0).
cache_filePath to a JSON cache file, TRUE for a
temporary file, or NULL to keep data in memory.
layerCamera layer. Default 13 (invisible).
digestLogical; compute a content digest for cache validation.
...Additional arguments forwarded to AbstractGeom.
DataCubeGeom$set_value()Update the voxel values of the geometry (not yet
implemented; currently calls .NotYetImplemented()).
DataCubeGeom$set_value(value = NULL, dim = dim(value))
valueNumeric vector of replacement voxel values.
dimInteger vector of length 3: dimensions matching value.
DataCubeGeom$to_list()Serialize the data cube geometry to a named list for JSON
export, adding the isDataCube flag.
DataCubeGeom$to_list()
DataCubeGeom$get_data()Retrieve a data value from this geometry or its owning group.
DataCubeGeom$get_data(key, force_reload = FALSE, ifnotfound = NULL)
keyGroup data key to retrieve.
force_reloadLogical; reload from the file cache even when an
in-memory copy exists. Default FALSE.
ifnotfoundValue returned when key is not found.
Default NULL.
DataCubeGeom$clone()The objects of this class are cloneable with this method.
DataCubeGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Volumetric data cube geometry rendered via a 3D texture lookup.
Extends DataCubeGeom with four-channel color map support and opacity
thresholding.
AbstractGeom -> DataCubeGeom -> DataCubeGeom2
typeGeometry type string ("datacube2").
clickableLogical; always FALSE for volume geometry.
thresholdOpacity threshold: voxel values below this level are
rendered as transparent. Default 0.6.
color_formatWebGL texture format string; either
"RGBAFormat" or "RedFormat".
color_mapNamed list describing the four-channel color map applied
to the volume, or NULL.
trans_space_fromCoordinate space of the input data before
applying the transformation matrix; either "model" (default)
or "scannerRAS".
is_datacube2Logical flag; always TRUE for
DataCubeGeom2 instances.
DataCubeGeom2$new()Create a new data cube geometry using a 3D texture.
DataCubeGeom2$new(
name,
value,
dim = dim(value),
half_size = c(128, 128, 128),
group = GeomGroup$new(name = "default"),
position = c(0, 0, 0),
color_format = c("RGBAFormat", "RedFormat"),
cache_file = NULL,
layer = 8,
digest = TRUE,
...
)
nameUnique character name.
valueInteger vector of voxel values (0-255).
dimInteger vector of length 3: dimensions of the volume.
half_sizeNumeric vector of length 3: half-extents of the
bounding box in world-space units. Default c(128, 128, 128).
groupGeomGroup used to store the voxel data.
positionNumeric vector of length 3: geometry origin.
color_formatWebGL texture format: "RGBAFormat" (default)
or "RedFormat".
cache_filePath to a JSON cache file, TRUE for a
temporary file, or NULL to keep data in memory.
layerCamera layer. Default 8 (main camera only).
digestLogical; compute a content digest for cache validation.
...Additional arguments forwarded to DataCubeGeom.
DataCubeGeom2$to_list()Serialize the texture data cube geometry to a named list
for JSON export, adding threshold, color_format,
color_map, isDataCube2, and trans_space_from.
DataCubeGeom2$to_list()
DataCubeGeom2$clone()The objects of this class are cloneable with this method.
DataCubeGeom2$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Default Directory to Store Template Brain
default_template_directory(check = FALSE)default_template_directory(check = FALSE)
check |
logical, check if the folder is missing, is so, create one. This option ensures the folder is always created. |
When threeBrain.template_dir is not set or invalid, the
function checks 'RAVE' (R Analysis and Visualization for 'iEEG',
https://rave.wiki) folder at home directory. If
this folder is missing, then returns results from
R_user_dir('threeBrain', 'data'). To override the default behavior,
use options(threeBrain.template_dir=...).
A directory path where template brain is stored at; see also
download_N27
default_template_directory()default_template_directory()
Geometry defined by explicit vertex coordinates and face indices, used primarily for brain surface meshes. Supports per-vertex color animation and FreeSurfer annotation overlays.
Zhengjia Wang
Query the 'FreeSurfer' labels
freesurfer_lutfreesurfer_lut
The 'FreeSurfer' atlases use
https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT
look-up table to query indexes. The 'threeBrain' electrode localization
also uses this table to export the 'FSLabel' from electrode. If
volume type is set to 'aparc_aseg', then please also use this
table to filter.
freesurfer_lut$from_key(0:10) freesurfer_lut$get_key("ctx-lh-supramarginal")freesurfer_lut$from_key(0:10) freesurfer_lut$get_key("ctx-lh-supramarginal")
This is a low-level function. Use brain$add_annotation instead.
generate_cortical_parcellation( brain, template_subject = "fsaverage", annotation = "Yeo2011_7Networks_N1000", add_annotation = TRUE )generate_cortical_parcellation( brain, template_subject = "fsaverage", annotation = "Yeo2011_7Networks_N1000", add_annotation = TRUE )
brain |
Brain object |
template_subject |
template subject where the annotation is stored |
annotation |
annotation name in the label folder; default is
|
add_annotation |
whether to add annotation to |
brain with the annotation added if add_annotation
is true
Alternative to 'Matlab' version of 'pial-outer-smoothed',
use this function along with fill_surface.
generate_smooth_envelope( surface_path, save_as = NULL, inflate = 3, verbose = TRUE, save_format = c("auto", "bin", "asc", "vtk", "ply", "off", "obj", "gii", "mz3", "byu") )generate_smooth_envelope( surface_path, save_as = NULL, inflate = 3, verbose = TRUE, save_format = c("auto", "bin", "asc", "vtk", "ply", "off", "obj", "gii", "mz3", "byu") )
surface_path |
path to |
save_as |
save final envelope to path, or |
inflate |
number of |
verbose |
whether to verbose the progress; default is true |
save_format |
format of saved file when |
A 3-dimensional mesh that contains vertices and face indices,
the result is also saved to save_as is specified.
if(interactive() && file.exists(file.path(default_template_directory(), "N27"))) { library(threeBrain) fs_path <- file.path(default_template_directory(), "N27") # lh.pial-outer-smoothed lh_pial <- file.path(fs_path, "surf", "lh.pial") save_as <- file.path(fs_path, "surf", "lh.pial-outer-smoothed") generate_smooth_envelope(lh_pial, save_as) # rh.pial-outer-smoothed rh_pial <- file.path(fs_path, "surf", "rh.pial") save_as <- file.path(fs_path, "surf", "rh.pial-outer-smoothed") generate_smooth_envelope(rh_pial, save_as) brain <- threeBrain( path = fs_path, subject_code = "N27", surface_types = 'pial-outer-smoothed' ) brain$plot(controllers = list( "Surface Type" = 'pial-outer-smoothed' )) }if(interactive() && file.exists(file.path(default_template_directory(), "N27"))) { library(threeBrain) fs_path <- file.path(default_template_directory(), "N27") # lh.pial-outer-smoothed lh_pial <- file.path(fs_path, "surf", "lh.pial") save_as <- file.path(fs_path, "surf", "lh.pial-outer-smoothed") generate_smooth_envelope(lh_pial, save_as) # rh.pial-outer-smoothed rh_pial <- file.path(fs_path, "surf", "rh.pial") save_as <- file.path(fs_path, "surf", "rh.pial-outer-smoothed") generate_smooth_envelope(rh_pial, save_as) brain <- threeBrain( path = fs_path, subject_code = "N27", surface_types = 'pial-outer-smoothed' ) brain$plot(controllers = list( "Surface Type" = 'pial-outer-smoothed' )) }
Superseded by volume_to_surf. Please do not use this function.
generate_subcortical_surface( atlas, index, save_prefix = NULL, label = NULL, IJK2RAS = NULL, grow = 1, remesh = TRUE, smooth = TRUE, smooth_delta = 3, ... )generate_subcortical_surface( atlas, index, save_prefix = NULL, label = NULL, IJK2RAS = NULL, grow = 1, remesh = TRUE, smooth = TRUE, smooth_delta = 3, ... )
atlas |
path to imaging 'parcellation', can be |
index |
'parcellation' index, see 'FreeSurfer' look-up table |
save_prefix |
parent folder to save the resulting surface |
label |
character label or name of the 'sub-cortical' structure, usually automatically derived from |
IJK2RAS |
an 'Affine' matrix from 'voxel' index to |
grow |
amount to grow (dilate) before generating mesh |
remesh, smooth, smooth_delta, ...
|
passed to |
A surface mesh, containing 'atlas' index, label, surface nodes and face indices.
Creates any mesh geometry given vertices and face indices
geom_freemesh( name, vertex = NULL, face = NULL, position = c(0, 0, 0), layer = 1, cache_file = NULL, group = NULL )geom_freemesh( name, vertex = NULL, face = NULL, position = c(0, 0, 0), layer = 1, cache_file = NULL, group = NULL )
name |
unique string in a scene to tell apart from different objects |
vertex |
position of each vertices (3 columns) |
face |
face indices indicating which 3 vertices to be linked (3 columns) |
position |
x,y,z location of the geometry |
layer |
visibility of the geometry, used when there are multiple cameras 1 is visible for all cameras |
cache_file |
cache vertex and face data into group |
group |
a GeomGroup object, if null, then the group will be generated automatically |
When generating a free mesh internally, a group must be specified,
therefore if group is NULL here, then a group will be generated.
However, it's always recommended to pass a group to the free mesh.
Zhengjia Wang
## Not run: # Make sure you have N27 brain downloaded to `default_template_directory()` # threeBrain::download_N27() n27_dir = file.path(default_template_directory(), "N27") surf_type = 'pial' # Locate mesh files lh = read_fs_asc(file.path(n27_dir, sprintf('surf/lh.%s.asc', surf_type))) rh = read_fs_asc(file.path(n27_dir, sprintf('surf/rh.%s.asc', surf_type))) # Create groups group = create_group(name = sprintf('Surface - %s (N27)', surf_type)) # create mesh lh_mesh = geom_freemesh( name = sprintf('FreeSurfer Left Hemisphere - %s (N27)', surf_type), vertex = lh$vertices[,1:3], face = lh$faces[,1:3], group = group ) rh_mesh = geom_freemesh( name = sprintf('FreeSurfer Right Hemisphere - %s (N27)', surf_type), vertex = rh$vertices[,1:3], face = rh$faces[,1:3], group = group ) # Render if( interactive() ) { threejs_brain(lh_mesh, rh_mesh) } ## End(Not run)## Not run: # Make sure you have N27 brain downloaded to `default_template_directory()` # threeBrain::download_N27() n27_dir = file.path(default_template_directory(), "N27") surf_type = 'pial' # Locate mesh files lh = read_fs_asc(file.path(n27_dir, sprintf('surf/lh.%s.asc', surf_type))) rh = read_fs_asc(file.path(n27_dir, sprintf('surf/rh.%s.asc', surf_type))) # Create groups group = create_group(name = sprintf('Surface - %s (N27)', surf_type)) # create mesh lh_mesh = geom_freemesh( name = sprintf('FreeSurfer Left Hemisphere - %s (N27)', surf_type), vertex = lh$vertices[,1:3], face = lh$faces[,1:3], group = group ) rh_mesh = geom_freemesh( name = sprintf('FreeSurfer Right Hemisphere - %s (N27)', surf_type), vertex = rh$vertices[,1:3], face = rh$faces[,1:3], group = group ) # Render if( interactive() ) { threejs_brain(lh_mesh, rh_mesh) } ## End(Not run)
Create sphere geometry
geom_sphere( name, radius, position = c(0, 0, 0), layer = 1, group = NULL, value = NULL, time_stamp = NULL )geom_sphere( name, radius, position = c(0, 0, 0), layer = 1, group = NULL, value = NULL, time_stamp = NULL )
name |
unique string in a scene to tell apart from different objects |
radius |
size of sphere |
position |
x,y,z location of the sphere |
layer |
visibility of the geometry, used when there are multiple cameras 1 is visible for all cameras |
group |
a GeomGroup object |
value, time_stamp
|
color of the sphere, used for animation/color rendering |
Zhengjia Wang
# Create a sphere with animation g = lapply(1:10, function(ii) { v = rep(ii, 10) v[1:ii] = 1:ii geom_sphere(paste0('s', ii), ii, value = v, position = c(11 * ii, 0,0), time_stamp = (1:10)/10) }) if( interactive() ) { threejs_brain(.list = g) }# Create a sphere with animation g = lapply(1:10, function(ii) { v = rep(ii, 10) v[1:ii] = 1:ii geom_sphere(paste0('s', ii), ii, value = v, position = c(11 * ii, 0,0), time_stamp = (1:10)/10) }) if( interactive() ) { threejs_brain(.list = g) }
Container that collects geometry objects belonging to the same logical group in the three-brain viewer. Manages shared data, an optional 4-by-4 transformation matrix, spatial position, and a local file cache.
nameUnique character name of the group.
layerCamera layer(s); 0 = main camera only, 1 = all cameras, 13 = invisible.
positionNumeric vector of length 3: group origin in world space.
group_dataNamed list of shared data attached to the group.
trans_matOptional 4-by-4 transformation matrix
(NULL for identity).
cached_itemsCharacter vector of group data keys stored in the file cache.
cache_envLocal environment used for in-memory caching of loaded cache files.
cache_pathDirectory path for the file cache.
disable_trans_matLogical; when TRUE the transformation
matrix is ignored during rendering.
parent_groupName of the parent group, or NULL.
subject_codeSubject identifier string, or NULL.
.cache_nameOverride for the sanitized cache directory name.
When NULL the name is derived from $name by replacing
non-alphanumeric characters with underscores.
GeomGroup$cache_name()Return the sanitized cache directory name for this group.
Uses .cache_name when set, otherwise derives the name from
$name by replacing non-alphanumeric characters with
underscores.
GeomGroup$cache_name()
GeomGroup$set_transform()Set or clear the 4-by-4 transformation matrix for the group.
GeomGroup$set_transform(mat = NULL)
matA 4-by-4 numeric matrix, or NULL to use the identity
transform.
GeomGroup$new()Create a new geometry group.
GeomGroup$new( name, layer = 0, position = c(0, 0, 0), cache_path = tempfile(), parent = NULL )
nameUnique character name for the group.
layerCamera layer(s), 0-13. Default 0.
positionNumeric vector of length 3: group origin.
Default c(0, 0, 0).
cache_pathDirectory path for caching serialized data.
parentName or GeomGroup object of the parent group,
or NULL.
GeomGroup$set_group_data()Attach a named data object to the group, optionally storing it in the file cache.
GeomGroup$set_group_data( name, value, is_cached = FALSE, cache_if_not_exists = FALSE )
nameKey name for the data object.
valueData to store.
is_cachedLogical; whether value is already a cache
descriptor list.
cache_if_not_existsLogical; write value to the file cache
when no cache file exists yet.
GeomGroup$get_data()Retrieve a data object from the group by key, loading from the file cache when necessary.
GeomGroup$get_data(key, force_reload = FALSE, ifnotfound = NULL)
keyName of the data object to retrieve.
force_reloadLogical; reload from the file cache even when an in-memory copy exists.
ifnotfoundValue returned when key is not found.
GeomGroup$to_list()Serialize the group to a named list for JSON export.
GeomGroup$to_list()
GeomGroup$clone()The objects of this class are cloneable with this method.
GeomGroup$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Function to read digest header
get_digest_header(file, key, if_error = NULL, .list = NULL)get_digest_header(file, key, if_error = NULL, .list = NULL)
file |
file path to a 'JSON' file |
key |
character, key to extract |
if_error |
value to return if key not found or read error occurs |
.list |
alternative list to supply if file is missing |
Get 'voxel' to world matrix
get_ijk2ras(x, type = c("scanner", "tkr"))get_ijk2ras(x, type = c("scanner", "tkr"))
x |
path to imaging files |
type |
world space type; choices are |
A four by four matrix
Import from 'FreeSurfer' and create 'JSON' cache for 3D viewer
import_from_freesurfer(fs_path, subject_name, quiet = FALSE)import_from_freesurfer(fs_path, subject_name, quiet = FALSE)
fs_path |
'FreeSurfer' subject directory |
subject_name |
subject code |
quiet |
whether to suppress message or not |
None.
Import 'T1-MRI', surface files, curvature/'sulcus', atlas, and
'Talairach' transform matrix into 'json' format. These functions are not
intended to be called directly, use import_from_freesurfer
instead.
import_fs( subject_name, fs_path, quiet = FALSE, dtype = c("T1", "surface", "curv", "atlas_volume", "atlas_surface", "xform"), sub_type = NULL, hemisphere = c("l", "r"), ... ) import_suma( subject_name, fs_path, quiet = FALSE, dtype = c("T1", "surface", "curv", "atlas_volume", "atlas_surface", "xform"), sub_type = NULL, hemisphere = c("l", "r"), ... )import_fs( subject_name, fs_path, quiet = FALSE, dtype = c("T1", "surface", "curv", "atlas_volume", "atlas_surface", "xform"), sub_type = NULL, hemisphere = c("l", "r"), ... ) import_suma( subject_name, fs_path, quiet = FALSE, dtype = c("T1", "surface", "curv", "atlas_volume", "atlas_surface", "xform"), sub_type = NULL, hemisphere = c("l", "r"), ... )
subject_name |
character, subject code |
fs_path |
path to 'FreeSurfer' folder |
quiet, ...
|
passed from or to other methods. |
dtype |
data type to import, choices are |
sub_type |
detailed files to import. |
hemisphere |
which hemisphere to import, ignored when |
logical, TRUE if the file is or has been cached, or
FALSE if the file is missing.
Line-segment geometry for drawing connections or paths in the three-brain viewer. Vertices may be static numeric coordinates or dynamic electrode references resolved at render time.
AbstractGeom -> LineSegmentsGeom
typeGeometry type string ("linesegments").
colorCSS hex color string(s) applied to line segments.
sizeLine width(s) in world-space units.
verticesVertex positions: a numeric matrix (3 x N) for static segments, or a list of position/electrode descriptors for dynamic segments.
dynamicLogical; TRUE when vertices are electrode
references resolved at render time rather than static coordinates.
LineSegmentsGeom$new()Create a new line-segment geometry.
LineSegmentsGeom$new(name, dynamic = FALSE, ...)
nameUnique character name.
dynamicLogical; when TRUE vertices are electrode
references resolved at render time rather than fixed coordinates.
...Additional arguments forwarded to AbstractGeom.
LineSegmentsGeom$set_vertices()Set vertex positions for the line segments.
LineSegmentsGeom$set_vertices(..., .list = list(), append = FALSE)
...Positions as numeric vectors of length 3 (static mode) or
named lists with subject_code and electrode elements
(dynamic mode).
.listAdditional positions supplied as a list.
appendLogical; when TRUE append rather than replace.
LineSegmentsGeom$set_color()Set the color(s) of the line segments.
LineSegmentsGeom$set_color(...)
...One or more R color values (names, hex strings, or integer palette indices) that are interpolated across all segments.
LineSegmentsGeom$set_size()Set the line width(s).
LineSegmentsGeom$set_size(...)
...One or more positive numbers interpolated across all segments.
LineSegmentsGeom$to_list()Serialize the line-segment geometry to a named list for JSON export.
LineSegmentsGeom$to_list()
LineSegmentsGeom$clone()The objects of this class are cloneable with this method.
LineSegmentsGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
List all built-in and user-customized electrode prototypes. User paths will be searched first, if multiple prototype configuration files are found for the same type.
list_electrode_prototypes() load_prototype(type)list_electrode_prototypes() load_prototype(type)
type |
electrode type, character |
list_electrode_prototypes returns a named list, names are
the prototype types and values are the prototype configuration paths;
load_prototype returns the prototype instance if type exists,
or throw an error.
availables <- list_electrode_prototypes() if( "sEEG-16" %in% names(availables) ) { proto <- load_prototype( "sEEG-16" ) print(proto, details = FALSE) }availables <- list_electrode_prototypes() if( "sEEG-16" %in% names(availables) ) { proto <- load_prototype( "sEEG-16" ) print(proto, details = FALSE) }
If 'RAVE' has been installed, please use 'RAVE' modules. This function is purely for demonstration purposes.
localization_module( subject_code, fs_path, ct_path = NULL, surfaces = "pial", use_141 = TRUE, shiny_options = list(launch.browser = TRUE), save_path = tempfile(pattern = "electrode", fileext = ".csv"), ..., control_presets = NULL, side_display = FALSE, controllers = list() )localization_module( subject_code, fs_path, ct_path = NULL, surfaces = "pial", use_141 = TRUE, shiny_options = list(launch.browser = TRUE), save_path = tempfile(pattern = "electrode", fileext = ".csv"), ..., control_presets = NULL, side_display = FALSE, controllers = list() )
subject_code |
subject code |
fs_path |
the subject's 'FreeSurfer' path |
ct_path |
the file path of 'CT' scans that have already been aligned to 'T1'; must be in 'NIFTI' format |
surfaces |
which surfaces to load |
use_141 |
whether to try 'SUMA' standard 141 surface; default is true |
shiny_options |
shiny application options; see |
save_path |
a temporary file where the electrode table should be cached; this file will be used to keep track of changes in case the application is crashed or shutdown |
... |
other parameters to pass into |
control_presets, side_display, controllers
|
passed to
|
A list of 'ui' elements, 'server' function, and
a stand-alone 'app'
# This example require N27 template brain to be installed # see `?download_N27` for details # using N27 to localize fs_path <- file.path(default_template_directory(), "N27") if(interactive() && dir.exists(fs_path)) { module <- localization_module("N27", fs_path) print(module$app) }# This example require N27 template brain to be installed # see `?download_N27` for details # using N27 to localize fs_path <- file.path(default_template_directory(), "N27") if(interactive() && dir.exists(fs_path)) { module <- localization_module("N27", fs_path) print(module$app) }
Create Multi-subject Template
merge_brain( ..., .list = NULL, template_surface_types = NULL, template_subject = unname(getOption("threeBrain.template_subject", "N27")), template_dir = default_template_directory(), electrode_priority = c("asis", "sphere", "prototype", "both") )merge_brain( ..., .list = NULL, template_surface_types = NULL, template_subject = unname(getOption("threeBrain.template_subject", "N27")), template_dir = default_template_directory(), electrode_priority = c("asis", "sphere", "prototype", "both") )
..., .list
|
|
template_surface_types |
which template surface types to load, default is auto-guess |
template_subject |
character, subject code to be treated as template, default is 'N27' |
template_dir |
the parent directory where template subject is stored in |
electrode_priority |
electrode shape priority, used to manage how
electrodes are displayed; default is |
Zhengjia Wang
Create or load new electrode prototype from existing configurations
new_electrode_prototype(base_prototype, modifier = NULL)new_electrode_prototype(base_prototype, modifier = NULL)
base_prototype |
base prototype, this can be a string of prototype type
(see |
modifier |
internally used |
An electrode prototype instance
available_prototypes <- list_electrode_prototypes() if("Precision33x31" %in% names(available_prototypes)) { # Load by type name new_electrode_prototype("Precision33x31") # load by path path <- available_prototypes[["Precision33x31"]] new_electrode_prototype(path) # load by json string json <- readLines(path) new_electrode_prototype(json) }available_prototypes <- list_electrode_prototypes() if("Precision33x31" %in% names(available_prototypes)) { # Load by type name new_electrode_prototype("Precision33x31") # load by path path <- available_prototypes[["Precision33x31"]] new_electrode_prototype(path) # load by json string json <- readLines(path) new_electrode_prototype(json) }
Plot slices of volume
plot_slices( volume, overlays = NULL, transform = NULL, positions = NULL, zoom = 1, pixel_width = 0.5, col = c("black", "white"), normalize = NULL, zclip = NULL, overlay_alpha = 0.3, zlim = normalize, main = "", title_position = c("left", "top"), fun = NULL, nc = NA, which = NULL, ... )plot_slices( volume, overlays = NULL, transform = NULL, positions = NULL, zoom = 1, pixel_width = 0.5, col = c("black", "white"), normalize = NULL, zclip = NULL, overlay_alpha = 0.3, zlim = normalize, main = "", title_position = c("left", "top"), fun = NULL, nc = NA, which = NULL, ... )
volume |
path to volume (underlay) |
overlays |
images to overlay on top of the underlay, can be either
a vector of paths to the overlay volume images, or a sequence of named lists.
Each list item has |
transform |
rotation of the volume in scanner |
positions |
vector of length 3 or matrix of 3 columns, the |
zoom |
zoom-in radio, default is 1 |
pixel_width |
output image pixel resolution; default is |
col |
color palette, can be a sequence of colors |
normalize |
range for volume data to be normalized; either |
zclip |
clip image densities; if specified, values outside of this range will be clipped into this range |
overlay_alpha |
transparency of the overlay; default is 0.3 |
zlim |
image plot value range, default is identical to |
main |
image titles |
title_position |
title position; choices are |
fun |
function with two arguments that will be executed after each image is drawn; can be used to draw cross-hairs or annotate each image |
nc |
number of "columns" in the plot when there are too many positions,
must be positive integer; default is |
which |
which plane to plot; default is |
... |
additional arguments passing into |
Nothing
Read 'FreeSurfer' ascii file
read_fs_asc(file)read_fs_asc(file)
file |
file location |
a list of vertices and face indices
Read FreeSurfer Annotations
read_fs_labels(path, vertex_number)read_fs_labels(path, vertex_number)
path |
label path |
vertex_number |
force to reset vertex number if raw file is incorrect |
Read 'FreeSurfer' m3z file
read_fs_m3z(filename)read_fs_m3z(filename)
filename |
file location, usually located at 'mri/transforms/talairach.m3z' |
An 'm3z' file is a 'gzip' binary file containing a dense vector field that describes a 3D registration between two volumes/images. This implementation follows the 'Matlab' implementation from the 'FreeSurfer'. This function is released under the 'FreeSurfer' license: https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferSoftwareLicense.
registration data
Read 'FreeSurfer' 'mgz/mgh' file
read_fs_mgh_mgz(filename)read_fs_mgh_mgz(filename)
filename |
file location |
list contains coordinate transforms and volume data
The function 'read_gii2' is a dynamic wrapper of Python 'nibabel' loader. If no Python is detected, it will switch to 'gifti::readgii'.
read_gii2(path)read_gii2(path)
path |
'Gifti' file path |
An R function acting as safe wrapper for nibabel.load.
The function 'read_mgz' is a dynamic wrapper of Python 'nibabel' loader. If no Python is detected, it will switch to built-in function 'read_fs_mgh_mgz', which has limited features.
read_mgz(path)read_mgz(path)
path |
'mgz/mgh' file path |
An R function acting as safe wrapper for nibabel.load.
'MGH' or 'Nifti' formatsRead volume file in 'MGH' or 'Nifti' formats
read_volume(file, format = c("auto", "mgh", "nii"), header_only = FALSE)read_volume(file, format = c("auto", "mgh", "nii"), header_only = FALSE)
file |
file path |
format |
the file format |
header_only |
whether only read headers; default is false |
A list of volume data and transform matrices; if
header_only=TRUE, then volume data will be substituted by the
header.
Shiny Renderer for threeBrain Widgets
expr |
R expression that calls three_brain function or Brain object |
env |
environment of expression to be evaluated |
quoted |
is expr quoted? Default is false. |
Zhengjia Wang
Function to reshape data to 'RAS' order
reorient_volume(volume, Torig)reorient_volume(volume, Torig)
volume |
3-mode tensor (voxels), usually from 'mgz', 'nii', or 'BRIK' files |
Torig |
a |
Reshaped tensor with dimensions corresponding to 'R', 'A', and 'S'
Save threeBrain widgets to local file system
save_brain(widget, path, title = "3D Viewer", as_zip = FALSE, ...)save_brain(widget, path, title = "3D Viewer", as_zip = FALSE, ...)
widget |
generated from function 'threejs_brain' |
path |
path to save the brain widget |
title |
widget title. |
as_zip |
whether to create zip file "compressed.zip". |
... |
ignored, used for backward compatibility |
Zhengjia Wang
'sEEG' shaft geometry prototypeIntended for creating/editing geometry prototype, please see
load_prototype to load existing prototype
seeg_prototype( type, center_position, contact_widths, diameter = 1, channel_order = seq_along(center_position), fix_contact = 1, overall_length = 200, description = NULL, dry_run = FALSE, default_interpolation = NULL, viewer_options = NULL, behnke_fried = FALSE, overwrite = FALSE )seeg_prototype( type, center_position, contact_widths, diameter = 1, channel_order = seq_along(center_position), fix_contact = 1, overall_length = 200, description = NULL, dry_run = FALSE, default_interpolation = NULL, viewer_options = NULL, behnke_fried = FALSE, overwrite = FALSE )
type |
type string and unique identifier of the prototype |
center_position |
numerical vector, contact center positions |
contact_widths |
numerical vector or length of one, width or widths of the contacts |
diameter |
probe diameter |
channel_order |
the channel order of the contacts; default is a sequence along the number |
fix_contact |
|
overall_length |
probe length, default is |
description |
prototype description |
dry_run |
whether not to save the prototype configurations |
default_interpolation |
default interpolation string for electrode localization |
viewer_options |
list of viewer options; this should be a list of key-value pairs where the keys are the controller names and values are the corresponding values when users switch to localizing the electrode group |
behnke_fried |
whether the electrode has micro-wires at the tip; default is false |
overwrite |
whether to overwrite existing configuration file; default is false, which throws a warning when duplicated |
A electrode shaft geometry prototype; the configuration file is saved to 'RAVE' 3rd-party repository.
probe_head <- 2 n_contacts <- 12 width <- 2.41 contact_spacing <- 5 overall_length <- 400 diameter <- 1.12 contacts <- probe_head + width / 2 + 0:(n_contacts-1) * contact_spacing proto <- seeg_prototype( type = "AdTech-sEEG-SD12R-SP05X-000", description = c( "AdTech sEEG - 12 contacts", "Contact length : 2.41 mm", "Central spacing : 5 mm", "Tip size : 2 mm", "Diameter : 1.12 mm" ), center_position = contacts, contact_widths = width, diameter = diameter, overall_length = overall_length, dry_run = TRUE ) print(proto, details = FALSE)probe_head <- 2 n_contacts <- 12 width <- 2.41 contact_spacing <- 5 overall_length <- 400 diameter <- 1.12 contacts <- probe_head + width / 2 + 0:(n_contacts-1) * contact_spacing proto <- seeg_prototype( type = "AdTech-sEEG-SD12R-SP05X-000", description = c( "AdTech sEEG - 12 contacts", "Contact length : 2.41 mm", "Central spacing : 5 mm", "Tip size : 2 mm", "Diameter : 1.12 mm" ), center_position = contacts, contact_widths = width, diameter = diameter, overall_length = overall_length, dry_run = TRUE ) print(proto, details = FALSE)
Sphere geometry for the three-brain viewer. Wraps a three-brain viewer sphere and supports animation clips for electrode-style data visualization.
AbstractGeom -> SphereGeom
typeGeometry type string ("sphere").
radiusSphere radius in world-space units.
width_segmentsNumber of horizontal segments (longitude).
height_segmentsNumber of vertical segments (latitude).
SphereGeom$new()Create a new sphere geometry.
SphereGeom$new(name, position = c(0, 0, 0), radius = 5, ...)
nameUnique character name.
positionNumeric vector of length 3: sphere center.
Default c(0, 0, 0).
radiusSphere radius in world-space units. Default 5.
...Additional arguments forwarded to AbstractGeom.
SphereGeom$to_list()Serialize the sphere geometry to a named list for JSON export.
SphereGeom$to_list()
SphereGeom$clone()The objects of this class are cloneable with this method.
SphereGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Image sprite geometry that positions a PNG texture billboard between two 3D points. The image is encoded as a data URI and rendered facing the camera in the three-brain viewer.
AbstractGeom -> SpriteGeom
clickableLogical; always FALSE for sprite geometry.
typeGeometry type string ("imagesprite").
image_uriBase64 data URI of the PNG image used as the sprite texture.
aspect_ratioWidth-to-height ratio of the source image, used to preserve proportions when scaling.
SpriteGeom$new()Create a new image sprite geometry.
SpriteGeom$new( name, image_path, entry_position = c(1, 0, 0), target_position = c(0, 0, 0), ... )
nameUnique character name.
image_pathPath to a PNG image file on disk.
entry_positionNumeric vector of length 3: one end of the sprite
axis (e.g. electrode entry point). Default c(1, 0, 0).
target_positionNumeric vector of length 3: the other end of the
sprite axis (e.g. electrode target point). Default c(0, 0, 0).
...Additional arguments forwarded to AbstractGeom.
SpriteGeom$to_list()Serialize the sprite geometry to a named list for JSON export.
SpriteGeom$to_list()
SpriteGeom$clone()The objects of this class are cloneable with this method.
SpriteGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Download and Manage Template Subjects
download_template_subject( subject_code = "N27", url, template_dir = default_template_directory() ) download_N27(make_default = FALSE, ...) set_default_template( subject_code, view = TRUE, template_dir = default_template_directory() ) threebrain_finalize_installation( upgrade = c("ask", "always", "never", "data-only", "config-only"), async = TRUE ) available_templates()download_template_subject( subject_code = "N27", url, template_dir = default_template_directory() ) download_N27(make_default = FALSE, ...) set_default_template( subject_code, view = TRUE, template_dir = default_template_directory() ) threebrain_finalize_installation( upgrade = c("ask", "always", "never", "data-only", "config-only"), async = TRUE ) available_templates()
subject_code |
character with only letters and numbers (Important); default is 'N27' |
url |
zip file address; must be specified if |
template_dir |
parent directory where subject's 'FreeSurfer' folder should be stored |
make_default |
logical, whether to make 'N27' default subject |
... |
more to pass to |
view |
whether to view the subject |
upgrade |
whether to check and download 'N27' brain interactively. Choices are 'ask', 'always', and 'never' |
async |
whether to run the job in parallel to others; default is true |
To view electrodes implanted in multiple subjects, it's highly
recommended to view them in a template space The detail mapping method
is discussed in function threeBrain.
To map to a template space, one idea is to find someone whose brain is
normal. In our case, the choice is subject 'N27', also known as 'Colin 27'.
function download_N27 provides a simple and easy way to download a
partial version from the Internet.
If you have any other ideas about template brain, you can use function
set_default_template(subject_code, template_dir) to redirect to
your choice. If your template brain is a 'Zip' file on the Internet, we
provide function download_template_subject to automatically install it.
Zhengjia Wang
R6 Class - Text Decoration Geometry
AbstractGeom -> TextDecorGeom
textLabel string rendered in the canvas
font_sizeWorld-space height of the sprite in mm
colorCSS color string for the text (e.g. "#ffffff")
font_weightCSS font-weight integer (e.g. 400 = normal, 700 = bold)
decor_idStable ID used to identify this decoration in the viewer.
Defaults to the geometry name.
typeGeometry type string used by the JavaScript engine.
clickableLogical; whether the geometry responds to mouse clicks in the viewer.
TextDecorGeom$new()Create a new text decoration geometry.
TextDecorGeom$new( text = "", position = c(0, 0, 0), name = NULL, decor_id = NULL, font_size = 5, color = "#ffffff", font_weight = 400, layer = 1, ... )
textCharacter string to display.
positionNumeric vector of length 3: c(x, y, z) in
world space.
nameUnique geometry name. If NULL a random ID is
generated automatically.
decor_idStable decoration ID visible to the Shiny proxy.
Defaults to name.
font_sizeWorld-space height of the sprite in mm. Default
5.
colorCSS color string. Default "#ffffff".
font_weightCSS font-weight integer. Default 400.
layerCamera layer(s), 0-13 (0 = main camera only,
1 = all cameras). Default 1.
...Additional arguments forwarded to AbstractGeom.
TextDecorGeom$to_list()Serialize to a list for JSON export.
TextDecorGeom$to_list()
TextDecorGeom$clone()The objects of this class are cloneable with this method.
TextDecorGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Create a brain object
threeBrain( path, subject_code, surface_types = c("pial", "smoothwm", "inflated", "sphere.reg"), atlas_types, annotation_types = "label/aparc.a2009s", ..., template_subject = unname(getOption("threeBrain.template_subject", "N27")), backward_compatible = getOption("threeBrain.compatible", FALSE) )threeBrain( path, subject_code, surface_types = c("pial", "smoothwm", "inflated", "sphere.reg"), atlas_types, annotation_types = "label/aparc.a2009s", ..., template_subject = unname(getOption("threeBrain.template_subject", "N27")), backward_compatible = getOption("threeBrain.compatible", FALSE) )
path |
path to 'FreeSurfer' directory, or 'RAVE' subject directory containing 'FreeSurfer' files, or simply a 'RAVE' subject |
subject_code |
subject code, characters |
surface_types |
surface types to load; default is |
atlas_types |
brain atlas to load; default is |
annotation_types |
annotations, this can be one or more files relative to the 'FreeSurfer' subject directory. Each annotation can be discrete such as surface atlas, or continuous such as surface curvature. |
... |
reserved for future use |
template_subject |
template subject to refer to; used for group template mapping |
backward_compatible |
whether to support old format; default is false |
Create a Threejs Brain and View it in Browsers
threejs_brain( ..., .list = list(), width = NULL, height = NULL, background = "#FFFFFF", cex = 1, timestamp = TRUE, title = "", side_canvas = FALSE, side_zoom = 1, side_width = 250, side_shift = c(0, 0), side_display = TRUE, control_panel = TRUE, control_presets = NULL, control_display = TRUE, camera_center = c(0, 0, 0), camera_pos = c(500, 0, 0), start_zoom = 1, symmetric = 0, default_colormap = "Value", palettes = NULL, value_ranges = NULL, value_alias = NULL, show_inactive_electrodes = TRUE, surface_colormap = system.file("palettes", "surface", "ContinuousSample.json", package = "threeBrain"), voxel_colormap = system.file("palettes", "datacube2", "FreeSurferColorLUT.json", package = "threeBrain"), videos = list(), widget_id = "threebrain_data", tmp_dirname = NULL, debug = FALSE, enable_cache = FALSE, token = NULL, controllers = list(), browser_external = TRUE, global_data = list(), global_files = list(), qrcode = NULL, custom_javascript = NULL, show_modal = "auto", embed = FALSE )threejs_brain( ..., .list = list(), width = NULL, height = NULL, background = "#FFFFFF", cex = 1, timestamp = TRUE, title = "", side_canvas = FALSE, side_zoom = 1, side_width = 250, side_shift = c(0, 0), side_display = TRUE, control_panel = TRUE, control_presets = NULL, control_display = TRUE, camera_center = c(0, 0, 0), camera_pos = c(500, 0, 0), start_zoom = 1, symmetric = 0, default_colormap = "Value", palettes = NULL, value_ranges = NULL, value_alias = NULL, show_inactive_electrodes = TRUE, surface_colormap = system.file("palettes", "surface", "ContinuousSample.json", package = "threeBrain"), voxel_colormap = system.file("palettes", "datacube2", "FreeSurferColorLUT.json", package = "threeBrain"), videos = list(), widget_id = "threebrain_data", tmp_dirname = NULL, debug = FALSE, enable_cache = FALSE, token = NULL, controllers = list(), browser_external = TRUE, global_data = list(), global_files = list(), qrcode = NULL, custom_javascript = NULL, show_modal = "auto", embed = FALSE )
..., .list
|
geometries inherit from AbstractGeom |
width, height
|
positive integers. Width and height of the widget. By default width='100%', and height varies. |
background |
character, background color such as |
cex |
positive number, relative text magnification level |
timestamp |
logical, whether to show time-stamp at the beginning |
title |
viewer title |
side_canvas |
logical, enable side cameras to view objects from fixed perspective |
side_zoom |
numerical, if side camera is enabled, zoom-in level, from 1 to 5 |
side_width |
positive integer, side panel size in pixels |
side_shift |
integer of length two, side panel shift in pixels ('CSS style': top, left) |
side_display |
logical, show/hide side panels at beginning |
control_panel |
logical, enable control panels for the widget |
control_presets |
characters, presets to be shown in control panels |
control_display |
logical, whether to expand/collapse control UI at the beginning |
camera_center |
numerical, length of three, XYZ position where camera should focus at |
camera_pos |
XYZ position of camera itself, default (0, 0, 500) |
start_zoom |
numerical, positive number indicating camera zoom level |
symmetric |
numerical, default 0, color center will be mapped to this value |
default_colormap |
character, which color map name to display at startup |
palettes |
named list, names corresponds to color-map names if you want to change color palettes |
value_ranges |
named list, similar to |
value_alias |
named list, legend title for corresponding variable |
show_inactive_electrodes |
logical, whether to show electrodes with no values |
surface_colormap |
a color map or its path generated by |
voxel_colormap |
a color map or its path generated by |
videos |
named list, names corresponds to color-map names, and items are generated from |
widget_id |
character, internally used as unique identifiers for widgets; only use it when you have multiple widgets in one website |
tmp_dirname |
character path, internally used, where to store temporary files |
debug |
logical, internally used for debugging |
enable_cache |
whether to enable cache, useful when rendering the viewers repeatedly in shiny applications |
token |
unique character, internally used to identify widgets in 'JavaScript' |
controllers |
list to override the settings, for example |
browser_external |
logical, use system default browser (default) or built-in one. |
global_data, global_files
|
internally use, mainly to store orientation matrices and files. |
qrcode |
'URL' to show in the 'QR' code; can be a character string or a named list of |
custom_javascript |
customized temporary 'JavaScript' code that runs after ready state; available 'JavaScript' variables are:
|
show_modal |
logical or |
embed |
whether to try embedding the viewer in current run-time; default is false (will launch default web browser); set to true if running in |
Zhengjia Wang
if( interactive() ) { library(threeBrain) # Please use `download_N27` to download N27 Collins template brain n27_path <- file.path(default_template_directory(), "N27") if( dir.exists(n27_path) ) { brain <- threeBrain(path = n27_path, subject_code = "N27", surface_types = c('pial', 'smoothwm')) print(brain) brain$plot( background = "#000000", controllers = list( 'Voxel Type' = 'aparc_aseg', 'Surface Type' = 'smoothwm', 'Blend Factor' = 1, 'Right Opacity' = 0.3, 'Overlay Sagittal' = TRUE ), show_modal = TRUE ) } }if( interactive() ) { library(threeBrain) # Please use `download_N27` to download N27 Collins template brain n27_path <- file.path(default_template_directory(), "N27") if( dir.exists(n27_path) ) { brain <- threeBrain(path = n27_path, subject_code = "N27", surface_types = c('pial', 'smoothwm')) print(brain) brain$plot( background = "#000000", controllers = list( 'Voxel Type' = 'aparc_aseg', 'Surface Type' = 'smoothwm', 'Blend Factor' = 1, 'Right Opacity' = 0.3, 'Overlay Sagittal' = TRUE ), show_modal = TRUE ) } }
Shiny Output for threeBrain Widgets
outputId |
unique identifier for the widget |
width, height
|
width and height of the widget. By default width="100 and height="500px". |
reportSize |
whether to report widget size in shiny
|
Zhengjia Wang
Tube geometry that sweeps a circular cross-section along a curved path defined by control points. Used to render electrode shafts and tract trajectories in the three-brain viewer.
AbstractGeom -> TubeGeom
typeGeometry type string ("tube").
radial_segmentsNumber of segments around the tube circumference.
tubular_segmentsNumber of segments along the tube path.
control_dataFlattened numeric vector (row-major) of control
points; each row encodes x, y, z, t
(normalized path position 0-1), and radius.
image_uriBase64 data URI of the tube texture image, or
NULL for a plain color.
TubeGeom$new()Create a new tube geometry.
TubeGeom$new(name, control_data, image_uri = NULL, ...)
nameUnique character name.
control_dataNumeric matrix with 5 columns: x, y,
z, t (path position), radius. Must have at
least 2 rows.
image_uriOptional base64 data URI string for a texture image.
...Additional arguments forwarded to AbstractGeom.
TubeGeom$to_list()Serialize the tube geometry to a named list for JSON export.
TubeGeom$to_list()
TubeGeom$clone()The objects of this class are cloneable with this method.
TubeGeom$clone(deep = FALSE)
deepWhether to make a deep clone.
Zhengjia Wang
Add video content to the viewer
video_content( path, duration = Inf, time_start = 0, asp_ratio = 16/9, local = TRUE )video_content( path, duration = Inf, time_start = 0, asp_ratio = 16/9, local = TRUE )
path |
local file path or 'URL' |
duration |
duration of the video |
time_start |
start time relative to the stimuli onset |
asp_ratio |
aspect ratio; default is |
local |
used only when |
The video path can be either local file path or a 'URL' from websites. When path is from the internet, there are two options: download the video before generating the viewer, or directly use the 'URL'.
If download happens before a viewer is generated (local=TRUE), then
the video content is local. The viewer will be self-contained. However,
the distribution will contain the video, and the archive size might be large.
If raw 'URL' is used (local=FALSE), then viewer is not self-contained
as the video link might break anytime. The 'screenshot' and 'record' function
might be limited if the 'URL' has different domain than yours. However,
the distribution will not contain the video, hence smaller. This works in the
scenarios when it is preferred not to share video files or they are
licensed, or simply distribution is limited. Besides, this method is slightly
faster than the local alternatives.
Returned by brain_proxy. Provides reactive active bindings
and setter methods for controlling a running three-brain viewer widget
from within a Shiny application.
Active bindings (reactive fields) reflect the viewer state and trigger Shiny reactivity when read inside a reactive context:
backgroundCurrent background color as a hex string.
text_decorationsList of current text decoration objects.
main_cameraNamed list with position, up,
and zoom.
side_displayLogical indicating whether the side canvas is visible.
surface_typeCurrent surface type string (e.g.
"pial").
display_variableName of the currently displayed data clip.
plane_positionNamed numeric vector c(R, A, S)
giving the slice cursor position in FreeSurfer surface coordinates.
controllersFull controller state list.
current_subjectNamed list describing the currently active subject, including transform matrices.
backgroundCurrent viewer background color as a hex string
(e.g. "#FFFFFF"). Reactive.
text_decorationsList of current text decoration parameter lists
pushed from JavaScript. Each element has fields id,
text, position, color, font_size, and
layer. Reactive.
main_cameraNamed list with elements position (length-3
numeric), up (length-3 numeric), and zoom (positive
numeric) describing the main camera state. Reactive.
side_displayLogical indicating whether the side canvas panel is currently visible. Reactive.
surface_typeCurrent brain surface type string
(e.g. "pial", "white"). Reactive.
display_variableName of the data clip currently displayed in
the viewer. "[None]" when nothing is displayed. Reactive.
plane_positionNamed numeric vector c(R, A, S) giving
the slice cursor position in FreeSurfer surface coordinates.
Reactive.
localization_tableData frame of localization electrode contacts
parsed from the JSON pushed by the viewer, or NULL. Reactive.
localization_add_quaternionRotation data list pushed by the viewer when a localization point is added. Reactive.
mouse_event_double_clickNamed list describing the last double-click mouse event in the viewer. Reactive.
mouse_event_clickNamed list describing the last single-click mouse event in the viewer. Reactive.
controllersFull named list of the viewer's current controller (GUI panel) state. Reactive.
current_subjectNamed list describing the currently active
subject. Includes subject_code, Norig, Torig,
and xfm transform matrices. Reactive.
syncSync token string pushed by the viewer on each render cycle; useful for triggering reactive updates. Reactive.
acpc_alignmentNamed list describing the AC-PC alignment in
scanner RAS space. Includes ac, pc, ras2acpc,
and set-flags. Reactive.
ViewerProxy$print()Print a summary of the proxy's available fields and methods.
ViewerProxy$print(...)
...Ignored.
ViewerProxy$new()Create a new viewer proxy. Normally called via
brain_proxy rather than directly.
ViewerProxy$new(outputId, session = shiny::getDefaultReactiveDomain())
outputIdShiny output element ID of the three-brain widget.
sessionShiny reactive domain session. Defaults to the current
session returned by shiny::getDefaultReactiveDomain().
ViewerProxy$isolate()Read an active binding without triggering Shiny reactivity.
ViewerProxy$isolate(name)
nameName of the active binding to read (character scalar).
ViewerProxy$get_controllers()Get the current controller state as an isolated (non-reactive) list.
ViewerProxy$get_controllers()
ViewerProxy$set_controllers()Send a named list of controller key-value pairs to the viewer.
ViewerProxy$set_controllers(ctrl)
ctrlNamed list of controller settings to apply.
ViewerProxy$set_background()Set the viewer background color.
ViewerProxy$set_background(col)
colAny R color value accepted by col2hexStr.
ViewerProxy$set_title()Display a title overlay in the viewer.
ViewerProxy$set_title(title)
titleCharacter string to display as the title. Pass an empty string or omit to clear the title.
ViewerProxy$set_zoom_level()Set the viewer camera zoom level.
ViewerProxy$set_zoom_level(zoom)
zoomPositive numeric zoom factor.
ViewerProxy$set_camera()Point the main camera toward a direction in world space.
ViewerProxy$set_camera(position, up)
positionNumeric vector of length 3: desired camera direction (will be normalized to a unit vector then scaled to radius 500).
upNumeric vector of length 3: camera up direction. Defaults
to c(0, 0, 1).
ViewerProxy$set_display_data()Change the displayed data clip and optional value range.
ViewerProxy$set_display_data(variable = "", range = NULL)
variableName of the data clip to display. Pass "" to
clear.
rangeNumeric vector of length 2 giving the display range, or
NULL to use the natural range of the data.
ViewerProxy$set_focused_electrode()Move the viewer focus to a specific electrode contact.
ViewerProxy$set_focused_electrode(subject_code, electrode)
subject_codeCharacter scalar: subject identifier.
electrodeInteger scalar: electrode contact number.
ViewerProxy$set_electrode_data()Push a data frame of electrode values to the viewer.
ViewerProxy$set_electrode_data( data, palettes = NULL, value_ranges = NULL, clear_first = FALSE, update_display = TRUE, override = TRUE )
dataData frame with at least columns Subject and
Electrode.
palettesOptional named list of color palette vectors.
value_rangesOptional named list of c(min, max) ranges.
clear_firstLogical; clear existing electrode data before
applying. Default FALSE.
update_displayLogical; update the viewer display after the data
is applied. Default TRUE.
overrideLogical; override existing data for the same clip.
Default TRUE.
ViewerProxy$set_electrode_palette()Apply a color palette to an existing electrode data clip.
ViewerProxy$set_electrode_palette(colors, variable)
colorsCharacter vector of CSS color strings.
variableName of the data clip to apply the palette to.
ViewerProxy$set_cex()Set the global text magnification factor for the viewer.
ViewerProxy$set_cex(cex = 1)
cexPositive numeric magnification factor. Default 1.
ViewerProxy$set_localization_electrode()Update the parameters of a localization electrode contact.
ViewerProxy$set_localization_electrode(which, params, update_shiny = TRUE)
whichInteger index of the electrode contact to update.
paramsNamed list of parameter values to update.
update_shinyLogical; push the update to Shiny inputs.
Default TRUE.
ViewerProxy$set_matrix_world()Set the world transform matrix of a named scene object.
ViewerProxy$set_matrix_world(name, m44)
nameCharacter: name of the three-brain scene object.
m44Numeric vector of length 16 or a 4-by-4 matrix (row-major).
ViewerProxy$add_localization_electrode()Add a new localization electrode contact to the viewer.
ViewerProxy$add_localization_electrode(params, update_shiny = TRUE)
paramsNamed list with at least Coord_x, Coord_y,
Coord_z in FreeSurfer surface coordinates (unless
is_prototype = TRUE).
update_shinyLogical; push the addition to Shiny inputs.
Default TRUE.
ViewerProxy$clear_localization()Remove all localization electrode contacts from the viewer.
ViewerProxy$clear_localization(update_shiny = TRUE)
update_shinyLogical; push the change to Shiny inputs.
Default TRUE.
ViewerProxy$set_incoming_localization_hemisphere()Set which hemisphere is targeted for the next electrode localization click.
ViewerProxy$set_incoming_localization_hemisphere(hemisphere)
hemisphereCharacter scalar: "left" or "right".
ViewerProxy$set_values()Add an animation clip of scalar or categorical values to a named geometry object in the viewer.
ViewerProxy$set_values(
name,
target_object,
data_type,
value,
palette = rainbow(64),
symmetric = FALSE,
time = ifelse(length(value) == 1, 0, stop("time must match length with value")),
value_range = NULL,
time_range = NULL,
value_names = NULL,
switch_display = FALSE
)
nameCharacter clip name used as the display variable label.
target_objectName of the geometry object to animate.
data_typeEither "continuous" or "discrete".
valueNumeric or character vector of values.
paletteColor palette: a vector of R colors.
Default rainbow(64).
symmetricLogical; whether the color scale is symmetric around
zero. Default FALSE.
timeNumeric vector of time points matching value.
Defaults to 0 for a single value.
value_rangeNumeric vector of length 2 overriding the data
range. NULL uses the natural range.
time_rangeNumeric vector of length 2 overriding the time
range. NULL uses the natural range.
value_namesOptional character vector of level labels for discrete data.
switch_displayLogical; switch the viewer display to this clip
after upload. Default FALSE.
ViewerProxy$get_text_decorations()Get the current text decorations from the viewer.
Returns a list of named lists, each with fields id,
text, position, color, font_size, and
layer. Returns an empty list when no decorations exist.
ViewerProxy$get_text_decorations()
ViewerProxy$set_text_decoration()Create or update a text decoration in the viewer.
ViewerProxy$set_text_decoration( id, text = NULL, position = NULL, font_size = NULL, color = NULL, layer = NULL )
idCharacter scalar: stable decoration ID.
textCharacter scalar: label to display.
positionNumeric vector of length 3 in world space.
font_sizePositive number: world-space sprite height (mm).
colorCSS color string (e.g. "#ff0000").
layerInteger or integer vector: camera layer(s).
ViewerProxy$delete_text_decoration()Delete one or more text decorations from the viewer.
ViewerProxy$delete_text_decoration(id)
idCharacter scalar or vector of decoration IDs to remove.
ViewerProxy$get_crosshair_position()Get the current slice cursor position in a requested coordinate space.
ViewerProxy$get_crosshair_position(
space = c("tkrRAS", "MNI305", "MNI152", "scanner", "CRS")
)
spaceCoordinate space. One of "tkrRAS" (default),
"MNI305", "MNI152", "scanner", or "CRS".
ViewerProxy$set_crosshair_position()Move the slice cursor to a given position in a requested coordinate space.
ViewerProxy$set_crosshair_position(
position,
space = c("tkrRAS", "MNI305", "MNI152", "scanner", "CRS")
)
positionNumeric vector of length 3.
spaceCoordinate space of position. One of
"tkrRAS" (default), "MNI305", "MNI152",
"scanner", or "CRS".
Zhengjia Wang
'nii' or 'mgz' volume filesGenerate surface file from 'nii' or 'mgz' volume files
volume_to_surf( volume, save_to = NA, lambda = 0.2, degree = 2, threshold_lb = 0.5, threshold_ub = NA, format = "auto" )volume_to_surf( volume, save_to = NA, lambda = 0.2, degree = 2, threshold_lb = 0.5, threshold_ub = NA, format = "auto" )
volume |
path to the volume file, or object from |
save_to |
where to save the surface file; default is |
lambda |
|
degree |
|
threshold_lb |
lower threshold of the volume (to create mask); default is |
threshold_ub |
upper threshold of the volume; default is |
format |
The format of the file if
|
Triangle 'rgl' mesh (vertex positions in native 'RAS'). If save_to is a valid path, then the mesh will be saved to this location.
read_volume, vcg_isosurface,
vcg_smooth_implicit
library(threeBrain) N27_path <- file.path(default_template_directory(), "N27") if(dir.exists(N27_path)) { aseg <- file.path(N27_path, "mri", "aparc+aseg.mgz") # generate surface for left-hemisphere insula mesh <- volume_to_surf(aseg, threshold_lb = 1034, threshold_ub = 1036) if (interactive()) { ravetools::rgl_view({ ravetools::rgl_call("shade3d", mesh, color = "yellow") }) } }library(threeBrain) N27_path <- file.path(default_template_directory(), "N27") if(dir.exists(N27_path)) { aseg <- file.path(N27_path, "mri", "aparc+aseg.mgz") # generate surface for left-hemisphere insula mesh <- volume_to_surf(aseg, threshold_lb = 1034, threshold_ub = 1036) if (interactive()) { ravetools::rgl_view({ ravetools::rgl_call("shade3d", mesh, color = "yellow") }) } }
Color maps for volume or surface data
create_colormap( gtype = c("surface", "volume"), dtype = c("continuous", "discrete"), key, color, value, alpha = FALSE, con = NULL, auto_rescale = FALSE, ... ) save_colormap(cmap, con) freeserfer_colormap(con) load_colormap(con) read_colormap(con, format = c("rave", "itksnap"))create_colormap( gtype = c("surface", "volume"), dtype = c("continuous", "discrete"), key, color, value, alpha = FALSE, con = NULL, auto_rescale = FALSE, ... ) save_colormap(cmap, con) freeserfer_colormap(con) load_colormap(con) read_colormap(con, format = c("rave", "itksnap"))
gtype |
geometry type, choices are |
dtype |
data type, |
key |
non-negative integer vector corresponding to color values; its length must exceed 1; see 'Details' |
color |
characters, corresponding to color strings for each key |
value |
actual value for each key |
alpha |
whether to respect transparency |
con |
a file path to write results to or to read from. The
file path can be passed as |
auto_rescale |
automatically scale the color according to image values; only valid for continuous color maps |
... |
used by continuous color maps, passed to
|
cmap |
color map object |
format |
file format to read from |
Internal 'JavaScript' shader implementation uses integer color keys to
connect color palettes and corresponding values. The keys must be
non-negative.
Zero key is a special color key reserved by system. Please avoid using it for valid values.
A list of color map information
# Creates a symmetric continuous colormap with 3 keys # The color range is -10 to 10 # The colors are 'blue','white','red' for these keys pal <- create_colormap( gtype = "volume", dtype = "continuous", key = c(1,2,3), value = c(-10,0,10), color = c('blue','white','red')) print( pal ) # ---------------- Get colormap key from a value ------------ # returns key index starting from pal$get_key( -10 ) # nearest value pal$get_key( 2 ) # set threshold, key is now 0 (no color) pal$get_key( 2, max_delta = 1 ) # ---------------- Save and load ---------------- f <- tempfile( fileext = '.json' ) save_colormap( pal, f ) cat(readLines(f), sep = '\n') load_colormap(f)# Creates a symmetric continuous colormap with 3 keys # The color range is -10 to 10 # The colors are 'blue','white','red' for these keys pal <- create_colormap( gtype = "volume", dtype = "continuous", key = c(1,2,3), value = c(-10,0,10), color = c('blue','white','red')) print( pal ) # ---------------- Get colormap key from a value ------------ # returns key index starting from pal$get_key( -10 ) # nearest value pal$get_key( 2 ) # set threshold, key is now 0 (no color) pal$get_key( 2, max_delta = 1 ) # ---------------- Save and load ---------------- f <- tempfile( fileext = '.json' ) save_colormap( pal, f ) cat(readLines(f), sep = '\n') load_colormap(f)
Generate volume data from 'MNI' coordinates
add_voxel_cube( brain, name, cube, size = c(256, 256, 256), trans_mat = NULL, trans_space_from = c("model", "scannerRAS"), color_format = c("RGBAFormat", "RedFormat") ) add_nifti( brain, name, path, trans_mat = NULL, color_format = c("RGBAFormat", "RedFormat"), trans_space_from = c("model", "scannerRAS") ) create_voxel_cube( mni_ras, value, colormap, keys = colormap$get_key(value), dimension = c(256, 256, 256) )add_voxel_cube( brain, name, cube, size = c(256, 256, 256), trans_mat = NULL, trans_space_from = c("model", "scannerRAS"), color_format = c("RGBAFormat", "RedFormat") ) add_nifti( brain, name, path, trans_mat = NULL, color_format = c("RGBAFormat", "RedFormat"), trans_space_from = c("model", "scannerRAS") ) create_voxel_cube( mni_ras, value, colormap, keys = colormap$get_key(value), dimension = c(256, 256, 256) )
brain |
a 'threeBrain' brain object generated from |
name |
the name of voxel cube, only letters, digits and |
cube |
a 3-mode array; see the following example |
size |
the actual size of the volume, usually dot multiplication of the dimension and voxel size |
trans_mat |
the transform matrix of the volume. For |
trans_space_from |
where does |
color_format |
color format for the internal texture. Default is 4-channel |
path |
'Nifti' data path |
mni_ras |
'MNI' 'RAS' coordinates, should be a |
value |
data values (length |
colormap |
a color map generated from |
keys |
integer color-keys generated from a color map with length of |
dimension |
volume dimension; default is a |
create_voxel_cube returns a list of cube data and other informations;
add_voxel_cube returns the brain object
# requires N27 brain to be installed # use `download_N27()` to download template Collins brain # sample MNI coords tbl <- read.csv(system.file( 'sample_data/example_cube.csv', package = 'threeBrain' )) head(tbl) # load colormap cmap <- load_colormap(system.file( 'palettes/datacube2/Mixed.json', package = 'threeBrain' )) x <- create_voxel_cube( mni_ras = tbl[, c('x', 'y', 'z')], keys = tbl$key, dimension = c(128, 128, 128) ) n27_path <- file.path(default_template_directory(), "N27") if( interactive() && dir.exists(n27_path) ) { brain <- merge_brain() # or add_voxel_cube(brain, 'example', x$cube) x$add_to_brain(brain, 'example') brain$plot(controllers = list( "Voxel Type" = 'example', 'Right Opacity' = 0.3, 'Left Opacity' = 0.3, 'Background Color' = '#000000' ), voxel_colormap = cmap) }# requires N27 brain to be installed # use `download_N27()` to download template Collins brain # sample MNI coords tbl <- read.csv(system.file( 'sample_data/example_cube.csv', package = 'threeBrain' )) head(tbl) # load colormap cmap <- load_colormap(system.file( 'palettes/datacube2/Mixed.json', package = 'threeBrain' )) x <- create_voxel_cube( mni_ras = tbl[, c('x', 'y', 'z')], keys = tbl$key, dimension = c(128, 128, 128) ) n27_path <- file.path(default_template_directory(), "N27") if( interactive() && dir.exists(n27_path) ) { brain <- merge_brain() # or add_voxel_cube(brain, 'example', x$cube) x$add_to_brain(brain, 'example') brain$plot(controllers = list( "Voxel Type" = 'example', 'Right Opacity' = 0.3, 'Left Opacity' = 0.3, 'Background Color' = '#000000' ), voxel_colormap = cmap) }