Create brain atlas from subcortical segmentation
Source:R/atlas_subcortical.R
create_subcortical_from_volume.RdTurn a subcortical segmentation volume (like aseg.mgz) into a brain
atlas with 3D meshes for each structure. The function extracts each labelled
region from the volume, creates a surface mesh, and smooths it.
For 2D plotting, the function can also generate slice views by taking snapshots at specified coordinates and extracting contours.
Requires FreeSurfer for mesh generation.
Usage
create_subcortical_from_volume(
input_volume,
decimate = 0.5,
verbose = get_verbose(),
...,
input_lut = NULL,
atlas_name = NULL,
output_dir = NULL,
slabs = NULL,
vertex_size_limits = NULL,
min_coverage = NULL,
cleanup = NULL,
skip_existing = NULL,
steps = NULL
)Arguments
- input_volume
Path to the segmentation volume. Supports
.mgz,.nii, and.nii.gzformats. Typically this isaseg.mgzor a custom segmentation in the same space. May also be thelist(volume, lut, id_offset)returned byprepare_subcortical_anatomical()/project_volume_anatomical(), in which case itsvolumeandlutare used (an explicitinput_luttakes precedence over the bundled one).- decimate
Mesh decimation factor between 0 and 1. Reduces the number of faces in 3D meshes using quadric edge decimation (via
Rvcg::vcgQEdecim()). A value of 0.5 reduces faces by 50%. Set to NULL to skip decimation. Requires the Rvcg package. Default is 0.5.- verbose
How much to print:
0silent,1progress (the default),2adds FreeSurfer's own output.TRUEandFALSEmean1and0. Falls back tooptions("ggseg.extra.verbose"), thenGGSEG_EXTRA_VERBOSE.- ...
Not used. Present so that a mistyped or misplaced argument is reported against this function rather than silently ignored; anything passed here is an error. Geometry is shaped after the build: see
atlas_polish(), oratlas_simplify(),atlas_smooth()andatlas_dilate()individually.- input_lut
Path to a FreeSurfer-style colour lookup table that maps label IDs to region names and colours (e.g.,
FreeSurferColorLUT.txtorASegStatsLUT.txt), or a data.frame with columnsidx,label,R,G,BandA(seeis_lut()).The table decides what is a region and what is context, the grey anatomy the regions are drawn against. Nothing is recognised by its id or its name:
A row is a region unless it says otherwise. It gets a mesh, a colour and a shape in each 2D view.
A row whose optional
contextcolumn isTRUEis context. It keeps its name, is traced on one slice per view rather than projected through the slab, and gets no mesh.A label in the volume that the table does not list is context too. With no name to go by, it is called
context_and its id, such ascontext_0002.
To leave a context shape out of the atlas altogether, remove it afterwards with
ggseg.formats::atlas_context_remove(). To treat the context differently when polishing, passcontext_patternaslabelsorexclude; seecontext_pattern().Either form may also carry a
hemicolumn ("left","right"or"midline") that sets each region's hemisphere; a row leftNA, or a table without the column, has it read from the label's name, and any other value is an error.write_lut()stores the column in a file.A data.frame may also carry a
namescolumn: the display name each region shows in a legend. A row leftNA, or a table without the column, is named after its region.If NULL, every label is a region with a generic name (e.g., "region_0010"), there is no context, and the atlas will have no palette.
- atlas_name
Name for the atlas. If NULL, derived from the input filename. It also names the folder of intermediate files inside
output_dir, so it must be a single name without path separators.- output_dir
Where to put the intermediate files. Defaults to
tempdir(), fromoptions("ggseg.extra.output_dir")orGGSEG_EXTRA_OUTPUT_DIR.- slabs
A data.frame specifying projection slabs with columns
name,type("axial", "coronal", "sagittal"),start(first slice),end(last slice). Defaults to three coronal and three axial slabs tiling the bounding box of the atlas's own labels, plus one left-hemisphere sagittal slab, so the band follows the anatomy of the volume rather than a fixed set of slice indices. Unlike slices, projections show ALL structures in their spatial relationships - like an X-ray view. May also be a named list ofsubcortical_slabs()arguments (e.g.slabs = list(labels = 801:810, coronal = 3, axial = 2)); it is expanded into a slab table withvolumedefaulting toinput_volume, so the slab indices are computed in the builder's own frame.- vertex_size_limits
Numeric vector of length 2 setting minimum and maximum vertex count for polygons. Polygons outside this range are filtered out. Default NULL applies no limits.
- min_coverage
Smallest share of
corelabels that must end up with 2D geometry, between 0 and 1. A build that falls below it warns and names the labels that have no shape; the warning fires whateververboseis set to, because a region that cannot be drawn is data loss rather than progress chatter. The build itself still returns, so a long pipeline is never thrown away over a threshold. Use0to turn the check off. Defaults to0.8, or tooptions("ggseg.extra.min_coverage"), thenGGSEG_EXTRA_MIN_COVERAGE.- cleanup
Remove the intermediate files afterwards. Default
TRUE, fromoptions("ggseg.extra.cleanup")orGGSEG_EXTRA_CLEANUP.The intermediate files live in a folder named after the atlas inside
output_dir, and the whole folder is removed. A build therefore refuses to start if that folder already holds files it did not write, since removing it would take them too. Choose anotheroutput_diroratlas_name, or passFALSEto build there and keep everything.- skip_existing
Reuse a step's intermediate files when they already exist, instead of running the step. Default
FALSE, fromoptions("ggseg.extra.skip_existing")orGGSEG_EXTRA_SKIP_EXISTING.A cache records which ggseg.extra wrote it, not what it was built from, so reuse cannot tell that the volume or lookup table has changed. Reuse is therefore asked for rather than assumed, and is reported when it happens. To continue an interrupted build, either pass
TRUEor leave the finished steps out ofsteps.- steps
Which pipeline steps to run. Default NULL runs all six:
1: Extract labels from the volume and read the colour table
2: Create a mesh for each structure
3: Build atlas data (3D only if stopping here)
4: Create projection snapshots
5: Extract contours
6: Build the final atlas with 2D geometry
Use
steps = 1:3for a 3D-only atlas. Geometry is shaped after the build, not during it: seeatlas_polish().
Value
A ggseg_atlas object with region metadata (core), 3D meshes,
a colour palette, and optionally sf geometry for 2D slice plots.
See also
atlas_polish() to simplify and round off the result, which
most builds want next.
Other atlas creation:
create_cerebellar_from_annotation(),
create_cerebellar_from_gifti(),
create_cerebellar_from_volume(),
create_cortical_from_annotation(),
create_cortical_from_cifti(),
create_cortical_from_gifti(),
create_cortical_from_labels(),
create_cortical_from_neuromaps(),
create_tract_from_tractography(),
create_tract_from_volume(),
create_wholebrain_from_volume()
Examples
if (FALSE) { # \dontrun{
# Create 3D-only subcortical atlas from aseg
atlas <- create_subcortical_from_volume(
input_volume = "path/to/aseg.mgz",
input_lut = "path/to/FreeSurferColorLUT.txt",
steps = 1:3
)
# View with ggseg3d
ggseg3d::ggseg3d(atlas = atlas)
# Full atlas with 2D slices
atlas <- create_subcortical_from_volume(
input_volume = "path/to/aseg.mgz",
input_lut = "path/to/ASegStatsLUT.txt"
)
# Post-process to remove/modify regions (functions from ggseg.formats)
atlas <- atlas |>
atlas_region_remove("White-Matter", match_on = "label") |>
atlas_region_contextual("Cortex", match_on = "label")
} # }