ggseg.extra 1.9.9.9016
Post-creation geometry
Smoothing, dilation and vertex reduction are steps you apply to a finished atlas, not settings baked into a build - retuning one should not cost a rebuild.
New
atlas_dilate()grows or shrinks region geometry, the post-creation counterpart of the snapshot-stage dilation the pipelines applied. Dilate the structures and leave the context alone: a grey brain grown by even a little closes its sulci and flattens into a blob.dilateon thecreate_*()functions is deprecated in favour ofatlas_dilate(). It is still honoured for now, so no atlas changes underfoot.dilate,smoothness,toleranceandsmooth_refinementsare no longer formals of thecreate_*()functions: they are caught in...instead, so they no longer appear in a signature or a help page while a call that still passes one keeps working and says so. Anything else in...is an error, as an unused argument always was. The notice for the smoothing arguments is the one they already had; onlydilate’s is new.-
atlas_smooth()andatlas_simplify()now do one thing each.atlas_smooth()decides how round an outline is;atlas_simplify()decides how many vertices it costs.keepis gone fromatlas_smooth(), andatlas_simplify()is no longer deprecated: it takeslabelsandexcludelike the others.Having both in one function meant
atlas_smooth()simplified tokeep = 0.05unless told otherwise, so a call that asked only for smoothing quietly threw away 95% of the vertices - and a second call quietly threw away 95% of what the first left. That is how the bundled cortex silhouettes ended up as blobs. Run them in that order, too: simplifying a rounded outline replaces its curves with straight chords, putting the stair-step back.
Minor improvements and fixes
Test
describe()calls are namespace-qualified.local_mocked_bindings(.package = "terra")attaches terra, and terra exports adescribe()of its own, which then maskedtestthat’s - turning laterdescribe()blocks into GDAL calls on filenames that do not exist. The error aborted the file, so its remaining blocks never ran. Which files were hit depended on run order, which is why a helper-level pin did not hold; the call sites are qualified instead.The sagittal context slice is now the thinnest section of cortex in the slab, not the densest. Sagittal is the one view where picking the slice with the most cortex is actively wrong: area peaks at both tangential extremes - the medial wall by the midline, and the lateral surface - where the slice skims along the sheet and returns a solid blob. A true cross-section, the one that reads as a gyrified ribbon, is where the area is lowest. The ends of the slab are trimmed before the search so it cannot fall into the midline gap. Axial and coronal still take the densest slice, where the reasoning does not apply.
The anatomical context silhouette is no longer dilated.
dilateexists to keep small deep structures from vanishing, but it was applied to every snapshot in the directory, including the grey brain, where a two-pixel dilation closes the sulci and flattens the mantle. Structures are dilated as before. The exclusion is deliberately case-sensitive so aCerebellar_Cortex_*parcel, which is a structure in its own right in some atlases, still gets dilated.The anatomical context silhouette is now taken from a single slice for every view, never projected through the slab. Projecting it unions every sulcus the slab passes through and fills them in, so the grey brain came out as a smooth blob rather than a gyrified mantle; the deeper the slab, the worse it got.
cortex_slice_for_slab()already chose a representative slice - the densest cortex slice within the slab - for axial and coronal views as well as sagittal, but only the sagittal branch used it. Structures are still projected through the slab, so small deep ones continue to show up in every view that passes through them.create_tract_from_volume()no longer sweeps the whole label volume once per tract. It collected each tract’s voxels withwhich(arr == label), so a 35-tract atlas made 35 full passes over the array; the voxels are now gathered in a single pass and grouped by label, and the voxel-to-world affine is applied after thinning rather than before, so it transforms at most4000points per tract instead of every voxel. Output is unchanged.
New features
- The grey anatomical silhouette behind a 2D view is now taken from the slice in the slab holding the most cortex, rather than from the slab midpoint. The silhouette is context, so it should be chosen for legibility — and a midpoint can land somewhere with almost nothing to draw. A mid-sagittal slab centred on the midline cuts the interhemispheric fissure:
cvs_avg35_inMNI152has 797 cortical voxels at x=128 against 6703 four voxels away, so the outline came out in fragments while the structures in front of it were fine. Widening the slab could not fix it, since only the structures project through the slab. Ties are broken toward the midpoint, so a slab whose slices are equally informative keeps the position it had before.
ggseg.extra 1.9.9.9014
New features
-
project_volume_anatomical()now warns whenprotect_cortexremoves a label entirely. The guard blocks the atlas from overwriting the cortical ribbon and cerebral white matter, which is right for deep grey structures but erases a white-matter atlas from the only tissue it describes — and it did so silently. ggsegJHU’s ICBM-DTI-81 atlas shipped for a release with its right superior longitudinal fasciculus missing outright, with nothing in the build output to show it. The warning names the lost labels and points atprotect_cortex = FALSE.
Bug fixes
write_lut()no longer truncates label names to 29 characters. FreeSurfer parses its colour tables on whitespace and its ownFreeSurferColorLUT.txtcarries names up to 47 characters, so the cap corrupted every long label – and silently merged any two that were identical up to the cut. Julich-Brain’sCh_123_(Basal_Forebrain)_rightcame back asCh_123_Basal_Forebrain_righ, losing the hemisphere suffix and with it the hemisphere.clean_region_name()now strips the same hemisphere affixes thatdetect_hemi()recognises, including theL_/R_prefix convention and_left/_rightsuffixes. Where the two disagreed the hemisphere ended up inregionas well ashemi:R_Fxgave hemi"right"but region"r fx", so the two halves of one structure looked like two unrelated structures to anything grouping onregion– including the newggseg.formats::atlas_view_select(). A name that is only a hemisphere word is left alone rather than stripped to nothing.
ggseg.extra 1.9.9.9013
New features
-
atlas_smooth()gainsmethod. The default"close"is the existing morphological closing, which rounds outlines but fills any hole narrower than the smoothing distance – on a thin cortical ribbon that erases the sulci."chaikin","ksmooth"and"spline"come fromsmoothr::smooth()and move vertices rather than dilating the shape, so enclosed holes stay open. Use"close"for solid shapes such as tract tubes and one of the others where the geometry has holes worth keeping. -
atlas_smooth(smoothness =)is now a 0–1 strength shared by everymethod, mapped internally onto each method’s native parameter, so the same value means a comparable amount of smoothing whichever one is chosen. Values outside 0–1 are an error carrying the conversion rule, rather than being silently reinterpreted: divide an oldmethod = "close"distance by 5.
Bug fixes
2D atlas geometry no longer loses its holes.
coords2sf()grouped coordinates by(.subid, .id), but.subidis the ring index within a polygon (1 = exterior, >1 = holes) and.idthe polygon index, so every ring became its own solid polygon and every enclosed hole was filled. A thin cortical ribbon came out as a blob: the sagittal fsaverage slice measured 20,117 against a true area of 17,481, with 44 of its 137 rings surviving. Rings are now assembled as exterior-plus-holes, and the area matches exactly. This affects every atlas built throughget_contours()– cortical, subcortical, wholebrain and tract – so rebuilt atlases will differ from ones built before this fix.Tract 2D projections are no longer drawn in the wrong plane.
streamlines_to_volume()built each tube in the template’s native voxel layout and relied onRNifti::orientation(nii) <- "RAS"to convert it. For.mgztemplates that assignment was a silent no-op —read_volume()returns a bare array carrying no affine, soorientation()reports"RAS"whatever the layout — while the anatomical reference was converted, being read throughread_volume(reorient = TRUE). With an LIA template such as FreeSurfer’saseg.mgz, voxel axes 2 and 3 ended up swapped between the two, so axial projections were drawn over coronal anatomy and sagittal ones appeared rotated 90°. The volume is now reoriented explicitly.Tract 2D projections are no longer offset from the anatomical reference.
center_meshes()translates centerlines to the origin for 3D display, and the snapshot step rasterised those translated coordinates as though they were world RAS, shifting every tract relative to the anatomy. The translation is now recorded and undone before rasterising; 3D output is unchanged.Sagittal cortex reference slices now come from their own slab rather than a fixed plane, matching what axial and coronal already did. A sagittal slab at an explicit position previously had its silhouette drawn somewhere else. An explicit
cortex_xstill wins, and hemisphere-named views fall back to their lateral positions when the slab holds no cortex to choose from.The anatomical reference for tract atlases now includes the brainstem, cerebellar cortex and deep grey structures alongside the cortical ribbon, so tracts descending out of the cerebrum are drawn against anatomy instead of empty space. White matter is excluded, cerebral and cerebellar alike: tracts run through it, and filling it would bury them. Excluding cerebellar white matter also keeps the cerebellum a foliated shell like the cerebral ribbon instead of a solid mass that merges with the occipital lobe in sagittal views.
create_tract_from_volume()andcreate_tract_from_tractography()now honouratlas_namefor the atlas object itself, not only for the output directory. The finished atlas previously took the name derived from its tract labels (e.g."tracts"), ignoring what the caller asked for.
ggseg.extra 1.9.9.9012
New features
prepare_subcortical_mni152()embeds a subcortical parcellation supplied in fixed FSL-MNI152 space into a FreeSurfer subject’saseg(via the knownmni152.register.dattransform), replacing the lumped aseg structures the parcels subdivide and returning a merged volume plus a matching colour table ready forcreate_subcortical_from_volume(). It is the fixed-registration counterpart toprepare_subcortical_anatomical(), which instead computes anmri_coregregistration tocvs_avg35_inMNI152; use this one when the atlas already lives in a standard MNI152 template and should keepfsaverage5context.aseg_subcortical_labels()returns the lumped subcortical structure ids a finer parcellation typically subdivides.create_tract_from_volume()builds a white-matter tract atlas from a volumetric tract label map (one integer label per tract) rather than from streamlines: each tract’s voxel cloud is reduced to a principal-curve centerline and handed tocreate_tract_from_tractography(), which builds the 3D tubes and 2D projection. This suits probabilistic tract atlases distributed as NIfTI label volumes (e.g. AtlasTrack). Addsprincurveto Suggests.
Bug fixes
-
create_tract_from_tractography()no longer errors wheninput_tractsis an in-memory list of coordinate matrices: the setup log interpolated the matrices into a{.path}inline style, whichclicannot format as file paths.
ggseg.extra 1.9.9.9011
Minor improvements and fixes
- Workflows written by
use_atlas_github_actions()now run on pull requests.pkgdownpreviously had no pull request trigger at all, so a broken reference index or vignette could only fail after merging;code-qualityfiltered pull requests to those targetingmain, so a stacked pull request skipped linting entirely. Neither publishes from a pull request: the shared workflows guard the pkgdown deploy ongithub.event_name, and the coverage badge and README commits ongithub.ref.
ggseg.extra 1.9.9.9010
New features
-
use_atlas_github_actions()adds the shared ggsegverse GitHub Actions workflows to a package, in the style ofusethis::use_github_action().atlas_github_actions()lists what is available. Run it on a freshly scaffolded atlas package, or on an existing one to replace hand-maintained workflows with the shared set. -
setup_atlas_repo()gainsgithub_actions, TRUE by default.
Minor improvements and fixes
- Atlas packages now receive workflows as short caller stubs for the reusable workflows in
ggsegverse/.github, rather than inline copies. The scaffold previously shipped 229 lines of inline workflow, none of which called the shared workflows, so every new package started out with CI that had already drifted. -
setup_atlas_repo()no longer copies the atlas template’s.github/directory. That directory is the template’s own infrastructure — its smoke-test workflow and the scripts driving it — and had been leaking into every generated package. - The offline fallback now produces the same workflows as the downloaded template, since they no longer come from the template at all. Previously the fallback silently omitted CI.
ggseg.extra 1.9.9.9009
Bug fixes
- The bundled atlas template no longer generates a broken package. Template placeholders were spelled
{GGSEG}/{REPO}, which R parses as brace blocks, soair formatrewrote.{GGSEG}into a separate expression and splitlibrary({REPO})across lines. Generated packages had an accessor that returned nothing and a test suite that referenced an undefined object. -
data-raw/create-atlas.Rin the scaffold now calls the current API. It previously usedread_freesurfer_lut()(never exported),color_lut,input_gifti,input_cifti, and a tractinput_volumeargument, none of which exist, and omitted the requiredsource/descarguments tocreate_cortical_from_neuromaps(). Every uncommented section would have errored.
Minor improvements and fixes
- Template placeholders are now bare identifiers (
ATLASNAME,PKGNAME,YEARNUM) so template sources parse as valid R and cannot be rewritten by R tooling.setup_atlas_repo()still substitutes the legacy brace-wrapped spelling, so templates published before this change continue to work. - Added
air.tomlexcludinginst/templates/andinst/rstudio/templates/from formatting. - The scaffold now includes an
atlas_smooth()post-processing step and no longer passes the deprecatedtoleranceargument. - Generated packages set
Config/Needs/website: ggsegverse/ggseg.docsand use theggseg.docspkgdown template instead of an inlined bslib theme, and no longer setLazyDatawithout adata/directory. - Generated packages now pass
R CMD checkcleanly. The template declaredLicense: CC0while shipping an MIT-styleLICENSEfile, which produced a NOTE in every new package; it now declaresMIT + file LICENSE, matching both the bundled file and the other ggseg atlas packages. - Generated packages ship a
.lintrexcludingdata-raw/, so the deliberately commented-out scaffold no longer tripscommented_code_linter.
ggseg.extra 1.9.9.9008
Minor improvements and fixes
- Tract 2D projections now reuse the same centerline as the 3D tube (built with the configured
n_points/centerline_method) instead of recomputing a different 50-point mean centerline, so the two representations agree. -
read_tractography()reads.tckfiles without the previous quadratic slow-down on large bundles. -
create_tract_from_tractography()validatestube_segments(integer >= 3), and degenerate leading tract segments no longer yieldNaNtube vertices. - Cerebellar trilinear resampling skips non-finite deformation coordinates rather than raising an error, and a deep nucleus that cannot be converted to polygons is now reported instead of silently dropped.
-
create_wholebrain_from_volume()splits cortex at the correct (1-based) midline voxel; the left/right boundary was previously off by one voxel. - Reading a FreeSurfer LUT warns about malformed lines;
write_lut()validates its input;read_lut()/read_dpv()fail with clear messages on malformed headers, andread_dpv()handles zero-face surfaces. - CIFTI files with more than one label map warn that only the first is used.
- Annotation files whose colour table already defines an “unknown” region no longer produce a duplicate
unknownlabel. - Contour extraction reports a clear error when no region yields a contour instead of a cryptic downstream failure.
- Subcortical mesh tessellation honors the requested verbosity inside parallel workers.
- Reading a subcortical surface surfaces the underlying conversion error when the fallback reader is unavailable, and the interactive atlas preview warns on 3D render failures instead of failing silently.
-
setup_atlas_repo()no longer rewrites files under a template’s.gitdirectory and reports failed file copies/renames.
ggseg.extra 1.9.9.9007
Bug fixes
-
create_cerebellar_from_volume()no longer errors on float-typed parcellation volumes. Sampling labels at the SUIT surface forced an integervapply()template, so a double array — e.g. the SUIT volume written bytransform_mni_to_suit()— aborted the build. The volume is now coerced to integer before sampling. -
read_tractography()reads.trkfiles whose header track count is0. The TrackVis format uses0to mean “count not recorded, read to end of file”; the reader previously trusted the count and returned no streamlines, yielding an empty atlas. It now reads to the end of the file and treats a positive count as an upper bound. -
create_cortical_from_neuromaps()/read_neuromaps_volume()no longer abort with'breaks' are not uniquewhen a continuous map has tied values (common for thresholded maps or maps with many zeros). Duplicate quantile breaks are collapsed and the bin count is reduced with a warning; an all-medial-wall hemisphere now errors with a clear message. - Tract atlases built from in-memory streamline matrices (e.g.
create_tract_from_tractography(input_tracts = list(cst = matrix(...)))) now detect voxel- versus RAS-space correctly. Detection previously flattened the matrices and always assumed RAS, misplacing voxel-space tracts. -
create_tract_from_tractography()now reads the voxel-to-world affine from FreeSurfer.mgzheaders correctly, and warns instead of silently falling back to an approximate origin-centering heuristic when a template’s affine cannot be read. -
create_subcortical_from_volume()derives a defaultatlas_nameofaseg(notaseg.nii) from a.nii.gzinput. -
mri_infois now called with a shell-quoted volume path, so cerebellar deep-nuclei meshing works for volume paths that contain spaces. - Contour extraction (subcortical and tract 2D geometry) no longer crashes on empty or all-
NAregion rasters, keeps the valid contours when only some region geometries are empty, and reports a clear error when no region yields any contour instead of a crypticdplyrfailure. - Verbosity and boolean options parse spelled-out strings consistently:
GGSEG_EXTRA_VERBOSE=falsenow silences output, and string values such as"yes"or"1"are honored across the explicit, option, and environment-variable channels.
ggseg.extra 1.9.9.9005
Bug fixes
-
read_volume()now reorients FreeSurfer.mgzvolumes to RAS+, matching its long-standing behaviour for NIfTI inputs. Previously onlyniftiImageobjects were reoriented, so.mgzvolumes (e.g. FreeSurfer’s LIA-orientedaseg.mgz) reached the RAS+-assuming projection code still in LIA order. Subcortical atlases built directly from a.mgztherefore came out left-right flipped in axial views, top-bottom flipped in coronal, and 90-degrees rotated in sagittal; atlases built from reoriented.nii.gzvolumes (and tract atlases, whose geometry is already in scanner RAS) were unaffected. Volumes whose header carries no valid RAS information fall back to native voxel order.
Subcortical atlas builder helpers
New thin compositions of the existing ggseg.formats atlas ops and the volume reader, distilled from the repeated boilerplate in the ggsegFreeSurfer subcortical build scripts:
-
subcortical_slabs()builds a slab table from the bounding box of a set of labels, reading the volume in the same frame the builder uses so coronal/axial/sagittal slabs can’t be pointed at the wrong slices. -
aseg_context()collapses the standard post-processing chain (punch cortical white matter, strip the structuresasegdoesn’t draw, demote everything outsidefocusto grey context, drop empty views) into one call. The focus set is subtracted from the context set with exact, case-sensitive matching, so a region is never swallowed by a context entry that is a substring of its name (e.g.Thalamusvshypothalamus).aseg_hidden_labels()returns the default stripped set. -
lut_add()/lut_combine()append and merge FreeSurfer-style colour tables (validating withis_lut()and warning on index clashes) for atlases that add custom prefixed labels. -
create_subcortical_from_volume()gained two opt-in arguments:slabsnow also accepts asubcortical_slabs()list spec (e.g.slabs = list(labels = 801:810, coronal = 3)), and a newcontextargument runsaseg_context()on the finished 2D atlas (e.g.context = list(focus = "Hippocampus")). Both thread throughcreate_wholebrain_from_volume()’ssubcortical_opts.
sf smoothing moves out of atlas creation
Pipeline-time simplification of 2D sf geometry was the most common reason to re-run an otherwise expensive create_*() pipeline (10+ minutes for volumetric atlases). All create_*() functions now return raw, unsmoothed sf polygons. The (cheap) atlas_smooth() post-processing step is the single place where simplification level is decided, so you can iterate freely on a cached atlas:
atlas <- create_cortical_from_annotation(...) |>
atlas_smooth(keep = 0.2, exclude = "cortex_")- 3D mesh smoothing (tessellation, FreeSurfer
mris_smooth, decimation) is unchanged. -
tolerance,smoothnessandsmooth_refinementson everycreate_*()function are now soft-deprecated. Supplying any of them emits alifecycle::deprecate_warn()and the value is otherwise ignored. -
atlas_smooth()gainedlabels/excluderegex arguments so the brain-outline geometry can stay crisp while everything else is simplified. -
atlas_smooth()also gained asmoothnessargument that applies a positive-then-negativesf::st_buffer()(morphological closing) after vertex simplification. This restores the rounded sulcal curves the old pipelinesmoothnessargument produced, but as a per-region, post-atlas operation. Passkeep = NULLto skip vertex reduction and only round off voxel-edge stair-steps. - The “large atlas” warning text now points at
atlas_smooth()instead of the deprecatedtoleranceargument. -
create_wholebrain_from_volume()no longer injects a defaultsmooth_refinements = 2Linto the cerebellar sub-pipeline.
API naming and argument consistency pass
A pass over the atlas-builder family (create_cortical_from_*(), create_subcortical_from_volume(), create_cerebellar_from_*(), create_wholebrain_from_volume(), create_tract_from_tractography()) and the LUT helpers to make the API “as similar as possible” across atlas types. Old names/arguments keep working with a lifecycle::deprecate_warn().
-
Fixed:
create_cortical_from_labels()andcreate_tract_from_tractography()silently dropped region names wheninput_lutwas a FreeSurfer-style LUT file path, because the parser only looked for aregioncolumn and files parse into anidx/labelschema instead. It now falls back tolabelwhenregionis absent. -
Renamed the colour-table reader/writer family for consistency with the already-dominant
input_lutvocabulary used by every atlas builder:read_ctab()->read_lut(),write_ctab()->write_lut(),is_ctab()->is_lut(),get_ctab()->get_lut().lut_add()andlut_combine()are unchanged. -
Renamed
create_cerebellar_from_volume()’svolumeargument toinput_volume, matching itscreate_subcortical_from_volume()andcreate_wholebrain_from_volume()siblings. -
Renamed
mri_surf2surf_rereg()’shemiargument tohemisphere, matching the cortical builders. The default order ("lh"first) is unchanged. -
Renamed the volumetric
viewsargument toslabsoncreate_subcortical_from_volume()andcreate_tract_from_tractography(), andsubcortical_views()tosubcortical_slabs()to match. This distinguishes it from the cortical builders’views(a character vector selecting standard panels), which is unchanged and unrelated. -
Reordered arguments across all five builder families onto one shared layout: primary input(s),
input_lut,atlas_name,output_dir, type-specific structural arguments, refinement arguments (vertex_size_limits,dilate,decimate), the deprecatedtolerance/smoothness/smooth_refinementstrio,cleanup,verbose,skip_existing,steps, then any function-specific trailing arguments. Every call site in this package’s own tests, vignettes, and examples already used named arguments for everything but the first one or two positional inputs, so this should be a no-op for callers doing the same; it is a silent behaviour change for any positional call beyond that. - Internal:
create_wholebrain_from_volume()’scortical_optsallow-list is now derived reflectively fromcreate_cortical_from_annotation()’s formals (matching howsubcortical_opts/cerebellar_optsalready worked) instead of a hand-maintained constant that could drift.
Anatomical-context coregistration helpers
- New
coregister_volume()wrapsmri_coregto align an atlas volume to a FreeSurfer subject’s T1 grid (defaultcvs_avg35_inMNI152), returning a reusable LTA file. - New
project_volume_anatomical()resamples each atlas label with trilinear interpolation onto the targetaparc+aseggrid, takes the argmax across labels, and produces a merged volume that combines the sourceaparc+aseg(anatomical brain-outline context) with the user’s atlas labels. It returns alist(volume, lut, id_offset): the merged volume and a colour table aligned to it (FreeSurfer names for the survivingaparc+asegcontext labels plus the user’s labels at their shifted ids), so the context regions render with namesaseg_context()recognises. - New
prepare_subcortical_anatomical()chains both in a single call, returning the samelist(volume, lut, id_offset).create_subcortical_from_volume()now accepts that list directly asinput_volume, unpacking the matching colour table for you (an explicitinput_lutstill wins). - Removes the ~50 lines of per-atlas boilerplate previously hand-rolled in
ggsegShenandggsegHObuild scripts. -
id_offsetparameter (default200L) shifts every input label ID in the merged volume so they don’t collide with FreeSurferaparc+asegIDs (e.g. an atlas where11means “Putamen” while FS uses11for “Caudate”). The returned colour table is shifted in lock-step. -
protect_cortexparameter (defaultTRUE) keepsaparc+asegcortex voxels (labels 1000-2999) and cortical white matter (2,41) intact even when the user’s argmax wins abovethreshold— this preserves the brain-outline geometry that the subcortical pipeline draws as anatomical context. - The per-voxel argmax streams the running winner across labels instead of materialising an
n_voxels x n_labelsprobability matrix, so projecting a many-region atlas (e.g. Shen-268 onto a 256^3 grid) no longer needs tens of gigabytes of memory.
ggseg.extra 1.9.9.9004
Template-based atlas repo scaffolding
-
setup_atlas_repo()now downloads the atlas template from ggsegverse/ggseg-atlas-template instead of bundling template files inside the package. This makes the template a single source of truth that can be updated independently. - The generated scaffold includes all modern atlas repo conventions: Quarto README, Bootstrap 5 pkgdown config, code-quality workflow, render-readme workflow, update-codemeta workflow, and AI agent instructions.
-
data-raw/create-atlas.Rnow scaffolds all pipeline methods (cortical, subcortical, cerebellar, tract, wholebrain) with commented sections. - Falls back to a bundled minimal template when offline.
- Rich CLI messaging throughout the scaffolding process.
ggseg.extra 1.9.9.9003
Large-atlas warning
-
warn_if_large_atlas()now scales its threshold with region count viaper_region = 50(threshold =max(max_vertices, per_region * n_regions)). Prevents spurious warnings for high-resolution parcellations (e.g. Kong 1000-parcel) wherekeep_shapes = TRUEsets a ~40 vertices/region floor. - Fixed the follow-up hint which previously suggested raising
toleranceto reduce vertices; lower values simplify more aggressively.
Deep cerebellar nuclei support
-
create_cerebellar_from_volume()now detects deep cerebellar nuclei (Dentate, Interposed, Fastigial) that have volume voxels but no SUIT surface vertices. These are tessellated as individual 3D meshes with proper tkRAS-to-MNI coordinate transform, and rendered as smoothed coronal projection sf geometries in a separate “nuclei” view. - Orphaned surface parcels (e.g. buckner17 17Networks_14) that are too small for any SUIT vertex to land on are now rescued by assigning the nearest surface vertex, keeping them on the flatmap.
- Voxel neighbor fill radius expanded from 1 to 3 (configurable) to better capture small regions during volume-to-surface sampling.
- Restored colour auto-fill in
read_suit_parcellation()andread_neuromaps_volume().
Cerebellar atlas type and SUIT flatmap pipeline
New “cerebellar” atlas type added across the ggseg ecosystem (ggseg.formats, ggseg, ggseg3d). Cerebellar atlases use SUIT flatmap sf polygons for 2D rendering and per-region meshes for 3D (like subcortical).
Three creation pipelines:
-
create_cerebellar_from_gifti()creates from GIFTI label files + SUIT flatmap surface. -
create_cerebellar_from_annotation()creates from FreeSurfer.annotfiles on the SUIT cerebellar surface + SUIT flatmap. -
create_cerebellar_from_volume()creates from a NIfTI cerebellar segmentation volume + SUIT 3D surface (for vol-to-surf sampling) + SUIT flatmap. Includes per-region 3D mesh tessellation.
Supporting functions:
-
read_suit_parcellation()reads SUIT-format GIFTI labels with automatic hemisphere detection (Left/Right/Vermis). -
ggseg_data_cerebellar()(ggseg.formats) creates the data container. -
is_cerebellar_atlas()(ggseg.formats) type predicate.
Boundary triangle splitting
Boundary triangles (where vertices belong to different atlas regions) are now split into sub-polygons along edge midpoints instead of being assigned wholesale to a single region. This eliminates the sawtooth artifacts at region borders that resulted from the triangular mesh geometry.
- 2-region boundaries: triangle is split at the midpoints of the two cross-boundary edges — the majority region gets a quadrilateral, the minority region gets a triangle.
- 3-region boundaries: triangle is divided into three quadrilaterals meeting at the centroid.
- Default
toleranceincreased from 0.5 to 1 — the smoother borders tolerate higher simplification without visible degradation.
ggseg.extra 2.0.1
Cortical pipeline: mesh projection
The cortical atlas pipeline now projects inflated mesh triangles directly to 2D polygons via orthographic projection, replacing the screenshot-based contour extraction from v2.0.0.
- Much faster — atlas creation completes in ~5 seconds instead of minutes.
- Cleaner geometry — no pixel staircase artifacts from rasterisation.
- Fewer dependencies — no FreeSurfer rendering, ImageMagick, or Chrome needed for 2D geometry (FreeSurfer is still required to read annotation files).
- Better small-region visibility — boundary faces are assigned to the smallest neighbouring region so tiny parcels are not swallowed by their neighbours.
- Smooth region borders — boundary triangles (vertices in different regions) are split along edge midpoints so each region gets a clean polygon slice, eliminating the sawtooth artifacts from whole-triangle assignment.
Breaking changes
- Removed
method,snapshot_dim,smoothness, andstepsparameters from allcreate_cortical_from_*()functions. The pipeline always reads data and projects to 2D in one pass — no step-based control needed. - Changed default
tolerancefrom 0.5 to 1 — the triangle-splitting approach produces smoother borders that tolerate higher simplification.
Lighter dependency footprint
- Moved
chromote,htmlwidgets,magick,smoothr,terra,RNifti, andfreesurferfrom Imports to Suggests. Users who only need the cortical pipeline no longer need these packages installed. They are checked at runtime and requested when needed (subcortical, tract, and volumetric pipelines).
ggseg.extra 2.0.0
- Major rewrite of atlas creation pipelines with modular step-based architecture
- Added GIFTI (
.label.gii) and CIFTI (.dlabel.nii) annotation support - Added neuromaps surface and volume annotation pipelines
- Added whole-brain atlas creation from volumetric parcellations
- Added white-matter tract atlas creation from tractography files
- Added three-level verbosity control (silent/standard/debug)
- Deprecated
ggseg_atlas_repos(),install_ggseg_atlas(), andinstall_ggseg_atlas_all()in favour of ‘ggseg.hub’ - Moved
convert_legacy_brain_atlas()to ‘ggseg.formats’ (re-exported) - Removed rgdal, purrr, reticulate, and tidyr dependencies
- Replaced reticulate/kaleido snapshots with chromote
- Protected all parallel operations against multicore fork crashes
- Removed dead FreeSurfer wrapper functions
- Fixed read_ctab for multi-word labels
- Fixed subcortical label classification in whole-brain pipeline
ggseg.extra 1.6
1.6.0
- Removed rgdal dependency, replaced with sf/terra (#49, #59)
- Fixed r-universe API calls (JSON array format change)
- Fixed vignette build issues with conditional evaluation for suggested packages
- Replaced reticulate/kaleido with webshot2 for plotly screenshots
- Updated system setup vignette with new requirements
- Added documentation for parallel processing and progress bars
- Added note about freesurfer dev version requirement
- Updated CITATION to use bibentry()
- Updated pkgdown site with ggseg brand styling
- Fixed mris_label2annot example documentation
ggseg.extra 1.5
1.5.33.003
- small bug fix that prevented calls to FreeSurfer
- Possibility to initiate new atlas project from the RStudio Project GUI
ggseg.extra 1.5.33
- removes purrr dependency
- used ggseg r-universe as install repo for install functions