OSCR

Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior.

Code ↔ Paper

12 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 12 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
  1. [1] § Methods › Cerebral cortex parcellation ↔ scripts/2_normative_modeling/1_qc_euler_yeo17.py, lines 1–14 · score 0.74 · surface reconstruction, FreeSurfer, cerebral cortex, Euler, holes, normative modeling
  2. [2] § Methods › Association with behavioral performance ↔ scripts/4_behavioral_outcomes/3_behav_cereb_cortex.py, lines 87–141 · score 0.73 · fold outer, R2 scores, behavioral outcome, cross validation, concatenating, inner
  3. [3] § Methods › Cerebellar parcellation ↔ scripts/1_segmentation/func/1_fsl_func_warp.sh, the whole file · a weak match · score 0.72 · native space, MNI aligned, applywarp, FSL, MDTB, atlases
  4. [4] § Results › Growth of cerebellar association regions corresponds to socio-linguistic behavioral development ↔ scripts/4_behavioral_outcomes/3_behav_cereb_cortex.py, lines 378–456 · score 0.64 · Wilcoxon signed rank, ElasticNet, SRS, outperformed, R2, cortex
  5. [5] § Results › Cerebellar and cerebral subregions demonstrate domain-specific maturational coupling ↔ scripts/3_cerebral_associations/cerebral_assoc.py, lines 212–248 · score 0.61 · R2 scores, ElasticNet, cerebral associations, Coef, global, Ridge
  6. [6] § Methods › Cerebellar parcellation ↔ scripts/1_segmentation/func/2_func_native_vols.py, lines 33–122 · score 0.60 · native space, parcel volumes, outliers, atlases, segmentation
  7. [7] § Methods › Cerebral cortex parcellation ↔ scripts/1_segmentation/func/2_func_native_vols.py, lines 33–122 · score 0.59 · voxel volume, Parcel volumes, threshold, atlases, segmentation, normative modeling
  8. [8] § Methods › Association with behavioral performance ↔ scripts/4_behavioral_outcomes/1_behav_pls.py, lines 454–475 · score 0.57 · empirical correlation, behavioral scores, PLS, CI, brain, fitted
  9. [9] § Methods › Normative modeling ↔ scripts/2_normative_modeling/3_norm_modeling_hbr.py, lines 85–136 · score 0.56 · tuning samples, SHASHb, normative models, slope, chain, intercept
  10. [10] § Methods › Association with behavioral performance ↔ scripts/4_behavioral_outcomes/1_behav_pls.py, lines 150–182 · score 0.54 · covariance explained, latent variable, permutation, component, behaviors
  11. [11] § Methods › Normative modeling ↔ examples/04_HBR_SHASH.ipynb, lines 164–258 · score 0.51 · SHASHb, density, tuning, slope, chain, intercept
  12. [12] § Results › Growth of cerebellar association regions corresponds to socio-linguistic behavioral development ↔ scripts/4_behavioral_outcomes/1_behav_pls.py, lines 454–475 · score 0.50 · empirical correlation, Behavioral scores, PLS, brain, model

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 618 lines · 22 KB · MIT · 3 matches

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. @author: manoli
  5. """
  6. import os
  7. import numpy as np
  8. import pandas as pd
  9. import statsmodels.api as sm
  10. import matplotlib.pyplot as plt
  11. from matplotlib.patches import Rectangle
  12. from sklearn.preprocessing import StandardScaler
  13. from sklearn.model_selection import KFold
  14. from sklearn.cross_decomposition import PLSRegression
  15. from scipy.stats import pearsonr
  16. # Configure plotting style
  17. plt.rcParams.update({
  18. 'font.family': 'sans-serif',
  19. 'font.sans-serif': ['Arial'],
  20. 'axes.spines.top': False,
  21. 'axes.spines.right': False,
  22. 'axes.edgecolor': '#333333',
  23. 'axes.linewidth': 0.8
  24. })
  25. #####################################
  26. ### DATA IMPORT AND PREPROCESSING ###
  27. #####################################
  28. # Set directory
  29. data_dir = '/project/normative_cerebellum'
  30. # Import data
  31. data = pd.read_csv(os.path.join(data_dir, 'behavioral_outcomes/zscores_behaviors.csv'))
  32. behavs = data.iloc[:, 1:11] # Behavioral scores
  33. parcels = data.iloc[:, 14:] # Parcel normative z-scores
  34. behav_names = behavs.columns.tolist()
  35. parcel_names = parcels.columns.tolist()
  36. age = data['age']
  37. sex = data['sex']
  38. def residualize_data(X, confounds):
  39. """
  40. Regress out the confounds from each column of X.
  41. X: (n_samples, n_features)
  42. confounds: (n_samples, n_confounds)
  43. Returns: residualized X (same shape as X)
  44. """
  45. # Add an intercept to confounds
  46. conf = np.column_stack([np.ones(confounds.shape[0]), confounds])
  47. beta, _, _, _ = np.linalg.lstsq(conf, X, rcond=None)
  48. X_resid = X - conf @ beta
  49. return X_resid
  50. # Residualize behaviors for age and sex (to match parcels)
  51. confounds_beh = data[["age", "sex"]].values
  52. behavs_r = residualize_data(behavs, confounds_beh)
  53. # Scale data
  54. scalerX = StandardScaler()
  55. scalerY = StandardScaler()
  56. X_scaled = scalerX.fit_transform(parcels)
  57. Y_scaled = scalerY.fit_transform(behavs_r)
  58. ###############################################
  59. ### PLS COMPONENTS AND COVARIANCE EXPLAINED ###
  60. ###############################################
  61. print("\n--- Calculating PLS singular values and covariance explained ---")
  62. # Maximum number of components to analyze
  63. max_components = min(10, min(X_scaled.shape[1], Y_scaled.shape[1]))
  64. # Fit the PLS model with max_components
  65. pls = PLSRegression(n_components=max_components, scale=False)
  66. pls.fit(X_scaled, Y_scaled)
  67. # Get X and Y scores
  68. X_scores = pls.transform(X_scaled)
  69. Y_pred = pls.predict(X_scaled)
  70. # Calculate singular values (equivalent to square root of eigenvalues of X'Y Y'X)
  71. singvals = np.zeros(max_components)
  72. for i in range(max_components):
  73. # Calculate covariance between X and Y scores
  74. cov_matrix = np.cov(X_scores[:, i], Y_pred[:, i])
  75. # Scale by sqrt(n-1) to get singval equivalent
  76. singvals[i] = cov_matrix[0, 1] * np.sqrt(X_scaled.shape[0] - 1)
  77. # Calculate percentage of covariance explained by each component
  78. cv = singvals**2 / np.sum(singvals**2) * 100
  79. print("Covariance explained by each component (%):", cv)
  80. # Permutation test for null distribution
  81. print("\n--- Running permutation tests to generate null distribution ---")
  82. # Number of permutations
  83. n_permutations = 10000
  84. # Store permuted singular values
  85. perm_singvals = np.zeros((max_components, n_permutations))
  86. # Run permutation tests
  87. for perm in range(n_permutations):
  88. # Shuffle Y
  89. Y_perm = np.random.permutation(Y_scaled)
  90. # Fit PLS on permuted data
  91. pls_perm = PLSRegression(n_components=max_components, scale=False)
  92. pls_perm.fit(X_scaled, Y_perm)
  93. # Get permuted scores
  94. X_perm_scores = pls_perm.transform(X_scaled)
  95. Y_perm_pred = pls_perm.predict(X_scaled)
  96. # Calculate permuted singular values
  97. for i in range(max_components):
  98. cov_matrix = np.cov(X_perm_scores[:, i], Y_perm_pred[:, i])
  99. perm_singvals[i, perm] = cov_matrix[0, 1] * np.sqrt(X_scaled.shape[0] - 1)
  100. if (perm + 1) % 100 == 0:
  101. print(f"Completed {perm + 1} permutations")
  102. # Calculate percentage of covariance explained in the permuted models
  103. cv_perms = np.zeros_like(perm_singvals)
  104. for p in range(n_permutations):
  105. cv_perms[:, p] = perm_singvals[:, p]**2 / np.sum(perm_singvals[:, p]**2) * 100
  106. # Calculate p-values for each component
  107. p_values = np.zeros(max_components)
  108. for i in range(max_components):
  109. p_values[i] = (1 + np.sum(perm_singvals[i, :] > singvals[i])) / (1 + n_permutations)
  110. # Print summary
  111. print("\n--- Summary of Components ---")
  112. for i in range(max_components):
  113. print(f"Component {i+1}: {cv[i]:.2f}% covariance explained, p-value = {p_values[i]:.3f}")
  114. # Identify significant components
  115. sig_components = np.where(p_values < 0.05)[0] + 1
  116. print(f"\nSignificant components (p < 0.05): {sig_components}")
  117. # Plot
  118. print("\n--- Creating visualization ---")
  119. plt.figure(figsize=(7, 6))
  120. box_positions = range(max_components)
  121. boxplots = plt.boxplot(cv_perms.T, positions=box_positions, widths=0.6,
  122. patch_artist=True,
  123. boxprops=dict(facecolor='white', color='gray', linewidth=0.8),
  124. whiskerprops=dict(color='gray', linewidth=0.8),
  125. capprops=dict(color='gray', linewidth=0.8),
  126. medianprops=dict(color='gray', linewidth=1.2),
  127. flierprops=dict(marker='o', markerfacecolor='gray', markersize=3,
  128. markeredgecolor='gray', alpha=0.5))
  129. plt.scatter(box_positions, cv, s=60, c='#F9A03F', label='Effect size',
  130. edgecolor='black', linewidth=0.5, zorder=10)
  131. plt.ylim(0, 100)
  132. plt.xlabel('Latent variable', fontsize=10)
  133. plt.ylabel('% covariance explained', fontsize=10)
  134. plt.tick_params(axis='both', which='both', direction='out', length=0)
  135. plt.tick_params(axis='x', labelsize=9)
  136. plt.tick_params(axis='y', labelsize=9)
  137. plt.grid(axis='y', linestyle='--', alpha=0.2)
  138. legend_elements = [
  139. plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#F9A03F',
  140. markersize=8, markeredgecolor='black', markeredgewidth=0.5, label='Effect size'),
  141. Rectangle((0, 0), 1, 1, fc='white', ec='gray', linewidth=0.8, label='Spin null')
  142. ]
  143. plt.legend(handles=legend_elements, frameon=False, fontsize=9, loc='upper right')
  144. plt.tight_layout()
  145. # Save figure
  146. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'pls_covariance_explained.png'), bbox_inches='tight', dpi=300)
  147. ##############################################################
  148. ### PLS CROSS-VALIDATION AND PERMUTATION SIGNIFICANCE TEST ###
  149. ##############################################################
  150. # Start with unscaled data
  151. X = parcels
  152. Y = behavs_r
  153. # Set up cross-validation
  154. outer_cv = KFold(n_splits=10, shuffle=True, random_state=42)
  155. # Lists to store results
  156. train_correlations = []
  157. test_correlations = []
  158. # Perform cross-validation with normalization within each fold
  159. for fold, (train_idx, test_idx) in enumerate(outer_cv.split(X), start=1):
  160. print(f"\n=== Outer Fold {fold} ===")
  161. # Split the data
  162. X_train, Y_train = X.iloc[train_idx], Y.iloc[train_idx]
  163. X_test, Y_test = X.iloc[test_idx], Y.iloc[test_idx]
  164. # Scale within the fold using only training data
  165. scaler_X = StandardScaler()
  166. scaler_Y = StandardScaler()
  167. X_train_scaled = scaler_X.fit_transform(X_train)
  168. X_test_scaled = scaler_X.transform(X_test)
  169. Y_train_scaled = scaler_Y.fit_transform(Y_train)
  170. Y_test_scaled = scaler_Y.transform(Y_test)
  171. # Fit the model on scaled training data
  172. model = PLSRegression(n_components=1, scale=False) # scale=False since we manually scaled
  173. model.fit(X_train_scaled, Y_train_scaled)
  174. # Transform both train and test data
  175. X_train_latent = model.transform(X_train_scaled)
  176. Y_train_latent = Y_train_scaled @ model.y_weights_
  177. X_test_latent = model.transform(X_test_scaled)
  178. Y_test_latent = Y_test_scaled @ model.y_weights_
  179. # Compute correlation for training data (between latent variables)
  180. train_corr, _ = pearsonr(X_train_latent[:, 0], Y_train_latent[:, 0])
  181. train_correlations.append(train_corr)
  182. # Compute correlation for test data
  183. test_corr, _ = pearsonr(X_test_latent[:, 0], Y_test_latent[:, 0])
  184. test_correlations.append(test_corr)
  185. print(f"Fold {fold} Train Canonical Correlation: {train_corr:.3f}")
  186. print(f"Fold {fold} Test Canonical Correlation: {test_corr:.3f}")
  187. # Calculate statistics
  188. train_correlations = np.array(train_correlations)
  189. test_correlations = np.array(test_correlations)
  190. avg_train_corr = np.mean(np.abs(train_correlations))
  191. avg_test_corr = np.mean(np.abs(test_correlations))
  192. print(f"\nAverage absolute train CV canonical correlation: {avg_train_corr:.3f}")
  193. print(f"Average absolute test CV canonical correlation: {avg_test_corr:.3f}")
  194. # Perform permutation test with standardization on the full dataset
  195. n_permutations = 10000
  196. # Normalize the full dataset for the final model
  197. scaler_X_full = StandardScaler()
  198. scaler_Y_full = StandardScaler()
  199. X_scaled_full = scaler_X_full.fit_transform(X)
  200. Y_scaled_full = scaler_Y_full.fit_transform(Y)
  201. # Fit final model on normalized full data
  202. final_model = PLSRegression(n_components=1, scale=False)
  203. final_model.fit(X_scaled_full, Y_scaled_full)
  204. # Get latent scores
  205. X_latent_full = final_model.transform(X_scaled_full)
  206. Y_latent_full = Y_scaled_full @ final_model.y_weights_
  207. real_corr, _ = pearsonr(X_latent_full[:, 0], Y_latent_full[:, 0])
  208. # Store permuted correlations
  209. permuted_correlations = np.zeros(n_permutations)
  210. # Run the permutation test
  211. for i in range(n_permutations):
  212. # Shuffle Y (breaks relationship with X)
  213. Y_permuted = np.random.permutation(Y_scaled_full)
  214. # Fit PLS on shuffled data
  215. permuted_model = PLSRegression(n_components=1, scale=False)
  216. permuted_model.fit(X_scaled_full, Y_permuted)
  217. # Transform X and get the Y scores
  218. X_perm_latent = permuted_model.transform(X_scaled_full)
  219. Y_perm_latent = Y_permuted @ permuted_model.y_weights_
  220. # Compute canonical correlation on shuffled data
  221. permuted_correlations[i], _ = pearsonr(X_perm_latent[:, 0], Y_perm_latent[:, 0])
  222. # Progress update every 100 permutations
  223. if (i + 1) % 100 == 0:
  224. print(f"Completed {i + 1}/{n_permutations} permutations...")
  225. # Compute the p-value (proportion of permuted correlations >= real correlation)
  226. p_value = np.mean(np.abs(permuted_correlations) >= np.abs(real_corr))
  227. print(f"Real Canonical Correlation: {real_corr:.3f}")
  228. print(f"Permutation Test p-value: {p_value:.5f}")
  229. # Print summary statistics
  230. print("\nPLS Cross-Validation Performance Summary:")
  231. print("─" * 50)
  232. print(f"Training correlation (mean ± SD): {np.mean(train_correlations):.3f} ± {np.std(train_correlations):.3f}")
  233. print(f"Test correlation (mean ± SD): {np.mean(test_correlations):.3f} ± {np.std(test_correlations):.3f}")
  234. print(f"Null correlation (mean ± SD): {np.mean(permuted_correlations):.3f} ± {np.std(permuted_correlations):.3f}")
  235. print("─" * 50)
  236. print(f"Permutation test p-value: {p_value:.5f}")
  237. if p_value < 0.05:
  238. print(f"Result: Significant (p < 0.05)")
  239. else:
  240. print(f"Result: Not significant (p ≥ 0.05)")
  241. # Plot cross-validation
  242. plt.figure(figsize=(7, 2))
  243. # Prepare data for boxplots
  244. boxplot_data = [train_correlations, test_correlations, permuted_correlations]
  245. boxplot_labels = ['Train', 'Test', 'Null']
  246. plt.figure(figsize=(7, 2))
  247. bp = plt.boxplot(
  248. boxplot_data,
  249. labels=boxplot_labels,
  250. patch_artist=True,
  251. widths=0.4,
  252. showfliers=False,
  253. medianprops={'color': 'black', 'linewidth': 1.2},
  254. whiskerprops={'color': 'black', 'linewidth': 0.8},
  255. capprops={'color': 'black', 'linewidth': 0.8},
  256. vert=False # This makes the boxplot horizontal
  257. )
  258. for i, box in enumerate(bp['boxes']):
  259. box.set(facecolor='white', edgecolor='#333333', linewidth=0.8, alpha=0.9)
  260. plt.axvline(x=0, color='black', linestyle='-', alpha=0.3, linewidth=0.5)
  261. plt.grid(axis='x', linestyle='--', alpha=0.2)
  262. plt.xlabel("Score correlation (Pearson's r)", fontsize=9)
  263. plt.ylabel("", fontsize=9) # Empty ylabel
  264. plt.tick_params(axis='both', which='both', direction='out', length=0)
  265. plt.tick_params(axis='y', labelsize=9)
  266. plt.tick_params(axis='x', labelsize=8)
  267. all_values = np.concatenate(boxplot_data)
  268. x_min = min(np.min(all_values) * 1.1, -0.1)
  269. x_max = max(np.max(all_values) * 1.1, 0.8)
  270. plt.xlim(x_min, x_max)
  271. plt.tight_layout(pad=0.5)
  272. # Save figure
  273. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'pls_cv_boxplots.png', dpi=300, bbox_inches='tight'))
  274. ######################################################
  275. ### EXTRACT EMPIRICAL PLS CORRELATION AND LOADINGS ###
  276. ######################################################
  277. final_model = PLSRegression(n_components=1, scale=False) # scale=False since we already scaled
  278. final_model.fit(X_scaled, Y_scaled)
  279. # Convert to numpy arrays
  280. X_scaled_np = X_scaled.values if hasattr(X_scaled, 'values') else X_scaled
  281. Y_scaled_np = Y_scaled.values if hasattr(Y_scaled, 'values') else Y_scaled
  282. X_pls = final_model.transform(X_scaled_np)
  283. Y_pls = Y_scaled_np @ final_model.y_weights_
  284. real_corr, _ = pearsonr(X_pls[:, 0], Y_pls[:, 0])
  285. # Retrieve loadings
  286. brain_loadings = final_model.x_loadings_
  287. behavioral_loadings = final_model.y_loadings_
  288. print("Final in-sample canonical correlation (full data):", real_corr)
  289. # Plot behavior loadings
  290. # Get loadings for the first component and sort by absolute values
  291. loading_values = behavioral_loadings[:, 0]
  292. abs_loadings = np.abs(loading_values)
  293. sorted_indices = np.argsort(abs_loadings) # Sort in ascending order of absolute values
  294. sorted_loadings = loading_values[sorted_indices]
  295. sorted_vars = np.array(behav_names)[sorted_indices]
  296. plt.figure(figsize=(8, 10))
  297. ax = plt.gca()
  298. for i, (pos, loading) in enumerate(zip(range(len(sorted_vars)), sorted_loadings)):
  299. if loading >= 0:
  300. color = 'darkorange'
  301. else:
  302. color = 'royalblue'
  303. ax.barh(pos, loading, color=color, height=0.7)
  304. ax.set_yticks(range(len(sorted_vars)))
  305. ax.set_yticklabels(sorted_vars, fontsize=10)
  306. ax.set_xlabel("Loadings", fontsize=12)
  307. ax.axvline(x=0, color='black', linestyle='-', alpha=0.3)
  308. ax.spines['top'].set_visible(False)
  309. ax.spines['right'].set_visible(False)
  310. ax.spines['left'].set_visible(False)
  311. ax.tick_params(axis='y', which='both', left=False)
  312. ax.grid(axis='x', linestyle='--', alpha=0.3)
  313. plt.tight_layout()
  314. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'behavior_loadings.png'), dpi=300, bbox_inches='tight')
  315. # Plot brain loadings
  316. # Get loadings for the first component and sort by absolute values
  317. loading_values = brain_loadings[:, 0]
  318. abs_loadings = np.abs(loading_values)
  319. sorted_indices = np.argsort(abs_loadings) # Sort in ascending order of absolute values
  320. sorted_loadings = loading_values[sorted_indices]
  321. sorted_vars = np.array(parcel_names)[sorted_indices]
  322. plt.figure(figsize=(8, 10))
  323. ax = plt.gca()
  324. for i, (pos, loading) in enumerate(zip(range(len(sorted_vars)), sorted_loadings)):
  325. if loading >= 0:
  326. color = 'darkviolet'
  327. else:
  328. color = 'black'
  329. ax.barh(pos, loading, color=color, height=0.7)
  330. ax.set_yticks(range(len(sorted_vars)))
  331. ax.set_yticklabels(sorted_vars, fontsize=10)
  332. ax.set_xlabel("Loadings", fontsize=12)
  333. ax.axvline(x=0, color='gray', linestyle='-', alpha=0.5) # Changed to gray for better visibility against black bars
  334. ax.spines['top'].set_visible(False)
  335. ax.spines['right'].set_visible(False)
  336. ax.spines['left'].set_visible(False)
  337. ax.tick_params(axis='y', which='both', left=False)
  338. ax.grid(axis='x', linestyle='--', alpha=0.3)
  339. plt.tight_layout()
  340. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'brain_loadings.png'), dpi=300, bbox_inches='tight')
  341. # Plot empirical relationship between brain and behavior scores
  342. plt.figure(figsize=(6, 5))
  343. ax = plt.gca()
  344. plt.scatter(X_pls[:, 0], Y_pls[:, 0],
  345. alpha=0.8,
  346. s=60,
  347. color='darkviolet',
  348. edgecolors='white',
  349. linewidth=0.5)
  350. # Add regression line
  351. z = np.polyfit(X_pls[:, 0], Y_pls[:, 0], 1)
  352. p = np.poly1d(z)
  353. x_range = np.linspace(X_pls[:, 0].min(), X_pls[:, 0].max(), 100)
  354. plt.plot(x_range, p(x_range),
  355. color='darkorange',
  356. linewidth=4,
  357. linestyle='-',
  358. alpha=0.8)
  359. # Add 95% CI
  360. X_with_intercept = sm.add_constant(X_pls[:, 0])
  361. model = sm.OLS(Y_pls[:, 0], X_with_intercept).fit()
  362. X_range_with_intercept = sm.add_constant(x_range)
  363. predictions = model.get_prediction(X_range_with_intercept)
  364. ci = predictions.conf_int()
  365. plt.fill_between(x_range, ci[:, 0], ci[:, 1],
  366. color='darkorange', alpha=0.2, label='95% CI')
  367. plt.xlabel('Brain Scores (LV1)', fontsize=11, fontweight='normal')
  368. plt.ylabel('Behavior Scores (LV1)', fontsize=11, fontweight='normal')
  369. plt.grid(True, alpha=0.2, linestyle='--', linewidth=0.5)
  370. plt.tick_params(axis='both', which='both', direction='out', length=4, width=0.8)
  371. plt.tick_params(axis='both', which='major', labelsize=9)
  372. x_padding = (X_pls[:, 0].max() - X_pls[:, 0].min()) * 0.05
  373. y_padding = (Y_pls[:, 0].max() - Y_pls[:, 0].min()) * 0.05
  374. plt.xlim(X_pls[:, 0].min() - x_padding, X_pls[:, 0].max() + x_padding)
  375. plt.ylim(Y_pls[:, 0].min() - y_padding, Y_pls[:, 0].max() + y_padding)
  376. plt.tight_layout()
  377. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'pls_empirical_correlation.png'),
  378. dpi=300, bbox_inches='tight')
  379. #########################
  380. ### PLS BOOTSTRAPPING ###
  381. #########################
  382. print("\n--- Starting Bootstrap Analysis ---")
  383. # Number of bootstrap samples
  384. n_bootstrap = 10000
  385. # Arrays to store bootstrap results
  386. bootstrap_brain_loadings = np.zeros((brain_loadings.shape[0], n_bootstrap))
  387. bootstrap_behavioral_loadings = np.zeros((behavioral_loadings.shape[0], n_bootstrap))
  388. bootstrap_correlations = np.zeros(n_bootstrap)
  389. # Run the bootstrap
  390. for i in range(n_bootstrap):
  391. # Resample with replacement
  392. boot_indices = np.random.choice(X_scaled.shape[0], size=X_scaled.shape[0], replace=True)
  393. X_boot = X_scaled[boot_indices]
  394. Y_boot = Y_scaled[boot_indices]
  395. # Fit PLS on bootstrap sample
  396. boot_model = PLSRegression(n_components=1, scale=False)
  397. boot_model.fit(X_boot, Y_boot)
  398. # Store the loadings
  399. bootstrap_behavioral_loadings[:, i] = boot_model.y_weights_[:, 0]
  400. bootstrap_brain_loadings[:, i] = boot_model.x_weights_[:, 0]
  401. # Store the correlation
  402. X_boot_pls = boot_model.transform(X_boot)
  403. Y_boot_pls = boot_model.predict(X_boot)
  404. boot_corr, _ = pearsonr(X_boot_pls[:, 0], Y_boot_pls[:, 0])
  405. bootstrap_correlations[i] = boot_corr
  406. # Show progress
  407. if (i + 1) % 100 == 0:
  408. print(f"Completed {i + 1} bootstrap samples")
  409. # Calculate bootstrap statistics
  410. brain_loading_means = np.mean(bootstrap_brain_loadings, axis=1)
  411. brain_loading_std = np.std(bootstrap_brain_loadings, axis=1)
  412. brain_bootstrap_ratios = brain_loading_means / brain_loading_std
  413. behavioral_loading_means = np.mean(bootstrap_behavioral_loadings, axis=1)
  414. behavioral_loading_std = np.std(bootstrap_behavioral_loadings, axis=1)
  415. behavioral_bootstrap_ratios = behavioral_loading_means / behavioral_loading_std
  416. # Calculate 95% confidence intervals
  417. brain_ci_lower = np.percentile(bootstrap_brain_loadings, 2.5, axis=1)
  418. brain_ci_upper = np.percentile(bootstrap_brain_loadings, 97.5, axis=1)
  419. behavioral_ci_lower = np.percentile(bootstrap_behavioral_loadings, 2.5, axis=1)
  420. behavioral_ci_upper = np.percentile(bootstrap_behavioral_loadings, 97.5, axis=1)
  421. # Print bootstrap correlation statistics
  422. print(f"\nBootstrap Correlation Statistics:")
  423. print(f"Mean: {np.mean(bootstrap_correlations):.3f}")
  424. print(f"Standard Deviation: {np.std(bootstrap_correlations):.3f}")
  425. print(f"95% CI: [{np.percentile(bootstrap_correlations, 2.5):.3f}, {np.percentile(bootstrap_correlations, 97.5):.3f}]")
  426. # Determine significance using bootstrap ratios (BSR)
  427. # Threshold: |BSR| > 2.57 (≈p<0.01)
  428. bsr_threshold = 2.57
  429. # For behavioral variables
  430. behavioral_significant_bsr = np.abs(behavioral_bootstrap_ratios) > bsr_threshold
  431. # For brain variables
  432. brain_significant_bsr = np.abs(brain_bootstrap_ratios) > bsr_threshold
  433. # Print results
  434. print("\n--- Behavioral Variables Significance ---")
  435. for i, var in enumerate(behav_names):
  436. ci_sig = behavioral_ci_lower[i] * behavioral_ci_upper[i] > 0
  437. bsr_sig = behavioral_significant_bsr[i]
  438. print(f"{var}: BSR={behavioral_bootstrap_ratios[i]:.2f}, "
  439. f"CI=[{behavioral_ci_lower[i]:.3f}, {behavioral_ci_upper[i]:.3f}], "
  440. f"CI sig: {ci_sig}, BSR sig: {bsr_sig}")
  441. print("\n--- Brain Variables Significance (top 10 by |BSR|) ---")
  442. # Sort by absolute BSR for display
  443. brain_bsr_order = np.argsort(np.abs(brain_bootstrap_ratios))[::-1]
  444. for idx in brain_bsr_order[:10]:
  445. ci_sig = brain_ci_lower[idx] * brain_ci_upper[idx] > 0
  446. bsr_sig = brain_significant_bsr[idx]
  447. print(f"{parcel_names[idx]}: BSR={brain_bootstrap_ratios[idx]:.2f}, "
  448. f"CI=[{brain_ci_lower[idx]:.3f}, {brain_ci_upper[idx]:.3f}], "
  449. f"CI sig: {ci_sig}, BSR sig: {bsr_sig}")
  450. # Plot behavioral bootstrap
  451. plt.figure(figsize=(10, 8))
  452. y_pos = np.arange(len(behav_names))
  453. # Plot the bars
  454. plt.bar(y_pos, behavioral_loading_means, color='darkorange', alpha=0.7)
  455. # Add error bars for 95% CIs
  456. plt.errorbar(y_pos, behavioral_loading_means,
  457. yerr=[behavioral_loading_means - behavioral_ci_lower,
  458. behavioral_ci_upper - behavioral_loading_means],
  459. fmt='none', ecolor='black', capsize=3)
  460. # Highlight significant variables (CI doesn't cross 0)
  461. significant_vars = (behavioral_ci_lower * behavioral_ci_upper > 0)
  462. for i, sig in enumerate(significant_vars):
  463. if sig:
  464. plt.bar(y_pos[i], behavioral_loading_means[i], color='red', alpha=0.5)
  465. plt.xticks(y_pos, behav_names, rotation=45, ha='right')
  466. plt.xlabel('Behavioral Variables')
  467. plt.ylabel('Mean Bootstrap Loading')
  468. plt.title('Behavioral Loadings with 95% Bootstrap Confidence Intervals')
  469. plt.tight_layout()
  470. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'behavior_bootstrap.png'), dpi=300, bbox_inches='tight')
  471. # Plot brain bootstrap
  472. plt.figure(figsize=(10, 8))
  473. y_pos = np.arange(len(parcel_names))
  474. # Plot the bars
  475. plt.bar(y_pos, brain_loading_means, color='blue', alpha=0.7)
  476. # Add error bars for 95% CIs
  477. plt.errorbar(y_pos, brain_loading_means,
  478. yerr=[brain_loading_means - brain_ci_lower,
  479. brain_ci_upper - brain_loading_means],
  480. fmt='none', ecolor='black', capsize=3)
  481. # Highlight significant variables (CI doesn't cross 0)
  482. significant_vars = (brain_ci_lower * brain_ci_upper > 0)
  483. for i, sig in enumerate(significant_vars):
  484. if sig:
  485. plt.bar(y_pos[i], brain_loading_means[i], color='red', alpha=0.5)
  486. plt.xticks(y_pos, parcel_names, rotation=45, ha='right')
  487. plt.xlabel('Brain Variables')
  488. plt.ylabel('Mean Bootstrap Loading')
  489. plt.title('Brain Loadings with 95% Bootstrap Confidence Intervals')
  490. plt.tight_layout()
  491. plt.savefig(os.path.join(data_dir, 'behavioral_outcomes', 'brain_bootstrap.png'), dpi=300, bbox_inches='tight')

1_behav_pls.py at commit 4355bdd, under MIT · at the source

Overview

Authors: Aikaterina Manoli1,2,3, Neville Magielse1,2,4, Felix Hoffstaedter2,4, Nilsu Sağlam1, Thanos Tsigaras2,4, Augustijn A A de Boer5,6, Lorenz Ahle1, Ceyda Yalçin1, Milin Kim7,8, Torgeir Moberget7,9, Thomas Wolfers7,10,11, Casey Paquola2, Charlotte Grosse Wiesmann1,12, Andre F Marquand5,6,13, Jorn Diedrichsen14,15,16, Sofie L Valk1,2,4
16 affiliations
  1. Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig, Germany
  2. Institute of Neuroscience and Medicine (INM-7: Brain and Behaviour), Research Center Jülich, Jülich, Germany
  3. Faculty of Medicine, Leipzig University, Leipzig, Germany
  4. Institute of Systems Neuroscience, Medical Faculty and University Hospital Düsseldorf, Heinrich Heine University, Dusseldorf, Germany
  5. Donders Institute for Brain, Cognition and Behavior, Radboud University Nijmegen, Nijmegen, The Netherlands
  6. Department for Cognitive Neuroscience, Radboud University Medical Center Nijmegen, Nijmegen, The Netherlands
  7. Centre for Precision Psychiatry, Division of Mental Health and Addiction, University of Oslo and Oslo University Hospital, Oslo, Norway
  8. Department of Psychology, Faculty of Social Sciences, University of Oslo, Oslo, Norway
  9. Department of Psychology, Pedagogy and Law, School of Health Sciences, Kristiania University College, Oslo, Norway
  10. Department of Psychiatry and Psychotherapy, University of Tübingen, Tübingen, Germany
  11. German Center for Mental Health (DZPG), Jena, Germany
  12. Cognitive Neuroscience Lab, Department of Liberal Arts and Sciences, University of Technology Nuremberg, Nuremberg, Germany
  13. Department of Neuroimaging, Institute of Psychiatry, Psychology, & Neuroscience, King’s College London, London, United Kingdom
  14. Western Institute of Neuroscience, Western University, London, ON Canada
  15. Department of Statistical and Actuarial Sciences, Western University, London, ON Canada
  16. Department of Computer Science, Western University, London, ON Canada
Journal: Nature communications, volume 17, issue 1, article 4338
Dates: received 24 September 2025; accepted 27 April 2026; published online 13 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41467-026-72940-5 · PMID 42129201 · PMCID PMC13172492 · OpenAlex W7161031961
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: human (organism)
Methods: Connectivity, Statistics, Machine learning, Preprocessing, Physiology & signal measures, Smoothing, state filtering, decompositions
Keywords: Cognitive neuroscience, Human behaviour
MeSH: Cerebellum*, Cerebral Cortex*, Social Behavior*, Adolescent, Child, Child, Preschool, Cognition, Female, Humans, Infant, Magnetic Resonance Imaging, Male, Neurodevelopment, Young Adult (* major topic)
Topic: Vestibular and auditory disorders (Neurology, Neuroscience), according to OpenAlex
Funding: European Research Council (101117806)
Citations: not cited yet (Europe PMC); 98 references in the paper

Abstract

The cerebellum’s involvement in cognitive functions is increasingly recognized, yet its developmental contribution to cognition remains poorly understood. The cerebellum undergoes rapid development in early life, paralleling major cognitive and behavioral changes. Although clinical studies have linked early cerebellar disruptions to profound developmental deficits, it remains largely unclear how typical cerebellar maturation supports the development of cognitive functions and how it interacts with broader cerebral development. Here, we apply a normative modeling framework to map cerebellar volumetric growth from age one to young adulthood (N = 751; ages 1–21 years). Using both lobular and functional cerebellar parcellations, we characterize typical cerebellar development from late infancy and its relationship to cerebral development and behavioral performance in childhood through adulthood. Across parcellations, association areas consistently show steeper growth trajectories than sensorimotor areas. Cerebellar and cerebral areas with similar functional roles demonstrate coordinated maturation, and volumetric growth in the posterior cerebellum relates to individual differences in socio-linguistic behaviors. These findings establish a comprehensive reference for typical cerebellar development, highlight cerebellar co-maturation with the cerebral cortex, and underscore the cerebellum’s role in supporting the development of cognitive functions.

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 12 matches between paragraphs and lines of code.

kmanoli/NormCerebellum

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 4355bdd8545b3df693b1d141f86543fda3fa222d, 27 May 2026
Languages: Python (10), Shell (2)
Size: 329 files, 12 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: pandas (10 files), NumPy (8 files), Matplotlib (7 files), scikit-learn (6 files), NiBabel (4 files), SciPy (4 files), seaborn (4 files), statsmodels (3 files), ArviZ (1 file), FSL (1 file), neuromaps (1 file), PyMC (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
14 files

iBEAT-V2/iBEAT-V2.0-Docker

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: f701061578ecc4411d428ca57fecbaa271d727c4, 13 January 2026
Size: 1 file, 0 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
1 file

shuohan/acapulco

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 350dfd59961c90cbb098746df87c99f1802fe1f5, 4 March 2022
Languages: Python (27), Shell (1)
Size: 36 files, 28 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, environment (Dockerfile, setup.py), tests
Not found: license file, CITATION.cff, continuous integration, documentation
Tools: Keras (20 files), NumPy (12 files), NiBabel (5 files), Matplotlib (1 file), pandas (1 file), SciPy (1 file), TensorFlow (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
29 files

amarquand/PCNtoolkit

License: GPL-3.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 73b19a0f900138281d3a29b9514f2cfc631662af, 25 September 2026
Languages: Python (88), Jupyter (33)
Size: 275 files, 121 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, CITATION.cff, environment (pyproject.toml, doc/requirements.txt), tests, continuous integration, documentation, 33 notebooks
Tools: NumPy (66 files), pandas (41 files), Matplotlib (34 files), seaborn (28 files), xarray (20 files), SciPy (13 files), PyMC (10 files), scikit-learn (9 files), ArviZ (5 files), NiBabel (1 file), Connectome Workbench (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
123 files

Code availability

Image preprocessing leveraged open-source software (iBEAT V2.091: https://github.com/iBEAT-V2/iBEAT-V2.0-Docker; HCP minimal preprocessing pipeline90: https://github.com/Washington-University/HCPpipelines). Parcellations for the cerebellum and the cerebral cortex were also derived by openly available tools (ACAPULCO43: https://gitlab.com/shuohan/acapulco; FSL: https://fsl.fmrib.ox.ac.uk/fsl/docs/#/; FreeSurfer: https://surfer.nmr.mgh.harvard.edu/). ITK-SNAP93 for manual correction of segmentations is freely available online (https://itksnap.org/pmwiki/pmwiki.php). Normative modeling code is available via the PCNtoolkit25,44,45 (https://github.com/amarquand/PCNtoolkit). Scripts for all processing and analysis pipelines used in this study can be found on GitHub (https://github.com/kmanoli/NormCerebellum).

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

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:

  • 4 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 161 scripts, each with its path and the digest of its content;
  • 12 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

Datasets cited

Data Availability Statement

The present study used existing developmental data from the Lifespan BCP (https://nda.nih.gov/edit_collection.html?id=2848) and the Lifespan 2.0 HCP-D release (https://nda.nih.gov/general-query.html?q=query=featured-datasets:HCP%20Aging%20and%20Development (https://nda.nih.gov/general-query.html?q=query=featured-datasets:HCP Aging and Development)). Neuroimaging and behavioral data are publicly available for download from the provided links. The cerebellar functional atlases are available on GitHub (https://github.com/DiedrichsenLab/cerebellar_atlases). The cerebellar growth models for lobular and functional parcels are also available on GitHub (https://github.com/kmanoli/NormCerebellum). Source data are provided with this paper.

Image preprocessing leveraged open-source software (iBEAT V2.091: https://github.com/iBEAT-V2/iBEAT-V2.0-Docker; HCP minimal preprocessing pipeline90: https://github.com/Washington-University/HCPpipelines). Parcellations for the cerebellum and the cerebral cortex were also derived by openly available tools (ACAPULCO43: https://gitlab.com/shuohan/acapulco; FSL: https://fsl.fmrib.ox.ac.uk/fsl/docs/#/; FreeSurfer: https://surfer.nmr.mgh.harvard.edu/). ITK-SNAP93 for manual correction of segmentations is freely available online (https://itksnap.org/pmwiki/pmwiki.php). Normative modeling code is available via the PCNtoolkit25,44,45 (https://github.com/amarquand/PCNtoolkit). Scripts for all processing and analysis pipelines used in this study can be found on GitHub (https://github.com/kmanoli/NormCerebellum).

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, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 16 authors, 2 keywords, 14 MeSH terms, 1 funder, 91 references.

Cite

This paper

Manoli, A., Magielse, N., Hoffstaedter, F., Sağlam, N., Tsigaras, T., de Boer, A. A. A., Ahle, L., Yalçin, C., Kim, M., Moberget, T., Wolfers, T., Paquola, C., Wiesmann, C. G., Marquand, A. F., Diedrichsen, J., & Valk, S. L. (2026). Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior. Nature communications, 17(1), 4338. https://doi.org/10.1038/s41467-026-72940-5

BibTeX

@article{manoli2026cerebellar,
author = {Manoli, Aikaterina and Magielse, Neville and Hoffstaedter, Felix and Sağlam, Nilsu and Tsigaras, Thanos and de Boer, Augustijn A A and Ahle, Lorenz and Yalçin, Ceyda and Kim, Milin and Moberget, Torgeir and Wolfers, Thomas and Paquola, Casey and Wiesmann, Charlotte Grosse and Marquand, Andre F and Diedrichsen, Jorn and Valk, Sofie L},
title = {{Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior}},
journal = {Nature communications},
year = {2026},
month = may,
volume = {17},
number = {1},
pages = {4338},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/s41467-026-72940-5},
url = {https://doi.org/10.1038/s41467-026-72940-5},
pmid = {42129201},
pmcid = {PMC13172492}
}

RIS

TY - JOUR
AU - Manoli, Aikaterina
AU - Magielse, Neville
AU - Hoffstaedter, Felix
AU - Sağlam, Nilsu
AU - Tsigaras, Thanos
AU - de Boer, Augustijn A A
AU - Ahle, Lorenz
AU - Yalçin, Ceyda
AU - Kim, Milin
AU - Moberget, Torgeir
AU - Wolfers, Thomas
AU - Paquola, Casey
AU - Wiesmann, Charlotte Grosse
AU - Marquand, Andre F
AU - Diedrichsen, Jorn
AU - Valk, Sofie L
TI - Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/05/13
VL - 17
IS - 1
SP - 4338
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/s41467-026-72940-5
UR - https://doi.org/10.1038/s41467-026-72940-5
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41467-026-72940-5",
"type": "article-journal",
"title": "Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior",
"container-title": "Nature communications",
"author": [
{
"family": "Manoli",
"given": "Aikaterina"
},
{
"family": "Magielse",
"given": "Neville"
},
{
"family": "Hoffstaedter",
"given": "Felix"
},
{
"family": "Sağlam",
"given": "Nilsu"
},
{
"family": "Tsigaras",
"given": "Thanos"
},
{
"family": "de Boer",
"given": "Augustijn A A"
},
{
"family": "Ahle",
"given": "Lorenz"
},
{
"family": "Yalçin",
"given": "Ceyda"
},
{
"family": "Kim",
"given": "Milin"
},
{
"family": "Moberget",
"given": "Torgeir"
},
{
"family": "Wolfers",
"given": "Thomas"
},
{
"family": "Paquola",
"given": "Casey"
},
{
"family": "Wiesmann",
"given": "Charlotte Grosse"
},
{
"family": "Marquand",
"given": "Andre F"
},
{
"family": "Diedrichsen",
"given": "Jorn"
},
{
"family": "Valk",
"given": "Sofie L"
}
],
"container-title-short": "Nat Commun",
"volume": "17",
"issue": "1",
"page": "4338",
"DOI": "10.1038/s41467-026-72940-5",
"PMID": "42129201",
"PMCID": "PMC13172492",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41467-026-72940-5",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
13
]
]
}
}

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/s41467-026-72931-6 [code]
Three parsimonious spatiotemporal patterns in cerebellum reveal individual traits in function and behavior.
Journal: Nature communications
In common: Connectome Workbench, NiBabel, statsmodels, 6 other tools, 13 references
[2] doi:10.21203/rs.3.rs-9326213/v1 [code]
Multi-task fMRI outperforms resting-state fMRI for revealing task-invariant organization of the human brain
Journal: Research Square (preprint)
In common: neuromaps, Connectome Workbench, FSL, 7 other tools, 7 references, author Jörn Diedrichsen
[3] doi:10.64898/2026.03.09.710558 [code]
Multi-task fMRI outperforms resting-state fMRI for revealing task-invariant organization of the human brain
Journal: bioRxiv (preprint)
In common: neuromaps, Connectome Workbench, FSL, 7 other tools, 7 references, author Jörn Diedrichsen
[4] doi:10.1371/journal.pbio.3003856 [code]
Aging and metabolism contribute separately to brain-body health.
Journal: PLoS biology
In common: neuromaps, Connectome Workbench, FSL, 8 other tools, 8 references
[5] doi:10.1162/imag.a.1323 [code]
SUITPy: A Python-based toolbox for the analysis of cerebellar functional and anatomical imaging data across the human lifespan.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: NiBabel, pandas, SciPy, 2 other tools, 9 references, author Jörn Diedrichsen
[6] doi:10.1162/imag.a.1269 [code]
From early to contemporary normative modeling: Mapping individual differences in neurophysiological signals.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: ArviZ, PyMC, xarray, 8 other tools, 5 references
[7] doi:10.1038/s41586-026-10631-3 [code]
A prognostic human brain network for diffuse midline glioma.
Journal: Nature
In common: neuromaps, Keras, TensorFlow, 8 other tools, 6 references
[8] doi:10.64898/2026.08.13.26360304 [code]
Lifespan brain structural variation reveals shared organization across mental health conditions
Journal: medRxiv (preprint)
In common: NiBabel, statsmodels, seaborn, 5 other tools, 4 references, author Aikaterina Manoli
[9] doi:10.1038/s41467-026-75959-w [code]
Charting higher-order models of brain function beyond pairwise interactions.
Journal: Nature communications
In common: neuromaps, xarray, NiBabel, 7 other tools, 5 references
[10] doi:10.1038/s41398-026-03902-0 [code]
Mapping heterogeneous brain structural subtypes in alzheimer's disease and mild cognitive impairment using normative models.
Journal: Translational psychiatry
In common: ArviZ, PyMC, xarray, 8 other tools, 1 reference

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.

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: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

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