View source: R/vis_volume_clusters.R
| vis.volume.clusters | R Documentation |
Visualize the clusters of a volume, e.g., the supra-threshold voxels of a statistical map, as 3D iso-surfaces inside a single semi-transparent anatomical mesh (the context, typically the cortex of the same subject). A cluster is rendered as a set of nested iso-surface shells: the outermost shell is the iso-surface at the threshold (the cluster boundary), the inner ones sit at the higher iso-levels, and the innermost shell is at the cluster peak. This way the shape of the cluster and the location of its peak are visible at the same time, and the voxel structure of the data does not show up as staircase artifacts.
The shells are colored with a diverging colormap that encodes the iso-level, i.e., they use exactly the colors that the colorbar shows, and they become more opaque towards the core of the cluster, so that the core is visible through the outer shells. Positive and negative clusters can be rendered together, they use the two halves of the diverging colormap.
To render the clusters without a context mesh, pass context = NULL. To show the location of the clusters within a specific subject, use the context parameter to select the surface (e.g., "white" or "pial"); the surfaces of the fsaverage template subject can be downloaded with download_fsaverage if needed.
vis.volume.clusters(
subjects_dir = NULL,
subject_id = "fsaverage",
volume,
threshold = NULL,
threshold_quantile = 0.95,
max_level = NULL,
max_level_quantile = 0.99,
num_levels = 4L,
positive = TRUE,
negative = TRUE,
smoothing = 2L,
downsample = 1L,
frame = 1L,
backend = "auto",
context = list(surface = "white", alpha = 0.05),
alpha_range = c(0.08, 1),
makecmap_options = mkco.cluster(),
views = c("sd_lateral_lh", "sd_medial_lh", "sd_lateral_rh", "sd_medial_rh"),
rgloptions = rglo(),
rglactions = list(),
silent = FALSE
)
subjects_dir |
string or |
subject_id |
string. The subject identifier, used to load the context mesh. Defaults to 'fsaverage', the template subject for which the surfaces can be downloaded automatically. |
volume |
a 3D numerical array (or an |
threshold |
single positive number or |
threshold_quantile |
single value between 0 and 1, the quantile of the absolute non-zero voxel values used as the threshold if |
max_level |
single positive number or |
max_level_quantile |
single value between 0 and 1, the quantile of the supra-threshold voxel values used to compute |
num_levels |
positive integer, the number of nested shells per cluster, i.e., per sign. The outermost shell is at the threshold, the innermost at |
positive |
logical, whether to render the clusters above |
negative |
logical, whether to render the clusters below |
smoothing |
non-negative integer, the number of 3x3x3 box blur passes applied to the volume before the shells are extracted. This removes the staircase artifacts of the marching cubes algorithm and is what makes the clusters look like smooth blobs. Defaults to 2. Set to 0 to extract the shells from the raw volume. |
downsample |
positive integer, a factor by which the volume is subsampled before the shells are extracted. Values larger than 1 reduce the number of triangles (and thus the rendering time) considerably, at the cost of a less detailed surface, which can be useful because a cluster is rendered as |
frame |
positive integer, the frame (4th dimension) to use for a 4D volume. Defaults to 1. |
backend |
character string, the backend used to extract the iso-surfaces, one of 'auto' (the default: use the |
context |
|
alpha_range |
numerical vector of length 2, the alpha value of the outermost shell (at the threshold) and of the innermost shell (at the cluster peak), each between 0 and 1. The values in between are interpolated, separately for the positive and the negative clusters. Defaults to |
makecmap_options |
named list of parameters to pass to |
views |
list of character strings, the views to visualize. Available views are |
rgloptions |
option list passed to |
rglactions |
named list, passed to the visualization functions, see |
silent |
logical, whether to suppress the console messages which report the threshold, the levels and the backend used. Defaults to |
the list of renderable meshes, invisibly: the context meshes (if any) first, then the cluster shells, ordered from the outermost to the innermost shell of each sign. Passing this list to export saves the scene as an image, including the colorbar of the cluster values.
The cluster shells are extracted in the voxel space of the volume and transformed to surface RAS with index2ras_tkr, so they are aligned with surface renderings of the same subject. This requires the volume to be in the standard FreeSurfer orientation with 1 mm voxels (a conformed volume), which is the case for volumes read with subject.volume; volumes in other spaces (like a 2 mm MNI template) have to be transformed to the subject space outside of fsbrain first.
A single iso-surface contains, by definition, the threshold value at all of its vertices, so a color gradient within one shell is not meaningful. The value information is therefore encoded in the nesting: each shell is drawn in the color of its own iso-level (the outer shell in the color of the threshold, the innermost one in the color of the peak), and the shells are semi-transparent, with the transparency decreasing towards the core (see alpha_range). This results in a soft glow which is brightest at the location of the maximum. Setting num_levels = 1 instead renders one fully opaque shell per sign (the cluster boundary), which is the cleanest option if only the extent of the clusters matters. Note that the backfaces of the shells are drawn (back = 'filled'): with culled backfaces, the rgl renderer would composite the nested transparent shells in the wrong order, so the innermost shell would end up on top of the outer ones.
A cluster is rendered as num_levels meshes, so the number of iso-surfaces that have to be extracted is num_levels times the number of signs (20 for the defaults). For a conformed volume of 256^3 voxels this takes about 30 seconds with the Rvcg backend, most of which is the marching cubes extraction. Setting downsample = 2 reduces this to a few seconds (and the number of triangles by roughly a factor of 8), which is usually not visible for the smooth blobs that the default smoothing produces; it is a good choice for larger volumes, for small num_levels it matters less.
volvis.shells to visualize a whole volume (not just the clusters) as nested shells, volvis.voxels for a voxel-based rendering, vis.volume.on.surface to combine a volume with a morphometry-colored surface, and vis.subcortical.region.values for the related atlas version with one value per region.
Other visualization functions:
highlight.vertices.on.subject(),
highlight.vertices.on.subject.spheres(),
vis.color.on.subject(),
vis.data.on.fsaverage(),
vis.data.on.subject(),
vis.labeldata.on.subject(),
vis.mask.on.subject(),
vis.region.values.on.subject(),
vis.rglwidget(),
vis.subcortical.region.values(),
vis.subject.annot(),
vis.subject.label(),
vis.subject.morph.native(),
vis.subject.morph.standard(),
vis.subject.pre(),
vis.symmetric.data.on.subject(),
vis.volume.on.surface(),
vislayout.from.coloredmeshes()
Other volume visualization:
vis.volume.on.surface(),
volvis.lb(),
volvis.lb.with.surface(),
volvis.lightbox(),
volvis.slices.with.surface()
## Not run:
fsbrain::download_optional_data();
fsbrain::download_fsaverage(accept_freesurfer_license = TRUE);
subjects_dir = fsbrain::get_optional_data_filepath("subjects_dir");
# Use the brain volume of the demo subject as a fake statistical map: bright voxels are
# 'positive', dark ones are 'negative'.
brain = subject.volume(subjects_dir, 'subject1', 'brain');
stat = (brain - 110) / 30;
# Render the clusters inside a semi-transparent cortex of the fsaverage template subject:
cm = vis.volume.clusters(subjects_dir, 'fsaverage', stat, threshold = 1.5,
rglactions = list('no_vis' = TRUE));
export(cm, colorbar_legend = 'value', output_img = 'clusters.png');
# A single opaque shell per cluster, which only shows the cluster extent:
cm_simple = vis.volume.clusters(subjects_dir, 'fsaverage', stat, threshold = 1.5,
num_levels = 1, rglactions = list('no_vis' = TRUE));
# Without any context mesh, and with a fixed colormap range:
cm_ctx = vis.volume.clusters(subjects_dir, 'fsaverage', stat, threshold = 1.5,
context = NULL, makecmap_options = list('colFn' = squash::blueorange, 'n' = 100L,
'symm' = TRUE, 'range' = c(-2.0, 2.0)), rglactions = list('no_vis' = TRUE));
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.