You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
VBGAMLSS fits Generalized Additive Models for Location, Scale and Shape voxel-wise or vertex-wise, designed for normative modelling in neuroimaging.
VBGAMLSS is based on gamlss2, so it uses the same formula syntax.
# devtools is required to install from GitHub
install.packages("devtools")
# gamlss2 from R-universe and ANTsR from GitHub
install.packages(
"gamlss2",
repos= c("https://gamlss-dev.R-universe.dev",
"https://cloud.R-project.org")
)
# qs2: quick serialization 2remotes::install_cran("qs2", type="source", configure.args="--with-simd=AVX2")
# Note for vertex based data ANTsR is not mandatorydevtools::install_github("ANTsX/ANTsR")
Note: VBGAMLSS is heavily based on gamlss2 which is under development so changes are common. If you encounter issues, please let me know.
🎭 Quick Start
library(VBGAMLSS)
# Paths to example datansubj<-258img_controls<-"~/controls.nii.gz"# 90x90x90x258img_patients<-"~/patients.nii.gz"# 90x90x90x258mask<-"~/mask.nii.gz"# 90x90x90# Covariatescovs_controls<-data.frame(
x0=1:nsubj,
x1= as.factor(rbinom(nsubj, 1, 0.6)),
)
covs_patients<-data.frame(
x0= rnorm(nsubj),
x1= rnorm(nsubj) * rnorm(nsubj),
)
# Convert to 2D subject × voxel/verteximageframe_controls<- images2matrix(img_controls, mask)
imageframe_patients<- images2matrix(img_patients, mask)
# Fit the voxel-wise GAMLSS models. Note: formulas follow gamlss2 syntax, # but the Y is the response variable placeholder is mandatory. vbgamlss_model<- vbgamlss(
imageframe_controls,
g.formula=Y~ pb(x0) +x1|x1,
g.family=NO,
num_cores=20,
train.data=covs_controls,
debug=TRUE
)
After few hours (less than 8h for 150k voxels on 40 cores)
# Save / load
save_model(vbgamlss_model, "~/vbgamlss.model/fitted_model")
models_loaded<- load_model("~/vbgamlss.model/fitted_model.vbgamlss")
# Predict & compute Z-scorespredictions<- predict.vbgamlss(models_loaded, newdata=covs_patients)
zscores<- zscore.vbgamlss(predictions, imageframe_patients)
# Map the z-score to nifti. `_subj-<ID>.zscore.nii.gz` is then appended. # ID id the patient index of the imageframe. # Note, this function computes z-scores from a `vbgamlss.predictions" object. # It differes from the `map_zscores_from_map` function which computes the maps # z-scores directly from coefficient maps.
map_zscores(
zscores,
mask=mask,
filename="~/patients_deviation_maps/deviation_map",
)
# Map the predicted μ,σ,ν,τ response distribution parameters to nifti. `_subj-<ID>_fam-<FAMILY>_par-<PARAM>.nii.gz` is then appended. FAMILY is the distribution family (e.g. SHASH), PARAM is the parameter (e.g. mu, sigma).
map_model_predictions(
predictions,
mask=mask,
filename="~/patients_parameter_maps/prediction",
)
For space efficiency reason, vbgamlss remove the distribution class from each submodel after fitting. use this function to restore it if needed (e.g. if you want to do custom operation on vbgamlss submodels).
Apply a function to each voxel submodel in a vbgamlss object and return a vector. restore_family() is already included in each iteration before calling the custom function.
Perform stratified k-fold cross-validation for voxel-wise models and summaries results.
📝 General notes
Using an HPC is strongly encouraged. Fitting models voxel-wise is computationally and memory intensive and may take a long time.
Please consider tweaking chunk_max_mb parameter of vbgamlss to fit your system's memory constraints (256Mb is a good starting point). The function will proceed chunking the imageframe and parallize a chunk at the time to avoid loading everyhting in memory at once.
When performing model selection is advise to do it on a subset of voxels (regularly or randomly sampled) with a penalized likelihood (e.g. GAIC with k=2 or k=log(n)) method instead of CV for time reasons.
Providing an already subsampled mask is simple and effective. vbgamlss's subsample parameter is DEPRECATED.
vbgamlss can be forced to save each chunk and resume the fit from the last chunk in case of interruptions (e.g. time limits on HPC) by providing cache=T and cachedir. See ?vbgamlss for details.
🏗️ Work in progress
vbgamlss.cv: ⚠️ implemented, but not fully tested. Undocumented.
vbgamlss segmentation handling: ⚠️ implemented, but not fully tested.
vbgamlss.model_selection: ❌ "It will not work on other HPC systems. Undocumented.
⚠ Known Issues
It takes a long time to fit models voxel-wise.
pbmcappyly runs sequentially on some systems (i.e. Windows).
vbgamlss.model_selection currently does not generalize across all HPC systems
For space efficiency reason, vbgamlss remove the distribution class from each submodel after fitting. use this function to restore it if needed (e.g. if you want to do custom operation on vbgamlss submodels).
Apply a function to each voxel submodel in a vbgamlss object and return a vector. restore_family() is already included in each iteration before calling the custom function.