OSCR

Bayesian brain mapping: A population-informed framework for personalized functional network topography and connectivity.

Code ↔ Paper

16 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 16 matches · 1 of them tie a paragraph to a whole file without given lines: a weak match, whose lines are not tinted
  1. [1] § Methods › Population-derived priors ↔ demo/demo_step1.Rmd, lines 390 to 421 · score 0.80 · framewise displacement, head motion, filtered version, scan duration, FD, multiband · Report a mismatch
  2. [2] § Methods › The BBM hierarchical Bayesian model ↔ R/fit_BBM.R, lines 121 to 205 · score 0.79 · conjugate inverse Wishart, faster computation, mixing matrix, FC prior, correlation, zero · Report a mismatch
  3. [3] § Methods › Population-derived priors ↔ src/03_balance_age_sex.R, the whole file · a weak match · score 0.69 · overrepresented sex, balance sex, age, FD, filters, HCP · Report a mismatch
  4. [4] § Methods › Fitting the single-subject model ↔ R/id_engagements.R, lines 1 to 62 · score 0.68 · discovery rate, id_engagements, standard deviations, Bonferroni, thresholding, Fitting · Report a mismatch
  5. [5] § Methods › The BBM hierarchical Bayesian model ↔ R/VB_FC_BBM.R, lines 1 to 55 · score 0.66 · conjugate inverse Wishart, mixing matrix, correlation, zero, Cholesky, computation · Report a mismatch
  6. [6] § Methods › Population-derived priors ↔ R/rm_nuisIC.R, lines 27 to 132 · score 0.65 · global signal, nuisance components, removal, denoised, regression, ICA · Report a mismatch
  7. [7] § Results › Different templates produce similar network topography priors › BBM FC prior accurately captures population variance patterns ↔ R/estimate_prior.utils.R, lines 21 to 33 · score 0.61 · IW distribution, inverse Wishart, covariance matrices, theoretically, empirical · Report a mismatch
  8. [8] § Results › Different templates produce similar network topography priors › BBM FC prior accurately captures population variance patterns ↔ R/fit_BBM.R, lines 121 to 205 · score 0.58 · conjugate inverse Wishart, FC prior, iteratively, Cholesky, component, temporal · Report a mismatch
  9. [9] § Methods › Fitting the single-subject model ↔ R/EM_BBM.R, lines 1 to 52 · score 0.58 · expectation maximization, fMRI, iterative, variances, brain, matrices · Report a mismatch
  10. [10] § Methods › Population-derived priors ↔ R/dual_reg2.R, lines 1 to 110 · score 0.58 · nuisance regression, resampling, split, denoised, signal, volume · Report a mismatch
  11. [11] § Results › Computational demands of BBM ↔ src/shrinkage_estimation.r, lines 1 to 59 · score 0.56 · focal subject, Fitting BBM, peak, concurrent, threads, parallelized · Report a mismatch
  12. [12] § Results › Computational demands of BBM ↔ demo/demo_step1.Rmd, lines 142 to 233 · score 0.55 · peak memory, concurrent threads, GB, training, OSF, volumes · Report a mismatch
  13. [13] § Methods › The BBM hierarchical Bayesian model ↔ R/dual_reg2.R, lines 1 to 110 · score 0.54 · remove nuisance, fMRI, denoising, vectors, ICA, location · Report a mismatch
  14. [14] § Results › Different templates produce similar network topography priors › BBM FC prior accurately captures population variance patterns ↔ demo/demo_step1.Rmd, lines 305 to 367 · score 0.54 · inverse Wishart, Yeo17 template, functional connectivity, standard deviation, empirical, SD · Report a mismatch
  15. [15] § Methods › The BBM hierarchical Bayesian model ↔ R/EM_BBM.R, lines 570 to 608 · score 0.53 · diagonal matrix, correlation matrix, standard deviations, SPDE, BBM · Report a mismatch
  16. [16] § Methods › The BBM hierarchical Bayesian model ↔ R/rm_nuisIC.R, lines 27 to 132 · score 0.52 · remove nuisance components, denoising, residual, noise, ICA, fitting · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

R Markdown · 606 lines · 26 KB · no license · 3 matches

  1. ---
  2. title: "`BayesBrainMap` step 1 demo: population-derived priors"
  3. author: "Nohelia Da Silva Sanchez, Diego Derman, Saige Rutherford, Damon D. Pham, Ellyn Butler, Mary Beth Nebel, Amanda F. Mejia"
  4. output:
  5. bookdown::html_document2:
  6. toc: false
  7. number_sections: false
  8. html_document: default
  9. bibliography: references.bib
  10. citeproc: true
  11. link-citations: yes
  12. header-includes: \usepackage{pifont} \usepackage{float} \usepackage{caption}
  13. editor_options:
  14. markdown:
  15. wrap: sentence
  16. ---
  17. ```{r setup, include=FALSE}
  18. knitr::opts_chunk$set(echo = TRUE, fig.pos = "H")
  19. library(kableExtra)
  20. library(magrittr)
  21. library(knitr)
  22. library(BayesBrainMap)
  23. library(ciftiTools)
  24. library(fMRItools)
  25. library(ggplot2)
  26. wb_path <- "C:/Users/diego/Downloads/workbench-windows64-v2.1.0/workbench/bin_windows64"
  27. ciftiTools.setOption("wb_path", wb_path)
  28. #library(osfr)
  29. #osf_repo <- osf_retrieve_node("k6vx8")
  30. # setup environment
  31. dir_project <- file.path(getwd(), "..") # Path to GitHub folder
  32. dir_data <- file.path(dir_project, "data")
  33. dir_manuscript <- file.path(dir_project, "manuscript")
  34. ## Start definitions
  35. template = "Yeo17" # This can be changed later.
  36. gsr_mode = "noGSR" # This can be changed later.
  37. # precalculated priors URL look-up table
  38. prior_url_lookup <- list(
  39. Yeo17 = "https://osf.io/k6vx8/files/u2r6e",
  40. GICA15 = "https://osf.io/k6vx8/files/2dk58",
  41. GICA25 = "https://osf.io/k6vx8/files/2umyv",
  42. MSC = "https://osf.io/k6vx8/files/7knmf",
  43. PROFUMO = "https://osf.io/k6vx8/files/vsxg7"
  44. )
  45. # Default mode main component idx per template (for visualization purposes)
  46. # This can be modified to visualize other networks/components as desired.
  47. default_idx <- list(
  48. Yeo17 = 14, # DefaultA
  49. GICA15 = 2, #
  50. GICA25 = 3, #
  51. MSC = 1, #
  52. PROFUMO = 1 #
  53. )
  54. # phase encoding direction for BOLD in population priors
  55. phe = "combined"
  56. # look up table for component names per template (for visualization purposes)
  57. template_component_lookup <- list(
  58. Yeo17 = data.frame(Key = 1:17, Network = c("Visual", "Somatomotor A", "Somatomotor B", "Dorsal Attention A", "Dorsal Attention B", "Ventral Attention A", "Ventral Attention B", "Limbic A", "Limbic B", "Frontoparietal A", "Frontoparietal B", "Default A", "Default B", "Default C", "Default D", "Default E", "Unknown")),
  59. MSC = data.frame(Key = c(1:13), Component = c("Medial Wall", "Default", "Lat Vis", "Fronto-Par", "Med Vis", "Dors Attn", "Premotor", "Vent Attn", "Salience", "Cing-Operc", "Hand SM", "Face SM", "Auditory")),
  60. GICA15 = data.frame(Key = 1:15, Component = paste("IC ", c(1:15))),
  61. GICA25 = data.frame(Key = 1:25, Component = paste("IC ", c(1:25))),
  62. PROFUMO = data.frame(Key = c(1:24), Component = paste("IC ", c(1:24)))
  63. )
  64. ```
  65. ## Bayesian Brain Mapping Overview
  66. This demo accompanies the manuscript "Bayesian brain mapping: population-informed individualized functional topography and connectivity" ([Da Silva Sanchez et al., 2026](https://arxiv.org/abs/2602.01551v1)), which provides a comprehensive introduction to Bayesian Brain Mapping (BBM).
  67. Briefly, there are two steps to performing BBM, both implemented in the `BayesBrainMap` R package: *(1) prior estimation* and *(2) model fitting*.
  68. In this demo we will walk through the code for the first step. If you aim to download a pre-calculated prior based on the HCP population, or already estimated your own prior, you can skip to `demo_step2` to see how to fit the model and estimate subject-level brain maps.
  69. The code shown within this demo is intended for learning purposes, and is not intended to be run within this demo due to computational resources and data availability (we cannot share the HCP data ourselves).
  70. However, we do provide instructions for running all steps yourself and the goal is to teach you how to do so.
  71. ```{r model-overview, echo=FALSE, fig.align='center', fig.cap="Overview of Bayesian Brain Mapping. The two main steps are (1) prior estimation and (2) model fitting.", message=TRUE, warning=TRUE, out.width="100%"}
  72. knitr::include_graphics(file.path(dir_manuscript, "Figure1", "Figure1.png"))
  73. ```
  74. ## Setup
  75. To reproduce this workflow, first clone the repository to your local machine or cluster:
  76. ```{bash eval=FALSE}
  77. git clone https://github.com/mandymejia/BBM-priors.git # if you are running this file, you have already done this step
  78. cd BBM-priors/
  79. ```
  80. This GitHub repository contains the priors for the Yeo17 parcellation.
  81. If you wish to use another parcellation (i.e., GICA, MSC, PROFUMO) they can be downloaded from [OSF](https://osf.io/k6vx8/files/osfstorage).
  82. Once you have downloaded additional priors from OSF, they should be moved into the `priors/` folder within the data `folder/` to match the structure shown below.
  83. The folder structure should look like this, including a `data/templates` directory containing hard parcellations, continuous networks maps, to be used as templates for estiamting priors. The `data/posteriors` directory will contain the subject-level brain maps estimated in the model fitting step, and the `data/priors` directory will contain the population-level priors estimated in the prior estimation step (see Figure).
  84. ```{=html}
  85. <pre style="font-family: monospace; white-space: pre;">
  86. BBM-priors/
  87. ├── data/
  88. │ ├── templates/
  89. │ ├── posteriors/
  90. │ └── priors/
  91. │ └──── Yeo17/
  92. │ └──── ...
  93. ├── src/
  94. │ ├── 00_main.R
  95. │ ├── 0_setup.R
  96. │ ├── 1_fd_time_filtering.R
  97. │ └── ...
  98. ├── demo/
  99. │ └── BBM-demo.Rmd
  100. └── ...
  101. </pre>
  102. ```
  103. This section initializes the environment by loading required packages, setting analysis parameters, and defining directory paths.
  104. **Important:** Before running the workflow, you must review `0_setup.R` and install any necessary packages, ensure you have an installation of Connectome Workbench, and update the following variables to match your local or cluster environment:
  105. - `dir_project` (path to the GitHub folder)
  106. - `dir_train` (path to the HCP data)
  107. - `HCP_unrestricted_fname` (path to the unrestricted HCP CSV if you have access to it)
  108. - `HCP_restricted_fname` (path to the restricted HCP CSV if you have access to it)
  109. - `wb_path` (location of the CIFTI Workbench on your system)
  110. ```{r, echo=TRUE, message=FALSE, warning=FALSE, results='hide', eval=FALSE}
  111. github_repo_dir <- getwd()
  112. src_dir <- file.path(github_repo_dir, "../src")
  113. #source(file.path(src_dir, "setup.R"))
  114. ```
  115. ## Prior Estimation with `estimate_prior()`:
  116. ### Choosing Training Subjects
  117. 1. **Filter Subjects by Sufficient fMRI Scan Duration**
  118. See [Appendix A.1](#appendix-filtering-1) and script: `1_fd_time_filtering.R`
  119. 2. **Filter Unrelated Subjects**
  120. See [Appendix A.2](#appendix-filtering-2) and script: `2_unrelated_filtering.R`
  121. 3. **Balance sex within age groups**
  122. See [Appendix A.3](#appendix-filtering-3) and script: `3_balance_age_sex.R`
  123. The resulting subject list (`valid_combined_subjects_balanced.rds`) is used throughout the rest of the analysis.
  124. ### Run `estimate_prior()`
  125. In this step, we estimate group-level statistical priors using the `estimate_prior()` function from the `BayesBrainMap` package.
  126. We must specify the training data, processing choices, and the template file.
  127. #### Training Data
  128. The final lists of subjects saved above (`valid_combined_subjects_balanced.rds`) includes individuals who passed motion filtering in both LR and RL directions for both sessions, were unrelated, and were sex-balanced within age groups.
  129. #### Preprocessing Parameters
  130. To standardize scan duration and improve data quality, we apply both initial volume censoring and temporal truncation using parameters handled directly by the `estimate_prior()` function from the `BayesBrainMap` package.
  131. Specifically:
  132. - `drop_first = 15` removes the first 15 volumes from each scan to eliminate early signal instability and motion artifacts.
  133. - `scrub` defines volumes to censor and exclude after a target duration.
  134. We truncate data to the first 10 minutes (600 seconds), excluding any volumes beyond that point.
  135. - `hpf = 0.01` applies a high-pass filter at 0.01 Hz to remove low-frequency drift from the signal.
  136. See [Appendix B](#appendix-scrub) for more details.
  137. #### Template File
  138. Here we use the Yeo17 parcellation [@yeo2011organization] as the template.
  139. For details on how this parcellation was processed and simplified for use, see [Appendix C](#appendix-parcellations).
  140. #### Run `estimate_prior()`
  141. **Note:** The code below is provided for reference but is not evaluated in this demo.
  142. To run it yourself, you must have access to HCP data and update `dir_train` with the path to your HCP data directory.
  143. Pre-computed priors are available for download from [OSF](https://osf.io/k6vx8/files/osfstorage) and are used in the model fitting section below.
  144. Running `estimate_prior()` on the full subject list (\~350 subjects) takes approximately 27 hours and uses 6 GB of memory when run sequentially.
  145. With parallel processing enabled via `usePar`, runtime is significantly reduced. Using 48 concurrent threads, prior were estimated in 2 hours with a peak memory usage of 126 GB.
  146. ```{r warning=FALSE, eval=FALSE}
  147. # Read in template
  148. Yeo17 <- readRDS(file.path(dir_data, "templates", "Yeo17_simplified_mwall.rds"))
  149. # Exclude 0 or -1 -> medial wall
  150. valid_keys <- Yeo17$meta$cifti$labels[[1]]$Key
  151. inds <- valid_keys[valid_keys > 0]
  152. #point to training data
  153. BOLD1_fname <- "MNINonLinear/Results/rfMRI_REST1_LR/rfMRI_REST1_LR_Atlas_MSMAll_hp2000_clean.dtseries.nii"
  154. BOLD2_fname <- "MNINonLinear/Results/rfMRI_REST1_RL/rfMRI_REST1_RL_Atlas_MSMAll_hp2000_clean.dtseries.nii"
  155. BOLD1_paths <- file.path(dir_train, final_subject_ids, BOLD1_fname)
  156. BOLD2_paths <- file.path(dir_train, final_subject_ids, BOLD2_fname)
  157. #run estimate_prior
  158. prior <- estimate_prior(
  159. BOLD = BOLD1_paths,
  160. BOLD2 = BOLD2_paths,
  161. template = Yeo17,
  162. GSR = FALSE,
  163. TR = 0.72,
  164. hpf = 0.01,
  165. Q2 = 0,
  166. Q2_max = NULL,
  167. verbose = TRUE,
  168. inds = inds,
  169. brainstructures = c("left", "right"),
  170. drop_first = 15,
  171. scrub = scrub,
  172. usePar=usePar,
  173. wb_path = wb_path
  174. )
  175. # Save file
  176. saveRDS(prior, file.path(dir_prior, 'prior.rds'))
  177. ```
  178. ## Prior Visualization
  179. In this section, we visualize the Yeo17 template and the pre-estimated prior maps (mean and variance).
  180. We also visualize the functional connectivity prior.
  181. First, we load the pre-estimated prior that will be used for visualization and model fitting.
  182. This file is included in the *data_OSF* repository under `priors/Yeo17/` and can be loaded after downloading from OSF — no need to re-run `estimate_prior()`:
  183. ```{r load-prior, eval=FALSE}
  184. ################################################################################
  185. # Select template to use for the remainder of this demo
  186. template <- "Yeo17" # options: "Yeo17", "GICA15", "GICA25", "MSC", "PROFUMO"
  187. gsr_mode <- "noGSR" # options: "GSR", "noGSR"
  188. ################################################################################
  189. osf_url <- prior_url_lookup[[template]]
  190. # check if file exists. If not, download from OSF and load it. If it does, just load it.
  191. prior_fname <- file.path(dir_data, "priors", template, paste0("prior_", phe, "_", template, "_", gsr_mode,".rds"))
  192. if (!file.exists(prior_fname)) {
  193. message("Prior file not found locally. Downloading from OSF...")
  194. osf_tibble <- osf_download(osf_retrieve_file(osf_url), path = dirname(prior_fname), verbose = FALSE, progress = TRUE, conflicts = "skip")
  195. } else {
  196. message("Prior file found locally. Loading...")
  197. }
  198. # regardless, load the prior file
  199. prior <- readRDS(prior_fname)
  200. ```
  201. ### Priors for Spatial Engagement
  202. The Yeo17 parcellation divides the cortex into 17 functional networks.
  203. See [Appendix C](#appendix-parcellations) for details on how this parcellation was prepared.
  204. The `05_visualization_prior.R` script in `src/` loads each estimated prior file and plots both the mean and standard deviation.
  205. **The code below is shown for reference only.** Pre-computed plot images are included in the repository under `priors/priors_plots`, so you do not need to run this code — the figures are displayed directly below.
  206. ```{r plot-prior, eval=FALSE}
  207. # If Yeo17 template, template_parc_table needs to be updated to only reflect the correct number of labels (17)
  208. if (template == "Yeo17") {
  209. prior$template_parc_table <- subset(prior$template_parc_table, prior$template_parc_table$Key > 0)
  210. }
  211. # Plot mean
  212. plot(
  213. prior,
  214. stat = "mean",
  215. fname = file.path(dir_data, "priors", template, "plots_maps", paste0("prior_", phe, "_", template, "_", gsr_mode, "_DefaultA.png")),
  216. idx = default_idx[[template]],
  217. title = paste0(template, "Network Default (#", as.character(default_idx[[template]]),") (mean)")
  218. )
  219. # Plot standard deviation
  220. plot(
  221. prior,
  222. stat = "sd",
  223. fname = file.path(dir_data, "priors", template, "plots_maps", paste0("prior_", phe, "_", template, "_", gsr_mode, "_DefaultA.png")),
  224. idx = default_idx[[template]],
  225. title = paste0(template, "Network Default (#", as.character(default_idx[[template]]),") (sqrt varNN)")
  226. )
  227. ```
  228. ```{r model-overview2, echo=FALSE, fig.align='center', message=TRUE, warning=TRUE, out.width="100%"}
  229. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_maps", paste0("prior_", phe, "_", template, "_", gsr_mode, "_DefaultA_mean.png")))
  230. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_maps", paste0("prior_", phe, "_", template, "_", gsr_mode, "_DefaultA_sd.png")))
  231. ```
  232. ### Priors for Functional Connectivity
  233. The functional connectivity (FC) prior captures the expected correlation structure between networks.
  234. The `src/` folder contains visualization scripts for FC priors using both Cholesky and Inverse-Wishart parameterizations.
  235. This step visualizes the Functional Connectivity (FC) prior using both the Cholesky and Inverse-Wishart parameterizations.
  236. For the group-level prior, we compute and plot:
  237. - Mean FC matrix (off-diagonal values only)
  238. - Standard deviation of FC estimates (from the variance matrix)
  239. The plots are saved in: `data/priors/*template_name*/plots_FC/` with filenames indicating the template, GSR mode, and estimation method.
  240. ```{r plot-FC, eval=FALSE}
  241. # If Yeo17 template, template_parc_table needs to be updated to only reflect the correct number of labels (17)
  242. # Otherwise, no component name is provided, since this is only for demonstration purposes
  243. if (template == "Yeo17") {
  244. labs <- rownames(subset(prior$template_parc_table, prior$template_parc_table$Key > 0))
  245. } else if(template %in% c("GICA15", "GICA25", "PROFUMO", "MSC")) {
  246. labs <- template_component_lookup[[template]]$Component
  247. } else {
  248. labs <- paste0("IC ", seq(1, ncol(prior$prior$mean)))
  249. }
  250. plot_title <- paste0(template, " ", gsr_mode)
  251. FC <- prior$prior$FC
  252. legend_theme <- theme(
  253. legend.title = element_blank(),
  254. legend.text = element_text(size = 14),
  255. legend.key.height = unit(2, "cm"),
  256. legend.key.width = unit(0.6, "cm")
  257. )
  258. plots <- list(
  259. list(mat = FC$Chol$mean, lim = c(-0.8, 0.8), suffix = "Cholesky_mean", title = paste0(plot_title, " Cholesky FC Prior Mean")),
  260. list(mat = sqrt(FC$Chol$var), lim = c(0, 0.4), suffix = "Cholesky_sd", title = paste0(plot_title, " Cholesky FC Prior SD")),
  261. list(mat = FC$IW$mean, lim = c(-0.8, 0.8), suffix = "IW_mean", title = paste0(plot_title, " Inverse-Wishart FC Prior Mean")),
  262. list(mat = sqrt(FC$IW$var), lim = c(0, 0.4), suffix = "IW_sd", title = paste0(plot_title, " Inverse-Wishart FC Prior SD")),
  263. list(mat = FC$empirical$mean, lim = c(-0.8, 0.8), suffix = "Empirical_mean", title = paste0(plot_title, " Empirical FC Prior Mean")),
  264. list(mat = sqrt(FC$empirical$var), lim = c(0, 0.4), suffix = "Empirical_sd", title = paste0(plot_title, " Empirical FC Prior SD"))
  265. )
  266. for (p in plots) {
  267. plt <- plot_FC_gg(
  268. p$mat,
  269. labs = labs,
  270. lim = p$lim,
  271. labs_margin_y = -10,
  272. title = p$title
  273. ) + legend_theme
  274. ggplot2::ggsave(
  275. file.path(dir_data, "priors", template, "plots_FC", paste0("prior_", phe, "_", template, "_", gsr_mode, "_FC_", p$suffix, ".png")),
  276. plot = plt, bg = "white"
  277. )
  278. }
  279. ```
  280. #### PNG imgaes (4 per prior)
  281. - `Yeo17_FC_Cholesky_mean.png`
  282. - `Yeo17_FC_Cholesky_sd.png`
  283. - `Yeo17_FC_InverseWishart_mean.png`
  284. - `Yeo17_FC_InverseWishart_sd.png`
  285. These visualizations allow for a direct comparison of spatial FC structure and uncertainty across priors and estimation methods.
  286. The figures below show the mean and standard deviation of FC priors using Cholesky and Inverse-Wishart methods.
  287. ```{r model-overview3, echo=FALSE, fig.align='center', message=TRUE, warning=TRUE, out.width="100%"}
  288. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_FC", paste0("prior_", phe, "_", template, "_", gsr_mode, "_FC_Cholesky_mean.png")))
  289. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_FC", paste0("prior_", phe, "_", template, "_", gsr_mode, "_FC_Cholesky_sd.png")))
  290. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_FC", paste0("prior_", phe, "_", template, "_", gsr_mode, "_FC_IW_mean.png")))
  291. knitr::include_graphics(file.path(dir_data, "priors", template, "plots_FC", paste0("prior_", phe, "_", template, "_", gsr_mode, "_FC_IW_sd.png")))
  292. ```
  293. ## Appendix A: Subject Filtering {#appendix-subjectfiltering}
  294. ### Appendix A.1: Filter Subjects by Sufficient fMRI Scan Duration {#appendix-filtering-1}
  295. We begin by filtering subjects based on the fMRI scan duration after motion scrubbing For each subject, and for each session (`REST1`, `REST2`) and encoding direction (`LR`, `RL`), we compute framewise displacement (FD) using the `fMRIscrub` package.
  296. We use a lagged and filtered version of FD [@pham2023less] [@power2012spurious] [@fair2009functional] appropriate for multiband data.
  297. FD is calculated from the `Movement_Regressors.txt` file available in the HCP data for each subject, encoding and session.
  298. A volume is considered valid if it passes an FD threshold, and a subject is retained only if both sessions in both encodings have at least 10 minutes (600 seconds) of valid data.
  299. The final subject lists include those who passed the filtering criteria separately for each encoding: `LR`, `RL`, and their intersection, referred to as the`combined` list.
  300. The combined list includes only subjects who passed all criteria for both LR and RL encodings across both visits (REST1 and REST2), and is the one used throughout this project.
  301. ```{r warning=FALSE, eval=FALSE}
  302. # This script filters subjects based on motion using framewise displacement (FD)
  303. # from fMRIscrub.
  304. # For each subject, encoding (LR/RL), and session (REST1/REST2), it computes FD,
  305. # flags volumes exceeding the FD threshold of 0.5 mm (scrubbing),
  306. # and calculates valid scan time after excluding those high-motion volumes.
  307. # Subjects with ≥10 minutes of valid data in both sessions are retained.
  308. # Outputs (saved in dir_results):
  309. # - Valid subject lists for LR, RL, and combined encodings (intersection)
  310. # - FD summary per subject/session/encoding
  311. #set up path, etc.
  312. github_repo_dir <- getwd()
  313. src_dir <- file.path(github_repo_dir, "src")
  314. source(file.path(src_dir, "0_setup.R"))
  315. # Run script to exclude sessions based on head motion
  316. source(file.path(src_dir, "1_fd_time_filtering.R"))
  317. ```
  318. During this step, an FD summary table is generated with the following columns:
  319. - subject: HCP subject ID
  320. - session: REST1 or REST2
  321. - encoding: LR or RL, or combined
  322. - mean_fd: mean framewise displacement
  323. - valid_time_sec: total duration of valid data in seconds
  324. #### Preview of FD Summary Table
  325. ```{r results='asis', echo=FALSE}
  326. fd_summary <- read.csv(file.path(dir_data, "priors", "filtering", "fd_summary.csv"))
  327. kable(fd_summary[1:4, ]) %>%
  328. kable_styling(full_width = FALSE, position = "center")
  329. ```
  330. As shown above, subject 100206 qualifies for further analysis because each of the four sessions (REST1/REST2 × LR/RL) contains at least 600 seconds of valid data.
  331. The script is currently designed to filter based on valid time only, but it can be easily adapted to apply additional constraints such as maximum mean FD thresholds if desired (e.g., mean_fd \< 0.1).
  332. ### Appendix A.2: Filter Unrelated Subjects {#appendix-filtering-2}
  333. Building on the previous step, we use the HCP restricted demographic data to exclude related individuals.
  334. This step helps ensure the statistical independence of subjects in the group-level priors estimation.
  335. For the `LR`, `RL`, and `combined` lists of valid subjects derived in the previous step, we:
  336. 1. Subset the HCP restricted demographics to include only those subjects with at least 10 minutes remaining after scrubbing.
  337. 2. Filter by `Family_ID` to retain a single individual per family.
  338. Note: This step requires access to the HCP restricted data.
  339. If you do not have access, you can skip this step, resulting in some related subjects being included in your training data.
  340. ```{r warning=FALSE, eval=FALSE}
  341. # This script filters subjects to retain only unrelated individuals, using Family ID
  342. # information from the restricted HCP data.
  343. # For each encoding (LR, RL, combined), it selects one subject per family from the
  344. # FD-valid lists.
  345. # Outputs (saved in dir_personal due to restricted data):
  346. # - Unrelated subject lists for LR, RL, and combined encodings (intersection)
  347. source(file.path(src_dir, "2_unrelated_filtering.R"))
  348. ```
  349. ### Appendix A.3: Balance Sex Within Age Groups {#appendix-filtering-3}
  350. In the final step of subject selection, we balance sex across age groups to reduce potential demographic bias in priors estimation.
  351. For the `LR`, `RL`, and `combined` lists of valid subjects derived in the previous step, we:
  352. - Subset the HCP unrestricted demographics to include only those subjects.
  353. - Split subjects by age group and examine the sex distribution within each group.
  354. - If both sexes are present but imbalanced, we randomly remove subjects from the overrepresented group to achieve balance.
  355. Note: If the unrelated subject filtering step is skipped (e.g., due to lack of restricted data access), the code automatically falls back to using `valid_<encoding>_subjects_FD` instead of `valid_<encoding>_subjects_unrelated`.
  356. The final list of valid subjects is saved in `dir_results` as:
  357. - `valid_<encoding>_subjects_balanced.csv`
  358. - `valid_<encoding>_subjects_balanced.rds` (used in the prior estimation step)
  359. ```{r warning=FALSE, eval=FALSE}
  360. # This script balances sex within each age group for subjects who passed FD and
  361. # unrelated filtering.
  362. # For each encoding (LR, RL, combined), it samples subjects to equalize the number
  363. # of males and females per age group,
  364. # unless an age group includes only one gender (in which case no balancing is applied).
  365. # Uses age and gender information from the unrestricted HCP data.
  366. # Outputs (saved in dir_personal):
  367. # - Sex-balanced subject lists for LR, RL, and combined encodings (as .csv and .rds)
  368. source(file.path(src_dir, "3_balance_age_sex.R"))
  369. ```
  370. ## Appendix B: Scrubbing and Temporal Truncation {#appendix-scrub}
  371. Given the HCP TR of 0.72 seconds, 10 minutes corresponds to:
  372. ```{r warning=FALSE, eval=FALSE}
  373. T_total <- floor(600 / TR_HCP) # ~833 volumes
  374. ```
  375. To define the volumes to scrub (i.e., exclude beyond 10 minutes), we compute:
  376. ```{r warning=FALSE, eval=FALSE}
  377. T_scrub_start <- T_total + 1
  378. scrub_BOLD1 <- replicate(length(BOLD_paths1), T_scrub_start:nT_HCP, simplify = FALSE)
  379. scrub_BOLD2 <- replicate(length(BOLD_paths2), T_scrub_start:nT_HCP, simplify = FALSE)
  380. scrub <- list(scrub_BOLD1, scrub_BOLD2)
  381. ```
  382. Because `drop_first = 15` removes frames before truncation, the final retained time series per scan will be slightly shorter than 10 minutes.
  383. Approximately:
  384. ```
  385. (833 - 15) * 0.72 = ~589 seconds (~9.8 minutes)
  386. ```
  387. ## Appendix C: Prepare Yeo17 Parcellation for Prior Estimation {#appendix-parcellations}
  388. In this step, we load and preprocess a group-level cortical parcellation to be used as the template to estimate the priors in the next step.
  389. Specifically, we use the Yeo 17-network parcellation (`Yeo_17`) and perform the following operations:
  390. - Simplify the labels by collapsing hemisphere-specific naming and removing subnetwork identifiers, grouping regions by their main network.
  391. - Create a new `dlabel` object that maps each vertex to its corresponding network.
  392. - Mask out the medial wall to exclude it from analysis.
  393. The resulting parcellation is saved as `Yeo17_simplified_mwall.rds`.
  394. ```{r warning=FALSE, eval=FALSE}
  395. # This script simplifies the Yeo 17-network parcellation by collapsing region
  396. # labels and masking out the medial wall.
  397. # It creates a cleaned version of the parcellation suitable for downstream analyses.
  398. # Output:
  399. # - Saved as RDS file in dir_data: "Yeo17_simplified_mwall.rds"
  400. source(file.path(src_dir, "4_parcellations.R"))
  401. ```
  402. We can visualize the Yeo17 networks and their corresponding labels:
  403. ```{r warning=FALSE, eval=FALSE}
  404. # Load libraries
  405. library(ciftiTools)
  406. library(rgl)
  407. rgl::setupKnitr()
  408. # Load the parcellation
  409. yeo17 <- readRDS(file.path(dir_data, "outputs", "Yeo17_simplified_mwall.rds"))
  410. yeo17 <- add_surf(yeo17)
  411. view_xifti_surface(
  412. xifti = yeo17,
  413. widget = TRUE,
  414. title = "Yeo17 Network Parcellation",
  415. legend_ncol = 6,
  416. legend_fname = file.path(dir_manuscript, "parcellations_plots", "Yeo17", "Yeo17_legend.png"),
  417. fname=file.path(dir_data, "outputs", "parcellations_plots", "Yeo17")
  418. )
  419. ```
  420. ```{r, echo=FALSE, out.width="60%", fig.align="center"}
  421. knitr::include_graphics(file.path(dir_manuscript, "parcellations_plots", "Yeo17", "Yeo17.png"))
  422. ```
  423. ```{r, echo=FALSE, out.width="80%", fig.align="center"}
  424. # Show legend
  425. knitr::include_graphics(file.path(dir_manuscript, "parcellations_plots", "Yeo17", "Yeo17_legend.png"))
  426. ```
  427. ## Appendix D: Example Function Call for Prior Estimation {#appendix-example}
  428. ```{r warning=FALSE, eval=FALSE}
  429. # For detailed parameter descriptions, run: ?estimate_prior
  430. estimate_prior(
  431. BOLD = BOLD_paths1, # REST1 LR scans (list of file paths)
  432. BOLD2 = BOLD_paths2, # REST2 LR scans (same subjects/order as BOLD)
  433. template = GICA, # GICA 15-component parcellation (CIFTI dscalar file path)
  434. GSR = TRUE, # Apply global signal regression
  435. TR = 0.72, # Repetition time in seconds
  436. hpf = 0.01, # High-pass filter cutoff in Hz
  437. Q2 = 0, # No nuisance IC denoising
  438. drop_first = 15, # Drop first 15 volumes
  439. scrub = scrub, # Timepoints to scrub (list format)
  440. verbose = TRUE # Print progress updates
  441. )
  442. ```
  443. # References
  444. ::: {#refs}
  445. :::

demo_step1.Rmd at commit 145fa64, no license · at the source

Overview

  1. Department of Statistics, Indiana University, Bloomington, IN, United States
  2. Department of Psychology, Northwestern University, Evanston, IL, United States
  3. Center for Neurodevelopmental and Imaging Research, Kennedy Krieger Institute, Baltimore, MD, United States
Institutions: Indiana University Bloomington (United States); Indiana University (United States); Northwestern University (United States); Kennedy Krieger Institute (United States)
Journal: Imaging neuroscience (Cambridge, Mass.), volume 4, article IMAG.a.1411
Dates: received 20 April 2026; accepted 23 September 2026; published online 27 October 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1162/imag.a.1411 · PMID 42953563 · PMCID PMC13716283 · OpenAlex W7127433978
Open access: diamond, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: fMRI (modality), human (organism)
Methods: Spectral & time-frequency, Connectivity, Statistics, Smoothing, state filtering, decompositions, fMRI & imaging, Preprocessing
Keywords: Bayesian statistics, R toolbox, functional brain mapping, fMRI, application
MeSH: Brain*, Brain Mapping*, Magnetic Resonance Imaging*, Nerve Net*, Bayes Theorem, Connectome, Humans, Image Processing, Computer-Assisted, Neural Pathways (* major topic)
Topic: Functional Brain Connectivity Studies (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 73 references in the paper

Abstract

The spatial topography of functional brain organization is increasingly recognized to play an important role in cognition and disease. Accounting for individual differences in functional topography is also crucial for accurately distinguishing spatial and temporal aspects of functional brain connectivity. Yet, accurate estimation of personalized functional brain networks from functional magnetic resonance imaging (fMRI) without extensive scanning remains challenging due to high noise levels. Here, we describe Bayesian Brain Mapping (BBM), a technique for personalized functional topography and connectivity informed by population information. BBM relies on population-derived priors on both spatial topography of networks and between-network functional connectivity to guide subject-level estimation and combat noise. These priors are based on existing spatial templates, such as parcellations or continuous network maps, providing correspondence to those templates. Yet BBM is highly flexible, avoiding strong spatial or temporal constraints and allowing for overlap between networks and heterogeneous patterns of engagement. BBM is designed for single-subject analysis, making it computationally efficient and translatable to clinical settings. Here, we describe the BBM model and illustrate the use of the BayesBrainMap R package to construct population-derived priors, fit the model, and perform inference to identify engagements. A demo is provided in an accompanying Github repo. We also share priors derived from the Human Connectome Project and provide code to support the construction of priors from different data sources, lowering the barrier to adoption of BBM for studies of individual brain organization.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 16 matches between paragraphs and lines of code.

statMINDlab/BBM-demo

License: none: the authors keep all their rights
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Commit: 145fa64de1599cb28f6171ba9c6c8223c7c1f17c, 24 August 2026
Languages: R (33)
Size: 118 files, 33 scripts
Software Heritage: not archived
Found in: “Data and Code Availability”
Holds: README, 2 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: ggplot2 (4 files), tidyverse (4 files)
Availability: 1 check, the latest on 30 October 2026: the link answers
  • 30 October 2026: the link answers
34 files

mandymejia/BayesBrainMap

License: none: the authors keep all their rights
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Commit: 468d6e18b7715dcba8a7b19401d806186d1584c4, 5 October 2026
Languages: R (32)
Size: 133 files, 32 scripts
Software Heritage: archived
Found in: “Data and Code Availability”
Holds: README, environment (DESCRIPTION), tests, continuous integration, documentation, 1 notebook
Not found: license file, CITATION.cff
Tools: RNifti (7 files), ggplot2 (1 file)
Availability: 1 check, the latest on 30 October 2026: the link answers
  • 30 October 2026: the link answers
33 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 65 scripts, each with its path and the digest of its content;
  • 16 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data and Code Availability

The BayesBrainMap R package is available for download from CRAN and its source code is available for review in Github (https://github.com/mandymejia/BayesBrainMap).

The results of this paper can be reproduced with the code available on the dedicated Github repository (https://github.com/statMINDlab/BBM-demo). Additionally, simplified demos are also provided to facilitate the adoption of the tool, including example data and pre-calculated population priors hosted by OSF.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 October 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 7 authors, 5 keywords, 9 MeSH terms, 3 funders, 73 references.

Cite

This paper

Derman, D., Silva Sanchez, N. D., Rutherford, S., Pham, D. D., Butler, E. R., Nebel, M. B., & Mejia, A. F. (2026). Bayesian brain mapping: A population-informed framework for personalized functional network topography and connectivity. Imaging neuroscience (Cambridge, Mass.), 4, IMAG.a.1411. https://doi.org/10.1162/imag.a.1411

BibTeX

@article{derman2026bayesian,
author = {Derman, Diego and Silva Sanchez, Nohelia Da and Rutherford, Saige and Pham, Damon D and Butler, Ellyn R and Nebel, Mary Beth and Mejia, Amanda F},
title = {{Bayesian brain mapping: A population-informed framework for personalized functional network topography and connectivity}},
journal = {Imaging neuroscience (Cambridge, Mass.)},
year = {2026},
month = oct,
volume = {4},
pages = {IMAG.a.1411},
publisher = {MIT Press},
issn = {2837-6056},
doi = {10.1162/imag.a.1411},
url = {https://doi.org/10.1162/imag.a.1411},
pmid = {42953563},
pmcid = {PMC13716283}
}

RIS

TY - JOUR
AU - Derman, Diego
AU - Silva Sanchez, Nohelia Da
AU - Rutherford, Saige
AU - Pham, Damon D
AU - Butler, Ellyn R
AU - Nebel, Mary Beth
AU - Mejia, Amanda F
TI - Bayesian brain mapping: A population-informed framework for personalized functional network topography and connectivity
T2 - Imaging neuroscience (Cambridge, Mass.)
J2 - Imaging Neurosci (Camb)
PY - 2026
DA - 2026/10/27
VL - 4
SP - IMAG.a.1411
SN - 2837-6056
PB - MIT Press
DO - 10.1162/imag.a.1411
UR - https://doi.org/10.1162/imag.a.1411
LA - en
ER -

CSL-JSON

{
"id": "10.1162/imag.a.1411",
"type": "article-journal",
"title": "Bayesian brain mapping: A population-informed framework for personalized functional network topography and connectivity",
"container-title": "Imaging neuroscience (Cambridge, Mass.)",
"author": [
{
"family": "Derman",
"given": "Diego"
},
{
"family": "Silva Sanchez",
"given": "Nohelia Da"
},
{
"family": "Rutherford",
"given": "Saige"
},
{
"family": "Pham",
"given": "Damon D"
},
{
"family": "Butler",
"given": "Ellyn R"
},
{
"family": "Nebel",
"given": "Mary Beth"
},
{
"family": "Mejia",
"given": "Amanda F"
}
],
"container-title-short": "Imaging Neurosci (Camb)",
"volume": "4",
"page": "IMAG.a.1411",
"DOI": "10.1162/imag.a.1411",
"PMID": "42953563",
"PMCID": "PMC13716283",
"ISSN": "2837-6056",
"publisher": "MIT Press",
"URL": "https://doi.org/10.1162/imag.a.1411",
"language": "en",
"issued": {
"date-parts": [
[
2026,
10,
27
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41398-025-03614-x [code]
Sex differences in response to violence: role of salience network expansion and connectivity on depression.
Journal: Translational psychiatry
In common: RNifti, ggplot2, tidyverse, fMRI, 9 references, 3 authors
[2] doi:10.1162/imag_a_00504 [code]
Individual patterns of functional connectivity in neonates as revealed by surface-based Bayesian modeling.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: RNifti, fMRI, 10 references, 3 authors
[3] doi:10.1016/j.neuroimage.2023.119972 [code]
Less is more: balancing noise reduction and data retention in fMRI with data-driven scrubbing.
Journal: NeuroImage
In common: RNifti, ggplot2, tidyverse, fMRI, 7 references, 3 authors
[4] doi:10.1093/biostatistics/kxaf022 [code]
Leveraging population information in brain connectivity via Bayesian ICA with a novel informative prior for correlation matrices.
Journal: Biostatistics (Oxford, England)
In common: ggplot2, tidyverse, fMRI, 9 references, author Amanda F Mejia
[5] doi:10.1162/netn_a_00323 [code]
Controversies and progress on standardization of large-scale brain network nomenclature.
Journal: Network neuroscience (Cambridge, Mass.)
In common: fMRI, 16 references
[6] doi:10.1162/imag_a_00046 [code]
Evaluating functional brain organization in individuals and identifying contributions to network overlap.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: fMRI, 14 references
[7] doi:10.1038/s41593-024-01596-5 [code]
A precision functional atlas of personalized network topography and probabilities.
Journal: Nature neuroscience
In common: 14 references
[8] doi:10.1016/j.neuroimage.2023.120044 [code]
Comparison between gradients and parcellations for functional connectivity prediction of behavior.
Journal: NeuroImage
In common: fMRI, 14 references
[9] doi:10.1186/s12916-024-03784-3 [code]
Hierarchical individual variation and socioeconomic impact on personalized functional network topography in children.
Journal: BMC medicine
In common: ggplot2, tidyverse, fMRI, 12 references
[10] doi:10.1038/s42003-025-08509-7 [code]
Development of areal-level individualized homologous functional parcellations in youth.
Journal: Communications biology
In common: fMRI, 13 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1162/imag.a.1411.svg)](https://openscicode.org/badge/doi/10.1162/imag.a.1411)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1162/imag.a.1411.svg
   :target: https://openscicode.org/badge/doi/10.1162/imag.a.1411
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1162/imag.a.1411"><img src="https://openscicode.org/badge/doi/10.1162/imag.a.1411.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.