Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

LaBGAScore

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Contents

What this is

LaBGAScore is a curated collection of MATLAB scripts and helper functions implementing LaBGAS's standard neuroimaging analysis workflow, spanning BIDS conversion, first-level and second-level fMRI modeling, MVPA/machine-learning pipelines, PET, MRS, and several auxiliary toolkits. A small amount of code is in other languages — SAS macros under stats_tools/sas_macros/, and standalone Python utilities under qr_code/. Scripts can either be run directly from this repo, or — more commonly for a real study — copied into that study's own project repo and adapted there for study-specific purposes.

This is not a packaged software product: there is no build system or automated test suite. A lightweight static-analysis helper is available (see Tests and CI).

Typical LaBGAS project structure

Every LaBGAS project/study is organized as a DataLad superdatasetproj_xxx, with subdatasets:

  • sourcedata — raw/source acquisitions
  • BIDS — BIDS-converted imaging and phenotype data
  • derivatives — preprocessing output (e.g. derivatives/fmriprep/)
  • code — analysis scripts, adapted per study
  • firstlevel — first-level model outputs
  • secondlevel — second-level (group) model outputs

LaBGAScore's own scripts are canonical/example copies: for a real study they are downloaded and adapted into that study's code subdataset, not run in place from this GitHub repo. firstlevel/LaBGAScore_firstlevel_s1_options_dsgn_struct.m's own header states this explicitly ("provided in LaBGAScore as an example and needs to be downloaded and adapted to the code subdataset for your study/project"), citing the real study repo proj_erythritol_4a as a worked example.

For second-level (group) analyses specifically, there is a matching pair of folders per model: code/secondlevel/model_x/ (the adapted scripts) and secondlevel/model_x/ (that model's outputs — masks/, results/, results/figures/, results/notes/, results/html/). This pairing is set up by the sibling CANlab_help_examples repo's second-level template scripts (see below), not by anything in LaBGAScore itself.

Repository structure and naming convention

The top level is organized by analysis topic, not as a conventional MATLAB toolbox:

prep/, firstlevel/, secondlevel/, stats_tools/, atlas_mask_tools/, pet/, mrs/, decoding_toolbox/, cosmomvpa/, graphvar/, juspace/, power/, figures/, clean/, qr_code/.

Most domains split into <domain>/scripts/ (or top-level .m scripts) and <domain>/functions/ (helper functions the scripts call). There is exactly one class in the whole repo, secondlevel/classes/ProgressTracker.m (a handle-derived progress/ETA helper for long loops).

Naming conventions:

  • Numbered/lettered prefixes (prep_1_, prep_2_, s0_, s1_, s2_, s3_, a_, a2_, and lettered variants like s1a_/s1b_/s2a_/s2b_) mark ordered, reusable pipeline steps meant to be copied into a study's code subdataset and adapted — not generic library code.
  • A _example suffix (e.g. secondlevel/scripts/LaBGAScore_secondlevel_ooFmriDataObjML_example.m) marks a script that is illustrative only, not meant to be copied and run as-is.
  • Scripts (files with no function/classdef declaration) use a standard MATLAB comment header: %% scriptname.m title, a *USAGE* section, optionally *OPTIONS*/*DEPENDENCIES*/*NOTES*, then an author/date/version block. Functions follow MATLAB's standard function help-text convention (H1 line, syntax) instead.

secondlevel/ additionally contains seven detailed, standalone usage guides — README_ENet_neuroimaging_pipeline.md, README_ENet_plotting.md, README_PLSDA_neuroimaging_pipeline.md, README_PLSDA_paired_neuroimaging_pipeline.md, README_PLSDA_plotting.md, README_PLSR_neuroimaging_pipeline.md, README_PLSR_plotting.md — for the Elastic Net / PLS-DA / PLSR pipeline functions and their diagnostic plotting companions. Consult those directly for usage details; they aren't duplicated here.

Dependencies

Most workflows require CanlabCore, Neuroimaging_Pattern_Masks, and SPM12 on the MATLAB path. None of these is vendored into this repo — all must be cloned/installed separately and added to the path (see prep/LaBGAScore_prep_s0_define_directories.m and pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m, which check for and set up these paths per study).

Several domain folders assume their own external toolbox, also not vendored, expected pre-installed and on the path:

FolderExternal toolbox
cosmomvpa/CoSMoMVPA
decoding_toolbox/The Decoding Toolbox (TDT)
graphvar/GraphVar
juspace/JuSpace
mrs/Osprey
stats_tools/sas_macros/SAS with SAS/STAT (not MATLAB — these are .sas macro files)

Exception: pet/functions/LCN_*.m are legacy KU Leuven PET-processing functions vendored directly into this repo rather than pulled from an external toolbox.

There is no package manager or dependency manifest — path setup is manual, via the scripts below.

Path/environment setup scripts:

  • prep/LaBGAScore_prep_s0_define_directories.m — checks SPM12 is on the path (errors with setup instructions if not) and does addpath(genpath(codedir),'-end') for a study's code directory.
  • pet/scripts/LaBGAScore_pet_a_set_up_paths_always_run_first.m — the PET-domain equivalent; must be run first before other LaBGAScore PET second-level batch scripts.
  • clean/LaBGAScore_move_repos_matlabpath.m — reorders two repos on the MATLAB path and calls savepath.
  • clean/LaBGAScore_smart_parallel_pool_setup.m — configures a parpool, capping worker count at ~60% of available cores.

Both assume local repos live under /data/master_github_repos (see githubrootdir in prep_s0).

Domain-by-domain overview

prep/ — BIDS conversion and pre-first-level prep: LaBGAScore_prep_parrec2bids.m (Philips PAR/REC → BIDS-organized NIfTI), LaBGAScore_prep_s0_define_directories.m (defines study paths, checks SPM12), LaBGAScore_prep_s1_write_events_tsv*.m (logfiles → BIDS events.tsv, single- or multi-session/task), LaBGAScore_prep_s2_smooth*.m (unzip → smooth → re-zip fMRIPrep output).

firstlevel/ — SPM/CANlab first-level GLM pipeline: s1_options_dsgn_struct (builds the CANlab-style DSGN design struct) → s2_fit_model (fits and diagnoses first-level models, cloning CANlab dependencies as needed) → s3_diagnose_model (publishes an HTML diagnostic report via CANlab's scn_spm_design_check, saves VIFs), with s1a/s2a as the multisession/multitask variant of the first two. A separate phMRI (pharmacological challenge) chain (s1b/s2b/s3b/s3c) models the post-administration period as one regressor per timebin and builds SPM batches directly rather than through canlab_glm_*. functions/canlab_glm_subject_levels*_old.m are older CANlab GLM functions kept because current example scripts still call them. See firstlevel/README.md for the task-fMRI chain — the LaBGAS_options reference, the noise model, the inter-script handoff, what lands on disk, and the contrast-order contract with the second-level scripts — and firstlevel/README_phMRI.md for the phMRI chain.

secondlevel/ — group-level statistics and MVPA/ML pipelines: TFCE permutation inference using classic TFCE, Smith & Nichols 2009 (group_tfce_from_subject_maps.mtfce_one_fmri_dat.mtfce_volume.mtfce_transform_3d.m), PLS-DA/PLSR/Elastic Net pipelines with matching diagnostic-plotting functions (see the seven README_*.md guides above), the shared per-fold helpers they are built from (foldPreprocess.m, residualizeFold.m, residualizeY.m, applyScaling.m, capLV.m, validateCovariates.m, warnUnknownOptions.m, setParforStream.m, globalBaselineCV.m, selectENetHyperparams.m, enetLambdaGrid.m, logitSafe.m, quickCV_*.m, bootstrapOOB_*.m, makeGroupedFolds.m, swapWithinSubjectLabels.m, quickGroupedCV.m), atlas/threshold validation helpers (validateAtlasLabels.m, maskToSignificant.m), dice-overlap tools (dice_statistic_image*.m), an ROI/parcel extraction script (LaBGAScore_secondlevel_extractparcels_sessions.m), a MACS-toolbox model-space batch-setup script (LaBGAScore_secondlevel_MS_mat_pipeline.m), an MVPA-regression-on-connectivity-betas script (LaBGAScore_secondlevel_mvpa_beta_maps_conn.m), a PLS/ENet ROI-pipeline wrapper (LaBGAScore_secondlevel_roi_run_plot_PLS_ENet_pipeline.m), an object-oriented ML toolkit example (LaBGAScore_secondlevel_ooFmriDataObjML_example.m), and the ProgressTracker class.

stats_tools/ — general-purpose statistics helpers, in two languages. functions/LaBGAScore_Storey_FDR.m implements Storey's positive FDR correction (falling back to Benjamini-Hochberg when its precondition isn't met). sas_macros/ holds SAS macros for statistics the MATLAB side does not cover: mixed_effectsize.sas (%mixed_effectsize) computes effect sizes — partial eta-squared with a noncentral-F confidence interval, Cohen's f², and optionally eta-squared/omega-squared — for the fixed effects of a model fitted with PROC MIXED, and es_identify.sas (%es_identify, %es_identify_ds) audits effect sizes in an existing results table to determine which statistic was actually reported. Both files are self-contained; %include the one you need. They require SAS with SAS/STAT, and are the only non-MATLAB code in the analysis workflow proper. See stats_tools/sas_macros/README.md for usage, the formulas used, the marginal-versus-conditional residual distinction, and the caveats to state in a Methods section — including its note that the macros have not yet been run against a real model in SAS.

atlas_mask_tools/LaBGAScore_atlas_binary_mask_from_atlas.m and LaBGAScore_atlas_rois_from_atlas.m generate custom atlas/mask and per-ROI objects from a chosen atlas; the folder also ships a set of ready-made brain/gray-matter mask and template NIfTIs (brain_masks/, brain_templates/, gray_matter_masks/).

pet/ — PET-specific pipeline: path setup (a_set_up_paths_always_run_first.m, a2_set_default_options.m), DICOM-to-BIDS conversion, preprocessing, kinetic modeling (e.g. LaBGAScore_pet_model_TSPO_DPA714.m), prep/signature-application scripts mirroring the fMRI prep_* naming, and a PLS/ENet pipeline runner. functions/LCN_*.m are the vendored legacy KU Leuven PET-processing functions.

mrs/ — MRS pipeline built on Osprey: BIDS conversion (LaBGAScore_prep_mrs2bids.m), GE/Philips Osprey jobfiles (single- and multi-session), and run scripts (LaBGAScore_mrs_run_osprey_GE.m/_Philips.m).

cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m: first-level representational similarity analysis (behavioral vs. neural dissimilarity, leave-one-run-out cross-validation) plus group-level permutation/TFCE testing, via CoSMoMVPA.

decoding_toolbox/ — TDT-based decoding: LaBGAScore_decoding_template_xclass_acc.m (first-level (cross-)classification accuracy plus group-level testing) and LaBGAScore_decoding_SVM_between_subjects.m (a full between-subject SVM decoding pipeline with permutation-based TFCE inference, sharing secondlevel/functions/tfce_volume.m with the second-level TFCE stack).

graphvar/LaBGAScore_prep_graphvar_input_from_conn.m: builds GraphVar input files from CONN toolbox ROI-to-ROI connectivity output.

juspace/LaBGAScore_prep_juspace_input.m (builds first-level con-image input for JuSpace PET-receptor spatial correlation analysis) and LaBGAScore_juspace_corr_behav.m (correlates behavioral data with JuSpace's spatial-correlation results).

power/ — standalone power-analysis helper functions: holmthreshold.m, medianIQR_to_meanSD.m, print_LEAR_matrix.m, sd_from_ci.m.

figures/ — plotting helpers: canlabCmap.m (CANlab colormap), cluster_surface_plots.m, save_all_open_figures_smart.m.

clean/ — utilities: LaBGAScore_clean_gzip_all_nii.m (recursive .nii gzip), LaBGAScore_clean_sourcedata.m (cleans the sourcedata subdataset), LaBGAScore_move_repos_matlabpath.m, LaBGAScore_smart_parallel_pool_setup.m.

qr_code/ — standalone Python utilities (emailQR.py, email_QR_Input.py, QRtoPDF.py) for generating and emailing QR codes; not MATLAB, and unrelated to the neuroimaging pipeline proper.

Relationship to CANlab_help_examples (LaBGAS fork)

CANlab_help_examples is a sibling repo whose Second_level_analysis_template_scripts/ directory provides LaBGAS's group-level (second-level) fMRI analysis templates — univariate GLM, cross-validated SVM, CANlab signature-pattern responses, searchlight correlation, and single-trial/runwise MVPA and mediation. Several of those scripts depend directly on LaBGAScore:

LaBGAScore function/scriptCalled from (in CANlab_help_examples)Purpose
LaBGAScore_prep_s0_define_directories (prep/)a_set_up_paths_always_run_first.mDefines rootdir, codedir, BIDSdir, spmrootdir, etc. for the study
LaBGAScore_firstlevel_s1_options_dsgn_struct (firstlevel/)a_set_up_paths_always_run_first.mBuilds the first-level DSGN struct the second-level framework reads DSGN.modeldir/DSGN.conditions/DSGN.contrastnames from
LaBGAScore_firstlevel_s2_fit_model.m (firstlevel/)upstream of prep_3f_create_fmri_data_single_trial_object.m (not called directly)Fits first-level models; produces the single-trial con images that single-trial/runwise MVPA and mediation analyses consume
LaBGAScore_atlas_binary_mask_from_atlas.m (atlas_mask_tools/)referenced via atlasname_glm/atlasname_svm options in a2_set_default_options.mGenerates custom .mat atlas/mask objects usable as GLM/SVM masks
LaBGAScore_atlas_rois_from_atlas.m (atlas_mask_tools/)referenced via roi_names/roi_modelname/roi_set_name optionsGenerates per-ROI atlas objects for ROI-average analysis

In short: LaBGAScore owns study setup, first-level modeling, and atlas/mask generation; CANlab_help_examples (LaBGAS fork) owns the second-level/group analysis templates built on top of LaBGAScore's outputs. For that repo's own internals, see its own README.md under Second_level_analysis_template_scripts/.

Provenance and dependency documentation

Scripts are copied into a study's code subdataset and frozen there, but their dependencies are not: CanlabCore, our fork of CANlab_help_examples, CanlabPrivate and the rest are shared clones that keep moving. clean/ holds tooling that closes that gap. See clean/README_provenance.md for the full guide.

Record provenance when you publish a script — replace the publish call documented in each script header:

LaBGAScore_prov_publish('my_secondlevel_script', htmlsavedir)

The html report gains a Provenance section listing the commit of every dependency the script reaches, plus the screen and figure dimensions it was produced at, and a machine-readable copy lands in the model's results/notes/.

Reconstruct provenance for analyses already run with LaBGAScore_prov_resolve_retrospective, which recovers the same information from each artifact's own embedded date and each clone's git reflog. It writes sidecar files and never modifies the existing ones.

It covers result .mat files as well as published reports — only a few scripts per model are ever published, so reports alone would leave most of the pipeline undocumented. Output is one page per run, grouping a script's report with the .mat files it wrote and ranking them by how well each is dated.

Check your display before publishing.publish() captures figures from the screen, so your X2go window size and DPI decide how figures in the report come out:

LaBGAScore_check_display% what can this session produce, and what to change

Recommended settings per screen size are in LaBGAS_fMRI_analysis_workflow.md.

Run clean/labgascore_prov_protect_reflogs.sh once per machine. Git prunes reflogs after 90 days by default, silently. The reflog is the only record of which commit a clone actually had checked out at a past moment, and it cannot be reconstructed afterwards.

DEPENDENCIES.md documents what every script in this repo calls and which repository each of those lives in. It, dependencies.tsv and dependencies.yml are generated by clean/LaBGAScore_dep_report.m — regenerate them rather than editing.

Tests and CI

There is no automated test suite and no CI pipeline in this repo. Verify changes manually by running the affected script against real or study data; several scripts support MATLAB's publish() to generate a date-stamped HTML report of their output (e.g. cosmomvpa/LaBGAScore_cosmomvpa_searchlight_rsa.m, decoding_toolbox/LaBGAScore_decoding_template_xclass_acc.m).

clean/LaBGAScore_check_all_scripts.m runs MATLAB's built-in Code Analyzer (checkcode) across every .m file in the repo (or a subtree you pass it) and reports the results, with genuine syntax errors called out separately from style/performance suggestions. It reliably catches parse errors — a file that cannot run past the flagged line — but does not catch undefined variables used at runtime, calls to functions that don't exist or aren't on the path, or logic bugs; those still require reading the code. Run it before committing as a fast baseline check, not a substitute for review.

License

GNU General Public License v3.0 — see LICENSE.

About

Core scripts (and templates for them) for LaBGAS's (Laboratory for Brain-Gut Axis Studies, KU Leuven) standard neuroimaging analysis workflow.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages