OSCR

Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals.

Code ↔ Paper

The paper beside its authors' code: matches between them have not been computed for this paper yet.

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

Jupyter notebook · 730 lines · 24 KB · no license

  1. # %%
  2. import pandas as pd
  3. import numpy as np
  4. import seaborn as sns
  5. import matplotlib.pyplot as plt
  6. from matplotlib.pyplot import figure
  7. from sklearn.preprocessing import StandardScaler
  8. from sklearn.cross_decomposition import PLSRegression, PLSCanonical
  9. from sklearn.linear_model import LogisticRegression, Ridge
  10. from scipy.stats import pearsonr
  11. from tqdm import tqdm
  12. # %% [markdown]
  13. # # Preprocessing steps
  14. # %%
  15. date = '25.05.13'
  16. # %%
  17. fixed = pd.read_csv('../EN00_03.28.23.csv')
  18. #separate numerical and non-numerical data
  19. df_cleaned_num = fixed.select_dtypes(exclude=['object'])
  20. df_cleaned_cat = fixed.select_dtypes(include=['object'])
  21. #dummy-code all categorical data
  22. df_cleaned_cat = pd.get_dummies(df_cleaned_cat, dummy_na=False)
  23. print(df_cleaned_cat.shape)
  24. #merge back categorical and numerical variables
  25. df_cleaned_merged = df_cleaned_num.join(df_cleaned_cat)
  26. print(df_cleaned_merged.shape)
  27. fixed=df_cleaned_merged
  28. fixed_cols= list(fixed.columns)
  29. print(len(fixed_cols))
  30. fixed_cols.append('APOE')
  31. #version with statins intake
  32. balanced_df = pd.read_csv('../apoe_fh_balanced_df_03.28.23.csv', index_col=0)
  33. print(balanced_df.shape)
  34. # %%
  35. baseline_df = balanced_df[fixed_cols].drop(columns=['APOE',
  36. 'APOE_3 2',
  37. 'APOE_3 3',
  38. 'APOE_4 2',
  39. 'APOE_4 3',
  40. 'APOE_4 4',])
  41. cca_cols = []
  42. for i in range(1,51):
  43. cca_cols.append(f"{i}")
  44. #keep one-hot encoded APOE genotypes
  45. #APOE e4e4 excluded
  46. apoe_gen = [ 'APOE_3 2',
  47. 'APOE_3 3',
  48. 'APOE_4 3']
  49. balanced_df = balanced_df.drop(columns=['APOE','APOE_4 2','APOE_4 4'])
  50. # %%
  51. #all Prevent_AD columns
  52. all_phens_cols = list(balanced_df.drop(columns=apoe_gen).drop(columns=cca_cols).drop(columns=['CandID','Candidate_Age_MoCA','Candidate_Age_lab']).columns)
  53. all_phens_cols
  54. #ALL columns (except APOE genotypes)
  55. all_cols = all_phens_cols.copy()
  56. for col in cca_cols:
  57. all_cols.append(col)
  58. # Data normalization and standarization
  59. scaler = StandardScaler()
  60. z_df = scaler.fit_transform(balanced_df)
  61. z_df_df = pd.DataFrame(z_df, columns = balanced_df.columns)
  62. df = balanced_df.reset_index()
  63. # Store indices for males and females
  64. id_f = np.where(df.Sex_Female==1)
  65. id_m = np.where(df.Sex_Male==1)
  66. id_all = df.index
  67. z_df_df.CandID = balanced_df.CandID
  68. # %%
  69. # columns to remove from PLS-R models to keep for regression models or later steps (e.g. subgrouping)
  70. cols_reg = ['Sex_Female',
  71. 'Sex_Male',
  72. 'father_dx_ad_dementia',
  73. 'mother_dx_ad_dementia',
  74. 'sibling_dx_ad_dementia',
  75. 'time_diff',
  76. 'Age_baseline_months']
  77. # X columns set for the PLS-R models
  78. all_phens_cols = list(balanced_df.drop(columns=apoe_gen).drop(columns=cca_cols).drop(columns=[
  79. 'CandID',
  80. 'Candidate_Age_MoCA',
  81. 'Candidate_Age_lab',
  82. 'RBANS_version_A',
  83. 'RBANS_version_B',
  84. 'RBANS_version_C',
  85. 'RBANS_version_D',
  86. 'comments',
  87. 'only_father',
  88. 'only_mother',
  89. 'both']).drop(columns=cols_reg).columns)
  90. # SUBGROUPING
  91. # maternal AD
  92. id_mat = np.where(z_df_df.only_mother>0)
  93. df_mat = z_df_df.iloc[id_mat]
  94. # paternal AD
  95. id_pat = np.where(z_df_df.only_father>0)
  96. df_pat = z_df_df.iloc[id_pat]
  97. # males
  98. id_males = np.where(z_df_df.Sex_Male>0)
  99. df_males = z_df_df.iloc[id_males]
  100. # females
  101. id_females = np.where(z_df_df.Sex_Female>0)
  102. df_females = z_df_df.iloc[id_females]
  103. # %%
  104. print(z_df_df.shape)
  105. # %% [markdown]
  106. # ## Useful functions
  107. # %%
  108. def partial_least_square(df, x_cols, y_cols,comp,plot,tag):
  109. """
  110. Fit a PLS regression model and optionally plot Y loadings.
  111. Parameters:
  112. - df: pandas.DataFrame, the input data.
  113. - x_cols: list of str, predictor column names.
  114. - y_cols: list of str, response column names.
  115. - n_components: int, number of PLS components.
  116. - plot: bool, whether to plot the Y loadings.
  117. - tag: str, used for plot titles and filenames.
  118. Returns:
  119. - fitted PLSRegression object.
  120. """
  121. pls = PLSRegression(n_components=comp)
  122. pls.fit(df[x_cols],df[y_cols])
  123. if plot:
  124. figure(figsize=(4, 4), dpi=200)
  125. sns.heatmap(
  126. pls.y_loadings_[:, :3],
  127. cmap=plt.cm.RdBu_r,
  128. center=0,
  129. vmin=-0.4, vmax=0.4,
  130. square=True,
  131. annot=True,
  132. yticklabels=[r'$\mathit{APOE}\ \epsilon$3/2',
  133. r'$\mathit{APOE}\ \epsilon$3/3',
  134. r'$\mathit{APOE}\ \epsilon$3/4'],
  135. xticklabels=[f'Comp {i+1}' for i in range(3)],
  136. cbar_kws={"shrink": 0.4}
  137. )
  138. plt.title(f'Y loadings for PLS-R on {tag}')
  139. plt.xlabel('PLS-R components')
  140. plt.subplots_adjust(top=1)
  141. output_path = f'{date}/{tag}_pls_y_loadings_all_time_points_.png'
  142. plt.savefig(output_path, dpi=200, bbox_inches='tight')
  143. plt.show()
  144. plt.close('all')
  145. return pls
  146. # %%
  147. def pls_loadings(dff, idx, tag):
  148. """
  149. Fit PLS on input data and return transformed latent components with time info.
  150. Parameters:
  151. - dff: DataFrame, data to be used for PLS fitting.
  152. - idx: list-like, indices corresponding to rows in `balanced_df` for time labels.
  153. - tag: str, label for saving plots and file outputs.
  154. - n_components: int, number of PLS components to extract.
  155. - plot: bool, whether to generate and save loading plots.
  156. Returns:
  157. - latent_factors_df: DataFrame with latent components and 'time' column.
  158. - pls_model: Trained PLSRegression object.
  159. """
  160. pls = partial_least_square(dff, all_phens_cols,apoe_gen,comp=3, plot=True, tag=tag)
  161. latent_factors_pls = pls.transform(dff[all_phens_cols])
  162. latent_factors_pls_df = pd.DataFrame(latent_factors_pls, columns=['C1', 'C2', 'C3'])
  163. return latent_factors_pls_df, pls
  164. # %%
  165. def regress_adrd(latent_factors, target, idx, tag):
  166. """
  167. Run logistic regression predicting ADRD from latent factors and interactions,
  168. and plot coefficients heatmaps separately for HC and DN patterns.
  169. """
  170. # Build the column names for main effects and interactions
  171. factor_names = latent_factors.columns.tolist()
  172. predictors = ['HC-DN_pattern'] + [f'PLS_{name}' for name in factor_names]
  173. predictors += [f'HC-DN_pattern_PLS_{name}' for name in factor_names]
  174. # Store regression coefficients
  175. coef_table = []
  176. for cca_col in cca_cols:
  177. # Prepare design matrix
  178. main_var = z_df_df.loc[idx, cca_col].values.reshape(-1, 1) # Main effect
  179. pls_vars = latent_factors.loc[idx].values # Latent factors
  180. # Interaction terms
  181. interactions = main_var * pls_vars # Element-wise multiplication
  182. X = np.hstack([main_var, pls_vars, interactions])
  183. # Target
  184. y = df.loc[idx, target].values
  185. # Fit logistic regression
  186. model = LogisticRegression(max_iter=10000)
  187. model.fit(X, y)
  188. coef_table.append(model.coef_.flatten())
  189. # Assemble into a DataFrame
  190. coef_df = pd.DataFrame(coef_table, columns=predictors)
  191. coef_df.index = [f'Component: {col}' for col in cca_cols]
  192. # --- Plotting
  193. def plot_coefficients(data, start, end, title_suffix):
  194. plt.figure(figsize=(8, 6), dpi=80)
  195. sns.heatmap(
  196. data.iloc[start:end].T,
  197. cmap=plt.cm.RdBu_r, center=0, square=True,
  198. cbar_kws={"shrink": 0.2},
  199. vmin=-0.5, vmax=0.5,
  200. xticklabels=range(1, end-start+1)
  201. )
  202. plt.title(f'Regression of maternal history of ADRD on Prevent-AD latent factors ({title_suffix})')
  203. plt.xlabel('Mode expressions')
  204. plt.tight_layout()
  205. plt.show()
  206. # Plot HC (first 25) and DN (next 25)
  207. plot_coefficients(coef_df, 0, 25, f'{tag} - HC')
  208. plot_coefficients(coef_df, 25, coef_df.shape[0], f'{tag} - DN')
  209. return coef_df
  210. # %%
  211. def regress_adrd_shuffled(latent_factors_pls_df, target, idx=id_all, tag='all'):
  212. tables = []
  213. # Column names
  214. pls_cols = list(latent_factors_pls_df.columns)
  215. cols = ['HC-DN_pattern'] + [f'PLS_{col}' for col in pls_cols] + [f'HC-DN_pattern_PLS_{col}' for col in pls_cols]
  216. for i in tqdm(range(1000)):
  217. np.random.seed(i)
  218. table = []
  219. index = []
  220. for col in cca_cols:
  221. # Prepare regressors
  222. base_regressor = z_df_df[[col]].iloc[idx].to_numpy()
  223. pls_regressors = latent_factors_pls_df.iloc[idx].to_numpy()
  224. interactions = np.array([
  225. base_regressor.squeeze() * pls_regressors[:, j]
  226. for j in range(pls_regressors.shape[1])
  227. ]).T
  228. regressors = np.hstack([base_regressor, pls_regressors, interactions])
  229. # Fit logistic regression on shuffled labels
  230. model = LogisticRegression(max_iter=10000)
  231. y = df[target].iloc[idx].to_numpy()
  232. np.random.shuffle(y)
  233. model.fit(regressors, y)
  234. coefs = model.coef_.flatten()
  235. table.append(coefs)
  236. index.append(f'Component: {int(col)}')
  237. # Collect results
  238. table_df = pd.DataFrame(table, columns=cols, index=index)
  239. tables.append(table_df)
  240. # Concatenate all shuffled iterations
  241. result = pd.concat(tables)
  242. return result
  243. # %%
  244. def compute_pvals(real_df, shuffled_df, n_components=50):
  245. """
  246. Compute empirical p-values for each coefficient based on a shuffled null distribution.
  247. Parameters:
  248. - real_df: DataFrame of real coefficients (components x variables)
  249. - shuffled_df: DataFrame of shuffled coefficients (components x variables)
  250. - n_components: Number of components to consider (default = 50)
  251. Returns:
  252. - DataFrame of empirical p-values (same shape as real_df)
  253. """
  254. pval_df = pd.DataFrame(index=[f'Component: {n}' for n in range(1, n_components + 1)],
  255. columns=real_df.columns)
  256. for n in range(1, n_components + 1):
  257. real_coefs = real_df.loc[f'Component: {n}']
  258. shuffled_coefs = shuffled_df.loc[f'Component: {n}']
  259. for var in real_coefs.index:
  260. real_val = real_coefs[var]
  261. null_dist = shuffled_coefs[var]
  262. if real_val < 0:
  263. p_val = (null_dist < real_val).sum() / len(null_dist)
  264. else:
  265. p_val = (null_dist > real_val).sum() / len(null_dist)
  266. pval_df.at[f'Component: {n}', var] = p_val
  267. return pval_df
  268. # %%
  269. def plot_masked(tdff,mask,p,tag):
  270. masked_df=tdff[mask<(p/2)]
  271. figure(figsize=(8, 6), dpi=80)
  272. sns.heatmap(masked_df.iloc[:25,:].T, cmap=plt.cm.RdBu_r, center=0, square=True, cbar_kws={"shrink": 0.2}, vmin=-0.55, vmax=0.55,xticklabels=range(1,26))
  273. plt.title(f'Regression of maternal history of ADRD on the Prevent-AD latent factors for {tag}')
  274. plt.xlabel('HC mode expressions')
  275. plt.subplots_adjust(top=1)
  276. #plt.savefig(f'{date}/linear_regression_coefficients_ad_{tag}_hc.png', dpi=200, bbox_inches='tight')
  277. #plt.show()
  278. #figure(figsize=(8, 6), dpi=80)
  279. sns.heatmap(masked_df.iloc[25:,:].T, cmap=plt.cm.RdBu_r, center=0, square=True, cbar_kws={"shrink": 0.2}, vmin=-0.55, vmax=0.55, xticklabels=range(1,26))
  280. plt.title(f'Regression of maternal history of ADRD on the Prevent-AD latent factors for {tag}')
  281. plt.xlabel('DN mode expressions')
  282. #plt.ylabel('HC & DN Canonical variates')
  283. plt.subplots_adjust(top=1)
  284. #plt.savefig(f'{date}/linear_regression_coefficients_ad_{tag}_dn.png', dpi=200, bbox_inches='tight')
  285. plt.show()
  286. # %% [markdown]
  287. # ## PLS-R on all participants
  288. # %%
  289. date = '25.05.13'
  290. # %%
  291. import warnings
  292. warnings.simplefilter(action='ignore', category=FutureWarning)
  293. # %%
  294. latent_factors_pls_df, pls = pls_loadings(z_df_df,z_df_df.index, 'all participants')
  295. # %%
  296. latent_factors_pls_df.shape
  297. # %%
  298. print(pls.y_loadings_)
  299. # %%
  300. tables_m = regress_adrd(latent_factors_pls_df.copy(), 'only_mother', id_m, 'males')
  301. tables_m.to_csv(f'{date}/tables_m.csv')
  302. # Permutation analyses
  303. shuffled_tables_m = regress_adrd_shuffled(latent_factors_pls_df.copy(), 'only_mother', id_m, 'males')
  304. # Compute empirical p-values
  305. pvals_df_m = compute_pvals(tables_m, shuffled_tables_m)
  306. # %%
  307. tables_f = regress_adrd(latent_factors_pls_df, 'only_mother', id_f, 'females')
  308. tables_f.to_csv(f'{date}/tables_f.csv')
  309. # Permutation analyses
  310. shuffled_tables_f = regress_adrd_shuffled(latent_factors_pls_df, 'only_mother', id_f, 'females')
  311. # Compute empirical p-values
  312. pvals_df_f = compute_pvals(tables_f, shuffled_tables_f)
  313. # %%
  314. # Set common parameters
  315. p = 0.05
  316. ylabels = [
  317. 'Main effect HC/DN pattern',
  318. 'Main effect IP1',
  319. 'Main effect IP2',
  320. 'Main effect IP3',
  321. 'HC/DN pattern x IP1',
  322. 'HC/DN pattern x IP2',
  323. 'HC/DN pattern x IP3',
  324. ]
  325. # HC part (rows 0-25)
  326. figure(figsize=(8, 6), dpi=80)
  327. for tables, pvals, tag, hatch_style in [
  328. (tables_m, pvals_df_m, 'males', '//'),
  329. (tables_f, pvals_df_f, 'females', '\\\\')
  330. ]:
  331. masked_df = tables[pvals < (p / 2)]
  332. sns.heatmap(
  333. masked_df.iloc[:25, :].T,
  334. cmap=plt.cm.RdBu_r, center=0, square=True,
  335. cbar_kws={"shrink": 0.2},
  336. vmin=-0.55, vmax=0.55,
  337. xticklabels=range(1, 26),
  338. yticklabels= ylabels,
  339. )
  340. # Add hatch for both males and females
  341. plt.pcolor(masked_df.iloc[:25, :].T, hatch=hatch_style, alpha=0.)
  342. plt.title('Regression of maternal history of ADRD on the Prevent-AD latent factors for males vs. females')
  343. plt.xlabel('HC mode expressions')
  344. plt.legend(['males', 'females'], loc='upper right', bbox_to_anchor=(1.74, 1))
  345. plt.savefig(f'{date}/linear_regression_coefficients_ad_hc.png', dpi=200, bbox_inches='tight')
  346. plt.show()
  347. # DN part (rows 25+)
  348. figure(figsize=(8, 6), dpi=80)
  349. for tables, pvals, tag, hatch_style in [
  350. (tables_m, pvals_df_m, 'males', '//'),
  351. (tables_f, pvals_df_f, 'females', '\\\\')
  352. ]:
  353. # Two-tailed test
  354. masked_df = tables[pvals < (p / 2)]
  355. sns.heatmap(
  356. masked_df.iloc[25:, :].T,
  357. cmap=plt.cm.RdBu_r, center=0, square=True,
  358. cbar_kws={"shrink": 0.2},
  359. vmin=-0.55, vmax=0.55,
  360. xticklabels=range(1, 26),
  361. yticklabels= ylabels,
  362. )
  363. plt.pcolor(masked_df.iloc[25:, :].T, hatch=hatch_style, alpha=0.)
  364. plt.title('Regression of maternal history of ADRD on the Prevent-AD latent factors for males vs. females')
  365. plt.xlabel('DN mode expressions')
  366. plt.legend(['males', 'females'], loc='upper right', bbox_to_anchor=(1.74, 1))
  367. plt.savefig(f'{date}/linear_regression_coefficients_ad_dn.png', dpi=200, bbox_inches='tight')
  368. plt.show()
  369. # %% [markdown]
  370. # # Plotting PLS projections
  371. # %%
  372. from nilearn import datasets as ds
  373. from nilearn.maskers import NiftiLabelsMasker, NiftiMasker
  374. from nilearn.image import resample_img, index_img
  375. import nilearn.datasets as ds
  376. from nilearn import plotting
  377. # %%
  378. # Hippocampus (HC) data
  379. BL00_HC = pd.read_csv('../HC_segmentation/csv/BL00_HC_left_right.csv', index_col=0)
  380. col_HC = list(BL00_HC.columns)[0:-4]
  381. col_HC.remove('Whole_hippocampal_body_left')
  382. col_HC.remove('Whole_hippocampal_head_left')
  383. col_HC.remove('Whole_hippocampus_left')
  384. col_HC.remove('PSCID_left')
  385. # Default network (DN) data
  386. BL00_DN = pd.read_csv('../BL00_DN.csv', index_col=0)
  387. col_DN = BL00_DN.columns
  388. # %%
  389. date = '25.05.13'
  390. # %%
  391. fig, axes = plt.subplots(1, 3, figsize=(8, 6), sharey=True, dpi=75) # 1 row, 3 columns
  392. barWidth = 0.20
  393. x = np.array([0, 1]) # DN, HC
  394. for i in range(1, 4):
  395. ax = axes[i-1]
  396. results = {}
  397. # Compute percentages for each sex
  398. for sex in ['males', 'females']:
  399. # Default Network
  400. dn_path = f'{date}/brain_imaging/interactions_pls_c{i}_dn_{sex}_age_not_regressed_2025.csv'
  401. dn = pd.read_csv(dn_path, names=col_DN)
  402. data = dn.mean()
  403. pos_total = data[data > 0].sum()
  404. neg_total = -data[data < 0].sum()
  405. total = pos_total + neg_total
  406. dn_pos = pos_total / total * 100
  407. dn_neg = neg_total / total * 100
  408. # Hippocampus
  409. hc_path = f'{date}/brain_imaging/interactions_pls_c{i}_hc_{sex}_age_not_regressed_2025.csv'
  410. hc_mean = pd.read_csv(hc_path, names=col_HC).mean()
  411. pos_total = hc_mean[hc_mean > 0].sum()
  412. neg_total = -hc_mean[hc_mean < 0].sum()
  413. total = pos_total + neg_total
  414. hc_pos = pos_total / total * 100
  415. hc_neg = neg_total / total * 100
  416. results[sex] = {'dn': (dn_neg, dn_pos), 'hc': (hc_neg, hc_pos)}
  417. # Offsets for side-by-side bars
  418. gap = 0.05 # space between male and female bars
  419. # Adjusted offsets
  420. x_male = x - barWidth/2 - gap/2
  421. x_female = x + barWidth/2 + gap/2
  422. # Males (hatched)
  423. for idx, region in enumerate(['dn', 'hc']):
  424. neg, pos = results['males'][region]
  425. ax.bar(x_male[idx], neg, width=barWidth, color='blue', edgecolor='black', hatch='//', alpha=0.8)
  426. ax.bar(x_male[idx], pos, width=barWidth, bottom=neg, color='red', edgecolor='black', hatch='//', alpha=0.8)
  427. # Females (no hatch)
  428. for idx, region in enumerate(['dn', 'hc']):
  429. neg, pos = results['females'][region]
  430. ax.bar(x_female[idx], neg, width=barWidth, color='blue', edgecolor='black', alpha=0.8)
  431. ax.bar(x_female[idx], pos, width=barWidth, bottom=neg, color='red', edgecolor='black', alpha=0.8)
  432. ax.set_xticks(x)
  433. ax.set_xticklabels(['DN', 'HC'])
  434. ax.set_title(f'Intermediate phenotype {i}', fontweight='bold', fontsize=11)
  435. if i == 1:
  436. ax.set_ylabel('Percentage', fontsize=11)
  437. # Add a single legend
  438. from matplotlib.patches import Patch
  439. legend_elements = [
  440. Patch(facecolor='red', edgecolor='black', label='Maternal', alpha=0.8),
  441. Patch(facecolor='blue', edgecolor='black', label='Paternal', alpha=0.8),
  442. Patch(facecolor='white', edgecolor='black', hatch='//', label='Men', alpha=1),
  443. Patch(facecolor='white', edgecolor='black', label='Women', alpha=1)
  444. ]
  445. fig.legend(handles=legend_elements, loc='upper right', ncol=4, frameon=True)
  446. plt.tight_layout(rect=[0, 0, 1, 0.96])
  447. plt.savefig('Supplementary_Figure_S13.png', dpi=200, bbox_inches='tight')
  448. plt.show()
  449. # %%
  450. # Loop over PLS components
  451. for i in range(1, 4):
  452. for sex in ['males', 'females']:
  453. # Load data for DN projections
  454. dn_path = f'{date}/brain_imaging/interactions_pls_c{i}_dn_{sex}_age_not_regressed_2025.csv'
  455. dn = pd.read_csv(dn_path, names=col_DN)
  456. # Print sorted mean projections for inspection
  457. print(dn.mean().sort_values())
  458. # Get top 40 regions with highest absolute mean projection
  459. top_ids = dn.mean().abs().sort_values(ascending=False).head(40).index
  460. # Order these regions by signed mean value (low to high)
  461. ids_ordered = dn.mean()[top_ids].sort_values().index
  462. # Generate cleaned region labels
  463. new_labels = []
  464. for col in ids_ordered:
  465. col = col.replace('LH', 'left').replace('RH', 'right')
  466. parts = col.split('_')
  467. # Safe check for expected naming pattern
  468. if len(parts) >= 4:
  469. name = f"{parts[2]}_{parts[3]}_({parts[0]})"
  470. name = name.replace('_', ' ')
  471. else:
  472. name = col # fallback
  473. new_labels.append(name)
  474. # Create the heatmap
  475. plt.figure(figsize=(12, 0.3), dpi=80)
  476. ax = sns.heatmap(
  477. pd.DataFrame(dn.mean()[ids_ordered], columns=['DN']).T,
  478. cmap=plt.cm.RdBu_r,
  479. vmin=-0.30, vmax=0.30,
  480. xticklabels=new_labels
  481. )
  482. # Adjust aesthetics
  483. ax.xaxis.tick_top()
  484. plt.xticks(rotation=90)
  485. plt.yticks(rotation=0)
  486. plt.title(f'{sex}: Component {i}', pad=20)
  487. # Save figure
  488. output_path = f'{date}/brain_imaging/{sex}_dn_projections_pls_c{i}_2025.png'
  489. plt.savefig(output_path, dpi=200, bbox_inches='tight')
  490. plt.show()
  491. plt.close()
  492. # %%
  493. # Loop over 3 PLS components
  494. for i in range(1, 4):
  495. for sex in ['males', 'females']:
  496. # Load HC projection values and compute mean per region
  497. hc_path = f'{date}/brain_imaging/interactions_pls_c{i}_hc_{sex}_age_not_regressed_2025.csv'
  498. hc_mean = pd.read_csv(hc_path, names=col_HC).mean().sort_values()
  499. # Clean region labels for plot display
  500. cleaned_labels = []
  501. for col in hc_mean.index:
  502. label = col.replace('_', ' ')
  503. label = label.replace('right', '(right)').replace('left', '(left)')
  504. cleaned_labels.append(label)
  505. # Create the heatmap
  506. plt.figure(figsize=(12, 5), dpi=80)
  507. ax = sns.heatmap(
  508. pd.DataFrame(hc_mean, columns=['HC']).T,
  509. square=True,
  510. cbar_kws={"shrink": 0.5},
  511. cmap=plt.cm.RdBu_r,
  512. vmin=-0.30, vmax=0.30,
  513. xticklabels=cleaned_labels
  514. )
  515. # Adjust plot aesthetics
  516. plt.title(f'HC projections for PLS component {i} in {sex}', pad=20)
  517. plt.xticks(rotation=90)
  518. plt.yticks(rotation=0)
  519. # Save and display plot
  520. output_path = f'{date}/brain_imaging/{sex}_hc_projections_pls_c{i}_2025.png'
  521. plt.savefig(output_path, dpi=200, bbox_inches='tight')
  522. plt.show()
  523. plt.close()
  524. # %%
  525. yeo = ds.fetch_atlas_schaefer_2018(n_rois=400, yeo_networks=7)
  526. # dump DMN results in nifti format
  527. masker = NiftiLabelsMasker(labels_img=yeo.maps)
  528. masker.fit()
  529. # %%
  530. # Loop over 3 PLS components
  531. for i in range(3):
  532. # ---------------------------
  533. # Males
  534. # ---------------------------
  535. # Load DN interaction weights for males and average across rows
  536. dn = pd.read_csv(f'{date}/brain_imaging/interactions_pls_c{i+1}_dn_males_age_not_regressed_2025.csv', names=col_DN)
  537. dn = dn.mean()
  538. # Identify DMN regions from the Yeo atlas
  539. b_is_DMN = pd.Series(np.array(yeo.labels, dtype=str)).str.contains('Default').values
  540. # Initialize zero array for 400 brain regions and assign weights to DMN regions only
  541. out_DMN_weights = np.zeros((1, 400))
  542. out_DMN_weights[0, b_is_DMN] = dn.values
  543. # Reconstruct and save the Nifti image
  544. out_nii = masker.inverse_transform(out_DMN_weights)
  545. out_nii.to_filename(f'{date}/brain_imaging/males_IP{i+1}.nii.gz')
  546. # ---------------------------
  547. # Females
  548. # ---------------------------
  549. # Load DN interaction weights for females and average across rows
  550. dn = pd.read_csv(f'{date}/brain_imaging/interactions_pls_c{i+1}_dn_females_age_not_regressed_2025.csv', names=col_DN)
  551. dn = dn.mean()
  552. # Identify DMN regions from the Yeo atlas
  553. b_is_DMN = pd.Series(np.array(yeo.labels, dtype=str)).str.contains('Default').values
  554. # Initialize zero array for 400 brain regions and assign weights to DMN regions only
  555. out_DMN_weights = np.zeros((1, 400))
  556. out_DMN_weights[0, b_is_DMN] = dn.values
  557. # Reconstruct and save the Nifti image
  558. out_nii = masker.inverse_transform(out_DMN_weights)
  559. out_nii.to_filename(f'{date}/brain_imaging/females_IP{i+1}.nii.gz')
  560. # %%
  561. for i in range(1, 4):
  562. # Plot for females
  563. stat_img = f'{date}/brain_imaging/females_IP{i}.nii.gz'
  564. display = plotting.plot_stat_map(stat_img,
  565. display_mode='mosaic',
  566. cut_coords=10,
  567. cmap='RdBu_r',
  568. symmetric_cbar=True,
  569. vmax=0.30,
  570. threshold=0,
  571. black_bg=True,
  572. output_file=f'{date}/brain_imaging/10_cut_all_females_IP{i}.png'
  573. )
  574. # display.title(f'Intermediate phenotype {i}: Females', size=30)
  575. # Plot for males
  576. stat_img = f'{date}/brain_imaging/males_IP{i}.nii.gz'
  577. display = plotting.plot_stat_map(stat_img,
  578. display_mode='mosaic',
  579. cut_coords=10,
  580. cmap='RdBu_r',
  581. symmetric_cbar=True,
  582. vmax=0.30,
  583. threshold=0,
  584. black_bg=True,
  585. output_file=f'{date}/brain_imaging/10_cut_all_males_IP{i}.png',
  586. )
  587. # display.title(f'Intermediate phenotype {i}: Males', size=30)

2025_Brain_Imaging_Analyses.ipynb at commit 7eb9f79, no license · at the source

Overview

Authors: Chloé Savignac1,2,3, Frédéric St-Onge2,4, Sylvia Villeneuve4,5,6,7,8, AmanPreet Badhwar9,10, Sarah A. Gagliano Taliun11,12, Sali Farhan6,13, Maiya Geddes4,5,6,14,15, Yasser Iturria Medina6,7,16, Judes Poirier4,5,6,8, R. Nathan Spreng4,5,6,7,8,17, Danilo Bzdok1,3,7,18, PREVENT-AD Research Group
ORCID iDs: Chloé Savignac
18 affiliations
  1. Department of Biomedical Engineering, Faculty of Medicine, McGill University, Montreal, QC, Canada
  2. Integrated Program in Neuroscience, Faculty of Medicine, McGill University, Montreal, QC, Canada
  3. Mila – Quebec Artificial Intelligence Institute, Montreal, QC, Canada
  4. Research Center of the Douglas Mental Health Institute, Montreal, QC, Canada
  5. Centre for Studies in the Prevention of Alzheimer’s Disease, Douglas Mental Health Institute, McGill University, Montreal, QC, Canada
  6. Department of Neurology and Neurosurgery, Montreal Neurological Institute (MNI), Faculty of Medicine, McGill University, Montreal, QC, Canada
  7. McConnell Brain Imaging Centre (BIC), MNI, Faculty of Medicine, McGill University, Montreal, QC, Canada
  8. Department of Psychiatry, Faculty of Medicine, McGill University, Montreal, QC, Canada
  9. Department of Pharmacology and Physiology & Institute of Biomedical Engineering, Faculty of Medicine, Université de Montréal, Montreal, QC, Canada
  10. Centre de Recherche de L’Institut Universitaire de Gériatrie de Montréal (CRIUGM), Montreal, QC, Canada
  11. Department of Neurosciences & Department of Medicine, Faculty of Medicine, Université de Montréal, Montreal, QC, Canada
  12. Montreal Heart Institute, Montréal, QC, Canada
  13. Department of Human Genetics, Faculty of Medicine, McGill University, Montreal, QC, Canada
  14. Research Centre for Studies in Aging, Douglas Mental Health Institute, McGill University, Montreal, QC, Canada
  15. McGill University Research Centre for Studies in Aging, Montreal, QC, Canada
  16. Ludmer Centre for Neuroinformatics and Mental Health, McGill University, Montreal, QC, Canada
  17. Department of Psychology, Faculty of Medicine, McGill University, Montreal, QC, Canada
  18. School of Computer Science, McGill University, Montreal, QC, Canada
Journal: Cell reports. Medicine, volume 7, issue 8, article 102943
Dates: received 16 December 2025; accepted 30 June 2026; published online 28 July 2026; in print August 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.1016/j.xcrm.2026.102943 · PMID 42520805 · PMCID PMC13522784 · OpenAlex W7171510426
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: human (organism), Alzheimer's / dementia (population), clinical / translational (subfield)
Methods: Connectivity, Spectral & time-frequency, Statistics, Machine learning, Smoothing, state filtering, decompositions
Keywords: lineage, phenomics, PREVENT-AD, Alzheimer’s disease, family risk, parent-of-origin effects
MeSH: Alzheimer Disease*, Cardiovascular Diseases*, Genetic Predisposition to Disease*, Aged, Cognition, Female, Humans, Male, Parents, Phenotype, Risk Factors (* major topic)
Topic: Dementia and Cognitive Impairment Research (Psychiatry and Mental health, Medicine), according to OpenAlex
Funding: Fonds de la Recherche du Québec – Nature et Technologies; Santé; Canadian Institutes of Health Research (438531, 470425); Brain Canada Foundation; Canada Brain Research Fund; Health Canada; National Institutes of Health (R01 AG068563A, R01 R01DA053301-01A1); Healthy Brains Healthy Lives Initiative; Canada First Research Excellence Fund; Google; Canada CIFAR AI Chairs; Canada Institute for Advanced Research; CIHR; FRQS; J.L. Levesque Foundation; McGill University; Pfizer Canada; Douglas Hospital Research Centre and Foundation; Government of Canada; Canada Fund for Innovation
Citations: not cited yet (Europe PMC); 95 references in the paper

Abstract

Alzheimer’s disease (AD) has a higher prevalence in women than men and is more frequently inherited from mothers than fathers. Yet, while neuroimaging and biomarker studies link maternal family history to stronger AD-related alterations, epidemiological studies suggest that paternal history confers comparable or even greater risk. Here, we leverage the deeply profiled PREVENT-AD cohort to derive three intermediate phenotypes of AD susceptibility. Drawing on nearly 1,000 individual study visits, we quantify how these intermediate phenotypes vary as a function of maternal versus paternal AD lineage. We show that lineage-specific differentiation, including both maternal and paternal biases, is reflected in the brain structure and phenome of adult children of AD patients. Cognitive and cardiovascular risk markers, together with associated genetic variants, show the strongest differentiation along the parental-lineage spectrum of disease susceptibility relative to other correlates of AD burden. Our cross-generational analysis ultimately delineates multidimensional parent-of-origin effects in AD genealogy.

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

Repositories

Its files are read in the Code ↔ Paper reader above.

chloesavignac/PREVENTAD

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 7eb9f79987a57fb06e23637c32468c59e9ef4295, 2 June 2026
Languages: Jupyter (5), Python (2)
Size: 1,091 files, 7 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, 5 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (7 files), pandas (7 files), scikit-learn (6 files), Matplotlib (5 files), seaborn (5 files), Nilearn (4 files), SciPy (4 files), Plotly (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
8 files

Zenodo 20355121

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data and code availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
At the source:

Zenodo 14915601

License: BSD-3-Clause
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the text, “Key resources table”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (24 files), Matplotlib (4 files), pandas (2 files), scikit-learn (2 files), NiBabel (1 file), SciPy (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
97 files

thomasyeolab/cbig

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 35b5664bec8822e2f77da5e090e96f91d0095be6, 31 August 2026
Languages: MATLAB (2100), Shell (651), Python (571), C (113), C++ (65), C/C++ (62), R (25), Jupyter (5)
Size: 9,187 files, 3,592 scripts
Software Heritage: not archived
Found in: the text, “Brain-imaging data preprocessing”
Holds: README, license file, environment (external_packages/python/mapalign-master/requirements.txt, external_packages/python/mapalign-master/setup.py, external_packages/python/yapf-master/setup.cfg, external_packages/python/yapf-master/setup.py), tests, documentation, 2 notebooks
Not found: CITATION.cff, continuous integration
Tools: NumPy (130 files), PyTorch (122 files), FreeSurfer (93 files), SciPy (61 files), FieldTrip (60 files), Statistics and Machine Learning Toolbox (50 files), FSL (44 files), SPM (40 files), GIfTI library for MATLAB (10 files), Image Processing Toolbox (8 files), Connectome Workbench (8 files), scikit-learn (5 files), AFNI (2 files), Matplotlib (2 files), Tools for NIfTI and ANALYZE image (MATLAB) (2 files), ANTs (1 file), NiBabel (1 file), Nilearn (1 file), tedana (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
2,000 files

joblib/joblib

License: BSD-3-Clause
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: f3f61b27b50f4ed32fadb439f573d00d7ef07cb0, 24 September 2026
Languages: Python (92), Shell (7)
Size: 142 files, 99 scripts
Software Heritage: archived
Found in: the Zenodo archive record
Holds: README, license file, CITATION.cff, environment (pyproject.toml, joblib/test/_openmp_test_helper/setup.py), tests, continuous integration, documentation
Tools: NumPy (24 files), Matplotlib (4 files), scikit-learn (3 files), pandas (2 files), NiBabel (1 file), SciPy (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
101 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:

  • 5 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 2,199 scripts, each with its path and the digest of its content;
  • no match between paragraphs and code yet;
  • 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

• Data used in the preparation of this article were obtained from the Pre-symptomatic Evaluation of Novel or Experimental Treatments for Alzheimer’s Disease (PREVENT-AD) program, data release 6.0. PREVENT-AD is managed by The Centre for Studies on the Prevention of Alzheimer’s Disease (StoP-AD) at the Douglas Mental Health University Institute Research Centre, affiliated with McGill University (https://douglas.research.mcgill.ca/stop-ad-centre). Data management at the StoP-AD Centre is carried out through LORIS (https://loris.ca), which provides the technical infrastructure to manage the acquisition, storing, and conservation of data in order to facilitate data sharing with the greater research community. The PREVENT-AD Open Repository is publicly accessible through the Canadian Open Neuroscience Platform (CONP; ARK ID: https://n2t.net/ark:/70798/d78m93q8n7w4g20mhj) and the institutionally hosted database (https://openpreventad.loris.ca). The Open Repository includes MRI data and basic demographic information. Access requires the creation of an account through https://openpreventad.loris.ca/login/request-account/. Users must agree not to commercialize the dataset or claim intellectual property rights over it; not to attempt to re-identify or re-contact participants, including through linkage with other datasets; to obtain any required ethical approvals; to use the data exclusively for neuroscience research as permitted by participant consent; not to redistribute the data outside the repository; and to comply with monitoring requests and report any breaches of these terms. Eligible academic researchers and physicians may apply for access to the PREVENT-AD Registered Repository, which contains a more comprehensive set of participant data. The Registered Repository is available through CONP (ARK ID: https://n2t.net/ark:/70798/d7j9dvk4777m366kfb) and the institutionally hosted database (https://registeredpreventad.loris.ca). Access requests can be submitted at https://registeredpreventad.loris.ca/login/request-account/. Available data include PET imaging, medical information, genetic data, self-reported questionnaires, neuropsychological assessments, neurosensory evaluations, CSF protein measurements, and magnetoencephalography data. Access is subject to the same commercialization, privacy, ethical oversight, use restriction, confidentiality, and monitoring requirements described above. Following account approval, applicants are contacted by the PREVENT-AD Research Group. Questions regarding access to the Open and Registered Data may be directed to . The lead contact can help connect you with a member of the StoP-AD Center. • All individual numerical values underlying the summary data presented in the figures, along with the complete code utilized for their generation, have been made openly accessible on GitHub (https://github.com/chloesavignac/PREVENTAD) and deposited on Zenodo (https://doi.org/10.5281/zenodo.20355121) • Any additional information required to reanalyze the data reported in this work paper is available from the lead contact upon request.

Reproduced under the paper's license (CC BY-NC), 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, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 12 authors, 6 keywords, 11 MeSH terms, 20 funders, 89 references.

Cite

This paper

Savignac, C., St-Onge, F., Villeneuve, S., Badhwar, A., Gagliano Taliun, S. A., Farhan, S., Geddes, M., Iturria Medina, Y., Poirier, J., Spreng, R. N., Bzdok, D., & PREVENT-AD Research Group. (2026). Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals. Cell reports. Medicine, 7(8), 102943. https://doi.org/10.1016/j.xcrm.2026.102943

BibTeX

@article{savignac2026parent,
author = {Savignac, Chloé and St-Onge, Frédéric and Villeneuve, Sylvia and Badhwar, AmanPreet and Gagliano Taliun, Sarah A. and Farhan, Sali and Geddes, Maiya and Iturria Medina, Yasser and Poirier, Judes and Spreng, R. Nathan and Bzdok, Danilo and {PREVENT-AD Research Group}},
title = {{Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals}},
journal = {Cell reports. Medicine},
year = {2026},
month = jul,
volume = {7},
number = {8},
pages = {102943},
publisher = {Elsevier},
issn = {2666-3791},
doi = {10.1016/j.xcrm.2026.102943},
url = {https://doi.org/10.1016/j.xcrm.2026.102943},
pmid = {42520805},
pmcid = {PMC13522784}
}

RIS

TY - JOUR
AU - Savignac, Chloé
AU - St-Onge, Frédéric
AU - Villeneuve, Sylvia
AU - Badhwar, AmanPreet
AU - Gagliano Taliun, Sarah A.
AU - Farhan, Sali
AU - Geddes, Maiya
AU - Iturria Medina, Yasser
AU - Poirier, Judes
AU - Spreng, R. Nathan
AU - Bzdok, Danilo
AU - PREVENT-AD Research Group
TI - Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals
T2 - Cell reports. Medicine
J2 - Cell Rep Med
PY - 2026
DA - 2026/07/28
VL - 7
IS - 8
SP - 102943
SN - 2666-3791
PB - Elsevier
DO - 10.1016/j.xcrm.2026.102943
UR - https://doi.org/10.1016/j.xcrm.2026.102943
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.xcrm.2026.102943",
"type": "article-journal",
"title": "Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals",
"container-title": "Cell reports. Medicine",
"author": [
{
"family": "Savignac",
"given": "Chloé"
},
{
"family": "St-Onge",
"given": "Frédéric"
},
{
"family": "Villeneuve",
"given": "Sylvia"
},
{
"family": "Badhwar",
"given": "AmanPreet"
},
{
"family": "Gagliano Taliun",
"given": "Sarah A."
},
{
"family": "Farhan",
"given": "Sali"
},
{
"family": "Geddes",
"given": "Maiya"
},
{
"family": "Iturria Medina",
"given": "Yasser"
},
{
"family": "Poirier",
"given": "Judes"
},
{
"family": "Spreng",
"given": "R. Nathan"
},
{
"family": "Bzdok",
"given": "Danilo"
},
{
"literal": "PREVENT-AD Research Group"
}
],
"container-title-short": "Cell Rep Med",
"volume": "7",
"issue": "8",
"page": "102943",
"DOI": "10.1016/j.xcrm.2026.102943",
"PMID": "42520805",
"PMCID": "PMC13522784",
"ISSN": "2666-3791",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.xcrm.2026.102943",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
28
]
]
}
}

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.1371/journal.pbio.3003856 [code]
Aging and metabolism contribute separately to brain-body health.
Journal: PLoS biology
In common: tedana, Connectome Workbench, AFNI, 18 other tools, clinical / translational, 5 references
[2] doi:10.1038/s41467-026-76452-0 [code]
Music evokes shared neural representations of imagined narratives across sensory modalities.
Journal: Nature communications
In common: tedana, Connectome Workbench, AFNI, 18 other tools, 1 reference
[3] doi:10.1126/sciadv.adu9309 [code]
Variations of global brain asymmetry are associated with aging and related diseases.
Journal: Science advances
In common: tedana, Connectome Workbench, AFNI, 16 other tools, Alzheimer's / dementia, 1 reference
[4] doi:10.1038/s41467-026-73668-y [code]
Convergent and divergent brain-cognition development in early adolescence.
Journal: Nature communications
In common: tedana, Connectome Workbench, AFNI, 18 other tools
[5] doi:10.1038/s41398-026-04025-2 [code]
Brain energetic landscapes shape state dysregulation in major depressive disorder: a morphological network controllability perspective.
Journal: Translational psychiatry
In common: tedana, Connectome Workbench, AFNI, 18 other tools
[6] doi:10.3389/fnagi.2026.1742371 [code]
Cross-sectional and longitudinal functional network alterations associated with subthreshold depressive symptoms in healthy older adults.
Journal: Frontiers in aging neuroscience
In common: tedana, Connectome Workbench, AFNI, 16 other tools, clinical / translational
[7] doi:10.1016/j.neuroimage.2026.122171 [code]
A conserved node degree-based backbone and flexible hub organization of brain connectome during naturalistic movie watching.
Journal: NeuroImage
In common: tedana, Connectome Workbench, AFNI, 16 other tools
[8] doi:10.1016/j.isci.2026.116903 [code]
Neurobiological and behavioral relevance of intrinsic functional connectome constraints on task-evoked neural activation.
Journal: iScience
In common: tedana, Connectome Workbench, AFNI, 16 other tools
[9] doi:10.1002/epi.70323 [code]
Individual-specific resting-state networks predict language dominance in drug-resistant epilepsy.
Journal: Epilepsia
In common: tedana, Connectome Workbench, AFNI, 16 other tools
[10] doi:10.1162/imag.a.1222 [code]
Network-based near-scalp personalized brain stimulation targets.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: tedana, Connectome Workbench, AFNI, 16 other tools

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.