OSCR

A predictive corticospinal model for pain perception.

Code ↔ Paper

9 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 9 matches · 2 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § STAR★Methods › Method details › Model development ↔ 01_model_training.ipynb, lines 66–187 · score 0.86 · Lasso alpha, square error, LASSO PCR, model training, RMSE, R2
  2. [2] § STAR★Methods › Method details › Resting-state fMRI and clinical tracking ↔ utils/AlFF_calc.sh, the whole file · a weak match · score 0.81 · power spectrum, frequency bands, fALFF, 0.13 Hz, amplitude, sum
  3. [3] § STAR★Methods › Method details › Hidden Markov modeling of dynamic states › HMM specification and training ↔ src/hmmlearn/hmm.py, lines 422–531 · score 0.75 · diagonal covariance matrix, GaussianHMM, log likelihood, seed, transition, hmmlearn
  4. [4] § Development of the corticospinal pain intensity pattern › Comparisons between CsPIP and other models ↔ 01_model_training.ipynb, lines 66–187 · score 0.71 · LASSO PCR, Random Forest, external validation, kernel, SVR, regression
  5. [5] § STAR★Methods › Method details › Experimental design ↔ 02_model_specificity.ipynb, lines 68–202 · score 0.68 · low itch, High itch, high pain, low pain, compresses, modality
  6. [6] § STAR★Methods › Method details › Model development ↔ 01_model_training.ipynb, lines 294–412 · score 0.68 · Random Forest, epsilon, RBF, depth, RF, kernel
  7. [7] § Development of the corticospinal pain intensity pattern › External validation ↔ 02_model_specificity.ipynb, lines 68–202 · score 0.65 · low itch, high itch, high pain, low pain, modalities, intensities
  8. [8] § Development of the corticospinal pain intensity pattern › Spectral power of spontaneous activity within CsPIP serves as a state-dependent marker of pain relief ↔ utils/AlFF_calc.sh, the whole file · a weak match · score 0.64 · fALFF, low frequency fluctuations, 0.13 Hz, amplitude, temporally, power
  9. [9] § Development of the corticospinal pain intensity pattern › External validation ↔ 01_model_training.ipynb, lines 425–504 · score 0.63 · pain sensitivity, external validation, high pain, low pain, predict, 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

Jupyter notebook · 707 lines · 28 KB · MIT · 4 matches

  1. # %%
  2. import os
  3. import numpy as np
  4. from scipy.stats import pearsonr
  5. from sklearn.model_selection import GroupKFold, cross_val_predict
  6. from sklearn.decomposition import PCA
  7. from sklearn.linear_model import Lasso
  8. from sklearn.preprocessing import StandardScaler
  9. from sklearn.metrics import mean_squared_error, r2_score
  10. from sklearn.pipeline import Pipeline
  11. # %% [markdown]
  12. # # CsPIP training
  13. # %%
  14. # loading data
  15. datadir = '0data'
  16. train_y = np.load(os.path.join(datadir,'d1_train_y.npy'))
  17. test_y = np.load(os.path.join(datadir,'d1_test_y.npy'))
  18. train_pred = np.load(os.path.join(datadir,'d1_train_pred.npy'))
  19. test_pred = np.load(os.path.join(datadir,'d1_test_pred.npy'))
  20. train_set = np.load(os.path.join(datadir,'d1_train_set.npy'))
  21. test_set = np.load(os.path.join(datadir,'d1_test_set.npy'))
  22. train_groups = np.load(os.path.join(datadir,'d1_train_group.npy'))
  23. qh_lp_copes = np.load(os.path.join(datadir,'d2_qh_lp_set.npy'))
  24. qh_hp_copes = np.load(os.path.join(datadir,'d2_qh_hp_set.npy'))
  25. # qh_lp_pred = np.load(os.path.join(datadir,'d2_qh_lp_pred.npy'))
  26. # qh_hp_pred = np.load(os.path.join(datadir,'d2_qh_hp_pred.npy'))
  27. qh_lp_y = np.load(os.path.join(datadir,'d2_qh_lp_y.npy'))
  28. qh_hp_y = np.load(os.path.join(datadir,'d2_qh_hp_y.npy'))
  29. # %%
  30. lassopcr = Pipeline(steps=[
  31. ('scaler', StandardScaler()),
  32. ('pca', PCA()),
  33. ('lasso', Lasso())])
  34. # Set up the cross_valdation
  35. cv = GroupKFold(n_splits=10)
  36. # 并行得到逐样本的交叉验证预测
  37. y_pred = cross_val_predict(
  38. lassopcr, # 你的 Pipeline
  39. X=train_set,
  40. y=train_y,
  41. groups=train_groups,
  42. cv=cv,
  43. n_jobs=-1, # -1 = 用完所有 CPU 核
  44. method="predict" # 调用 predict
  45. )
  46. # 计算总体指标
  47. r = pearsonr(train_y, y_pred)[0]
  48. rmse = np.sqrt(mean_squared_error(train_y, y_pred))
  49. r2 = r2_score(train_y, y_pred)
  50. print(r, rmse, r2)
  51. lassopcr.fit(train_set, train_y)
  52. print(pearsonr(test_y, lassopcr.predict(test_set)))
  53. print('-'*20)
  54. print(pearsonr(qh_lp_y,lassopcr.predict(qh_lp_copes)))
  55. print(pearsonr(qh_hp_y,lassopcr.predict(qh_hp_copes)))
  56. # %% [markdown]
  57. # # nolinear
  58. # %%
  59. import numpy as np
  60. import os
  61. import pandas as pd
  62. from sklearn.preprocessing import StandardScaler
  63. from sklearn.decomposition import PCA
  64. from sklearn.linear_model import Lasso
  65. from sklearn.ensemble import RandomForestRegressor
  66. from sklearn.svm import SVR
  67. from sklearn.pipeline import Pipeline
  68. from sklearn.model_selection import GridSearchCV, GroupKFold
  69. from sklearn.metrics import mean_squared_error, r2_score
  70. from scipy.stats import pearsonr
  71. # # --- 1. Loading Data (保持你原有的代码) ---
  72. # --- 2. 定义评估函数 (Helper Function) ---
  73. def evaluate_model(model, X, y, dataset_name="Set"):
  74. preds = model.predict(X)
  75. r = pearsonr(y, preds)[0]
  76. # 如果只是为了看结果,可以只打印 r,也可以加上 RMSE
  77. print(f" [{dataset_name}] Pearson r: {r:.3f}")
  78. return r, preds
  79. # --- 3. 设置交叉验证策略 ---
  80. # 这一点非常重要:确保 GridSearch 内部也遵守 Group 约束
  81. cv = GroupKFold(n_splits=10)
  82. # --- 4. 定义模型和参数网格 ---
  83. # 我们把不同的模型放在一个字典里,方便循环处理
  84. model_configs = {
  85. # 'LassoPCR': {
  86. # 'pipeline': Pipeline([
  87. # ('scaler', StandardScaler()),
  88. # ('pca', PCA()),
  89. # ('regressor', Lasso(max_iter=10000)) # 增加 iter 防止收敛警告
  90. # ]),
  91. # 'param_grid': {
  92. # # 优化 PCA 维度 (可选,视特征数量而定)
  93. # 'pca__n_components': [0.8, 0.9, 0.95],
  94. # # 优化 Lasso 的 Alpha (审稿人要求的重点)
  95. # 'regressor__alpha': np.logspace(-4, 1, 20)
  96. # }
  97. # },
  98. 'SVR (RBF)': {
  99. 'pipeline': Pipeline([
  100. ('scaler', StandardScaler()),
  101. ('pca', PCA(n_components=0.95)), # SVR 在高维下较慢,通常建议先降维
  102. ('regressor', SVR(kernel='rbf'))
  103. ]),
  104. 'param_grid': {
  105. 'regressor__C': [0.1, 1, 10, 100],
  106. 'regressor__epsilon': [0.01, 0.1, 0.5]
  107. }
  108. },
  109. 'Random Forest': {
  110. 'pipeline': Pipeline([
  111. ('scaler', StandardScaler()), # RF 不需要归一化,但加上也不影响
  112. # RF 通常不需要 PCA,因为它可以处理高维特征
  113. ('regressor', RandomForestRegressor(random_state=42, n_jobs=-1))
  114. ]),
  115. 'param_grid': {
  116. 'regressor__n_estimators': [100, 200],
  117. 'regressor__max_depth': [None, 10, 20],
  118. 'regressor__min_samples_split': [2, 5]
  119. }
  120. }
  121. }
  122. # --- 5. 主循环:训练与评估 ---
  123. results = {}
  124. print(f"{'='*20} Start Model Training {'='*20}")
  125. preds = {}
  126. for name, config in model_configs.items():
  127. print(f"\n>>> Training Model: {name}...")
  128. # 配置 GridSearchCV
  129. grid = GridSearchCV(
  130. estimator=config['pipeline'],
  131. param_grid=config['param_grid'],
  132. cv=cv,
  133. scoring='neg_mean_squared_error', # 或者 'r2'
  134. n_jobs=-1,
  135. verbose=1
  136. )
  137. # 训练 (注意需要传入 groups 参数)
  138. grid.fit(train_set, train_y, groups=train_groups)
  139. # 获取最佳模型
  140. best_model = grid.best_estimator_
  141. print(f" Best Params: {grid.best_params_}")
  142. # --- 内部交叉验证性能 (Best CV Score) ---
  143. # 这是模型在训练集交叉验证中的平均表现
  144. print(f" Best CV Score (Neg MSE): {grid.best_score_:.3f}")
  145. # --- 外部测试集评估 ---
  146. print(" --- Performance on Hold-out Sets ---")
  147. # 1. Test Set
  148. r_test, preds['Test Set'] = evaluate_model(best_model, test_set, test_y, "Test Set")
  149. # 2. External Validation (QH LP)
  150. r_lp, preds['QH LP'] = evaluate_model(best_model, qh_lp_copes, qh_lp_y, "QH LP")
  151. # 3. External Validation (QH HP)
  152. r_hp, preds['QH HP'] = evaluate_model(best_model, qh_hp_copes, qh_hp_y, "QH HP")
  153. # 存储结果
  154. results[name] = {
  155. 'best_params': grid.best_params_,
  156. 'r_test': r_test,
  157. 'r_qh_lp': r_lp,
  158. 'r_qh_hp': r_hp
  159. }
  160. np.savez(f"sup_data/{name.replace(' ', '_')}_predictions.npz", **preds)
  161. print(f"\n{'='*20} Summary {'='*20}")
  162. for name, res in results.items():
  163. print(f"{name}: Test r={res['r_test']:.3f}, QH_LP r={res['r_qh_lp']:.3f}, QH_HP r={res['r_qh_hp']:.3f}")
  164. # %%
  165. def plot_regression_with_annotations(x, y, title, xlabel, ylabel, color='#7985B3',save_path=None):
  166. """
  167. Plots a regression plot with custom annotations.
  168. Parameters:
  169. - x: array-like, the observed values
  170. - y: array-like, the predicted values
  171. - title: str, the title of the plot
  172. - xlabel: str, the label for the x-axis
  173. - ylabel: str, the label for the y-axis
  174. - color: str, the color for the points and regression line
  175. """
  176. import matplotlib.pyplot as plt
  177. import seaborn as sns
  178. from sklearn.metrics import mean_absolute_error
  179. from scipy.stats import pearsonr
  180. from matplotlib.ticker import MaxNLocator
  181. plt.figure(figsize=(7, 6))
  182. ax = sns.regplot(x=x, y=y, scatter_kws={'alpha':0.4,'color':color}, line_kws={'color':color})
  183. # Customizing the plot with titles and labels
  184. ax.set_title(title,fontsize=20,fontweight='bold')
  185. ax.set_xlabel(xlabel,fontsize=16,fontweight='bold')
  186. ax.set_ylabel(ylabel,fontsize=16,fontweight='bold')
  187. # Removing top and right spines
  188. ax.spines['top'].set_visible(False)
  189. ax.spines['right'].set_visible(False)
  190. # Calculate correlation coefficient and p-value
  191. r, p = pearsonr(x, y)
  192. # Annotate the plot with the correlation coefficient and p-value
  193. ax.text(0.05, 0.95, f'r = {r:.2f}', transform=ax.transAxes, fontsize=16, fontweight='bold')
  194. ax.text(0.05, 0.90, f'p = {p:.3f}', transform=ax.transAxes, fontsize=16, fontweight='bold')
  195. # Calculate and display mean absolute error
  196. mae = mean_absolute_error(x, y)
  197. m, b = np.polyfit(x, y, 1)
  198. # Customize the number of ticks on x and y axes
  199. ax.xaxis.set_major_locator(MaxNLocator(3))
  200. ax.yaxis.set_major_locator(MaxNLocator(3))
  201. if save_path:
  202. plt.savefig(save_path, dpi=300, bbox_inches='tight')
  203. # Show the plot
  204. plt.show()
  205. # %%
  206. svr_pred = np.load('sup_data/SVR_(RBF)_predictions.npz', allow_pickle=True)
  207. rf_pred = np.load('sup_data/Random_Forest_predictions.npz', allow_pickle=True)
  208. # %%
  209. plot_regression_with_annotations(svr_pred['Test Set'],test_y,
  210. title='SVR Model Predictions (Hold-out Set)',
  211. ylabel='Actual Values',
  212. xlabel='Predicted Values',
  213. color='#7985B3',
  214. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/SVR_Holdout_Predictions.tif'
  215. )
  216. plot_regression_with_annotations(y = qh_lp_y,x = svr_pred['QH LP'],
  217. title='SVR Model Predictions (Study 2 Low Pain)',
  218. ylabel='Actual Values',
  219. xlabel='Predicted Values',
  220. color='#7985B3',
  221. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/SVR_QH_LP_Predictions.tif'
  222. )
  223. plot_regression_with_annotations(y = qh_hp_y,x = svr_pred['QH HP'],
  224. title='SVR Model Predictions (Study 2 High Pain)',
  225. ylabel='Actual Values',
  226. xlabel='Predicted Values',
  227. color='#7985B3',
  228. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/SVR_QH_HP_Predictions.tif'
  229. )
  230. # %%
  231. plot_regression_with_annotations(y = test_y,x = rf_pred['Test Set'],
  232. title='Random Forest Model Predictions (Hold-out Set)',
  233. ylabel='Actual Values',
  234. xlabel='Predicted Values',
  235. color='#FF6F61',
  236. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/RF_Holdout_Predictions.tif'
  237. )
  238. plot_regression_with_annotations(y = qh_lp_y,x = rf_pred['QH LP'],
  239. title='Random Forest Model Predictions (Study 2 Low Pain)',
  240. ylabel='Actual Values',
  241. xlabel='Predicted Values',
  242. color='#FF6F61',
  243. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/RF_QH_LP_Predictions.tif'
  244. )
  245. plot_regression_with_annotations(y = qh_hp_y,x = rf_pred['QH HP'],
  246. title='Random Forest Model Predictions (Study 2 High Pain)',
  247. ylabel='Actual Values',
  248. xlabel='Predicted Values',
  249. color='#FF6F61',
  250. save_path='/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/RF_QH_HP_Predictions.tif'
  251. )
  252. # %%
  253. # %%
  254. import numpy as np
  255. import os
  256. import pandas as pd
  257. from sklearn.preprocessing import StandardScaler
  258. from sklearn.decomposition import PCA
  259. from sklearn.linear_model import Lasso
  260. from sklearn.ensemble import RandomForestRegressor
  261. from sklearn.svm import SVR
  262. from sklearn.pipeline import Pipeline
  263. from sklearn.model_selection import GridSearchCV, GroupKFold
  264. from sklearn.metrics import mean_squared_error, r2_score
  265. from scipy.stats import pearsonr
  266. # # --- 1. Loading Data (保持你原有的代码) ---
  267. # --- 2. 定义评估函数 (Helper Function) ---
  268. def evaluate_model(model, X, y, dataset_name="Set"):
  269. preds = model.predict(X)
  270. r = pearsonr(y, preds)[0]
  271. # 如果只是为了看结果,可以只打印 r,也可以加上 RMSE
  272. print(f" [{dataset_name}] Pearson r: {r:.3f}")
  273. return r, preds
  274. # --- 3. 设置交叉验证策略 ---
  275. # 这一点非常重要:确保 GridSearch 内部也遵守 Group 约束
  276. cv = GroupKFold(n_splits=10)
  277. # --- 4. 定义模型和参数网格 ---
  278. # 我们把不同的模型放在一个字典里,方便循环处理
  279. model_configs = {
  280. 'LassoPCR': {
  281. 'pipeline': Pipeline([
  282. ('scaler', StandardScaler()),
  283. ('pca', PCA()),
  284. ('regressor', Lasso(max_iter=10000)) # 增加 iter 防止收敛警告
  285. ]),
  286. 'param_grid': {
  287. # 优化 PCA 维度 (可选,视特征数量而定)
  288. 'pca__n_components': [0.8, 0.9, 0.95],
  289. # 优化 Lasso 的 Alpha (审稿人要求的重点)
  290. 'regressor__alpha': np.logspace(-4, 1, 20)
  291. }
  292. },
  293. # 'SVR (RBF)': {
  294. # 'pipeline': Pipeline([
  295. # ('scaler', StandardScaler()),
  296. # ('pca', PCA(n_components=0.95)), # SVR 在高维下较慢,通常建议先降维
  297. # ('regressor', SVR(kernel='rbf'))
  298. # ]),
  299. # 'param_grid': {
  300. # 'regressor__C': [0.1, 1, 10, 100],
  301. # 'regressor__epsilon': [0.01, 0.1, 0.5]
  302. # }
  303. # },
  304. # 'Random Forest': {
  305. # 'pipeline': Pipeline([
  306. # ('scaler', StandardScaler()), # RF 不需要归一化,但加上也不影响
  307. # # RF 通常不需要 PCA,因为它可以处理高维特征
  308. # ('regressor', RandomForestRegressor(random_state=42, n_jobs=-1))
  309. # ]),
  310. # 'param_grid': {
  311. # 'regressor__n_estimators': [100, 200],
  312. # 'regressor__max_depth': [None, 10, 20],
  313. # 'regressor__min_samples_split': [2, 5]
  314. # }
  315. # }
  316. }
  317. # --- 5. 主循环:训练与评估 ---
  318. results = {}
  319. print(f"{'='*20} Start Model Training {'='*20}")
  320. for name, config in model_configs.items():
  321. print(f"\n>>> Training Model: {name}...")
  322. # 配置 GridSearchCV
  323. grid = GridSearchCV(
  324. estimator=config['pipeline'],
  325. param_grid=config['param_grid'],
  326. cv=cv,
  327. scoring='neg_mean_squared_error', # 或者 'r2'
  328. n_jobs=-1,
  329. verbose=1
  330. )
  331. # 训练 (注意需要传入 groups 参数)
  332. grid.fit(train_set, train_y, groups=train_groups)
  333. # 获取最佳模型
  334. best_model = grid.best_estimator_
  335. print(f" Best Params: {grid.best_params_}")
  336. # --- 内部交叉验证性能 (Best CV Score) ---
  337. # 这是模型在训练集交叉验证中的平均表现
  338. print(f" Best CV Score (Neg MSE): {grid.best_score_:.3f}")
  339. # --- 外部测试集评估 ---
  340. print(" --- Performance on Hold-out Sets ---")
  341. # 1. Test Set
  342. r_test, preds_test = evaluate_model(best_model, test_set, test_y, "Test Set")
  343. # 2. External Validation (QH LP)
  344. r_lp, preds_lp = evaluate_model(best_model, qh_lp_copes, qh_lp_y, "QH LP")
  345. # 3. External Validation (QH HP)
  346. r_hp, preds_hp = evaluate_model(best_model, qh_hp_copes, qh_hp_y, "QH HP")
  347. # 存储结果
  348. results[name] = {
  349. 'best_params': grid.best_params_,
  350. 'r_test': r_test,
  351. 'r_qh_lp': r_lp,
  352. 'r_qh_hp': r_hp
  353. }
  354. print(f"\n{'='*20} Summary {'='*20}")
  355. for name, res in results.items():
  356. print(f"{name}: Test r={res['r_test']:.3f}, QH_LP r={res['r_qh_lp']:.3f}, QH_HP r={res['r_qh_hp']:.3f}")
  357. # %%
  358. # 1. Test Set
  359. r_test, preds_test = evaluate_model(best_model, test_set, test_y, "Test Set")
  360. # 2. External Validation (QH LP)
  361. r_lp, preds_lp = evaluate_model(best_model, qh_lp_copes, qh_lp_y, "QH LP")
  362. # 3. External Validation (QH HP)
  363. r_hp, preds_hp = evaluate_model(best_model, qh_hp_copes, qh_hp_y, "QH HP")
  364. # %%
  365. # 1. Test Set
  366. r_test, preds_test = evaluate_model(best_model, test_set, test_y, "Test Set")
  367. # 2. External Validation (QH LP)
  368. r_lp, preds_lp = evaluate_model(best_model, qh_lp_copes, qh_lp_y, "QH LP")
  369. # 3. External Validation (QH HP)
  370. r_hp, preds_hp = evaluate_model(best_model, qh_hp_copes, qh_hp_y, "QH HP")
  371. import matplotlib.pyplot as plt
  372. import seaborn as sns
  373. from matplotlib.ticker import MaxNLocator
  374. from scipy.stats import pearsonr
  375. from matplotlib.colors import LinearSegmentedColormap
  376. def plot_d2d3(t1,t2,x1,y1,x2,y2,save=False):
  377. # 读取txt文件,通常是3列数据 (R, G, B)
  378. roma_data = np.loadtxt('/mnt/lxm/tools/romaO/romaO.txt')
  379. # 创建 Matplotlib 可用的 colormap 对象
  380. roma_cmap = LinearSegmentedColormap.from_list('romaO', roma_data)
  381. # 设置字体族为衬线体 (serif)
  382. plt.rcParams['font.family'] = 'serif'
  383. # 指定衬线体具体为 Times New Roman
  384. plt.rcParams['font.serif'] = ['Times New Roman']
  385. # 确保数学公式也尽量接近 Times 风格 (可选)
  386. plt.rcParams['mathtext.fontset'] = 'stix'
  387. # 设置字号 (可选,根据需要调整)
  388. plt.rcParams['font.size'] = 12
  389. # 设置 Seaborn 风格,但保留我们的字体设置
  390. sns.set_theme(style="ticks", rc={"font.family": "serif", "font.serif": ["Times New Roman"]})
  391. # 设置字体族为 Times New Roman
  392. plt.rcParams['font.family'] = 'serif'
  393. plt.rcParams['font.serif'] = ['Times New Roman']
  394. sns.set_context("notebook", rc={"font.family": "Times New Roman"})
  395. # 设置 Seaborn 风格,但保留我们的字体设置
  396. sns.set_theme(style="ticks", rc={"font.family": "serif", "font.serif": ["Times New Roman"]})
  397. color1=roma_cmap(0.15)
  398. color2=roma_cmap(0.95)
  399. # color3=roma_cmap(0.5)
  400. color3='black'
  401. # 创建图表
  402. plt.figure(figsize=(7, 6))
  403. ax = plt.gca() # 获取当前坐标轴
  404. # 为每个数据集绘制回归散点图
  405. sns.regplot(x=t1, y=t2, scatter_kws={'alpha':0.6, 'color':color3}, line_kws={'color':color3}, ax=ax, label='Hold-out Set')
  406. # sns.regplot(x=x1, y=y1, scatter_kws={'alpha':0.6, 'color':color1}, line_kws={'color':color1}, ax=ax, label='Low Pain')
  407. # sns.regplot(x=x2, y=y2, scatter_kws={'alpha':0.6, 'color':color2}, line_kws={'color':color2}, ax=ax, label='High Pain')
  408. # 自定义图表标题和轴标签
  409. ax.set_xlabel('Observed pain sensitivity',fontsize=16, fontweight='bold')
  410. ax.set_ylabel('Predicted pain sensitivity',fontsize=16, fontweight='bold')
  411. ax.spines['top'].set_visible(False)
  412. ax.spines['right'].set_visible(False)
  413. # 计算每个数据集的相关系数
  414. r1,p1=pearsonr(x1,y1)
  415. r2,p2=pearsonr(x2,y2)
  416. rt,p_t=pearsonr(t1,t2)
  417. # 添加相关系数的注释
  418. ax.text(0.05, 0.95, f'Hold-out Set: r = {rt:.2f}, p = {p_t:.3f}', transform=ax.transAxes, color=color3)
  419. # ax.text(0.05, 0.90, f'Study 2 - low pain: r = {r1:.2f}, p = {p1:.3f}', transform=ax.transAxes, color=color1)
  420. # ax.text(0.05, 0.85, f'Study 2 - high pain: r = {r2:.2f}, p = {p2:.3f}', transform=ax.transAxes, color=color2)
  421. ax.xaxis.set_major_locator(MaxNLocator(3)) # 在x轴上最多显示5个刻度
  422. ax.yaxis.set_major_locator(MaxNLocator(3)) # 在y轴上最多显示4个刻度
  423. # plt.ylim(0,13)
  424. # 显示图例
  425. plt.legend(loc='lower right',frameon=True, fontsize=13) # 或 ax.legend(loc='lower right')
  426. # 显示图表
  427. # if save:
  428. # # save
  429. # fileDir = '/mnt/lxm2/2025/03_Tens/manuscript_FINAL/figs/'
  430. # fileName = 'd2_corr.tif'
  431. # plt.gcf().savefig(fileDir+fileName, dpi=300, bbox_inches='tight', pad_inches=0.04,
  432. # pil_kwargs={'compression':'tiff_lzw'})
  433. plt.show()
  434. plot_d2d3(preds_test,test_y,preds_lp,qh_lp_y,preds_hp,qh_hp_y,save=True)
  435. # %% [markdown]
  436. # # bootstrap
  437. # %%
  438. nbootstraps = 10000
  439. nstop = 200 # frequency to stop/save bootstraps
  440. njobs = -1
  441. brain_v = len_brain
  442. spial_v = len_spinal
  443. from joblib import Parallel, delayed
  444. from scipy.stats import norm
  445. from tqdm import tqdm
  446. from os.path import join as opj
  447. outpath = '/mnt/lxm2/2025/03_Tens/lassopcr_res_0503_2a/boots_new'
  448. name = 'lassopcr'
  449. os.makedirs(opj(outpath, 'permsamples'), exist_ok=True)
  450. os.makedirs(opj(outpath, 'bootsamples'), exist_ok=True)
  451. def bootstrap_weights(X, Y,rs):
  452. # Randomly select observations
  453. rng = np.random.RandomState(rs)
  454. boot_ids = rng.choice(np.arange(len(X)),
  455. size=len(X),
  456. replace=True)
  457. try:
  458. # Fit the classifier on this sample and get the weights
  459. lassopcr.fit(X[boot_ids], Y[boot_ids])
  460. # Return the weights and stats
  461. return np.dot(lassopcr['pca'].components_.T, lassopcr['lasso'].coef_)
  462. except:
  463. print("SVD failed on a bootstrap sample. Skipping...")
  464. return rs # 返回 None 而不是零向量
  465. # Run in parrallel and stop/save regurarly to run in multiple
  466. for i in tqdm(range(nbootstraps//nstop)):
  467. # Check if file alrady exist in case bootstrap done x times
  468. outbootfile = ['bootsamples_' + str(nstop) + 'samples_'
  469. + str(i+1) + '_of_'
  470. + str(nbootstraps//nstop) + '.npy']
  471. print("Running permloop " + str(i + 1) + ' out of ' + str(nbootstraps//nstop))
  472. if not os.path.exists(opj(outpath, 'bootsamples', outbootfile[0])):
  473. bootstrapped = Parallel(n_jobs=40,
  474. verbose=0)(delayed(bootstrap_weights)(X=train_set, Y=train_y,rs=i*200+ii)
  475. for ii in range(nstop))
  476. try:
  477. bootstrapped = np.stack(bootstrapped)
  478. except:
  479. for ind, vv in enumerate(bootstrapped):
  480. if isinstance(vv, int): # Check if vv is of type int
  481. # Replace vv with the result of bootstrap_weights
  482. bootstrapped[ind] = bootstrap_weights(all_copes, all_y, vv)
  483. bootstrapped = np.stack(bootstrapped)
  484. np.save(opj(outpath, 'bootsamples', outbootfile[0]), bootstrapped)
  485. # %%
  486. mask_img = nb.load('/mnt/lxm2/2025/03_Tens/3group_level/all_lr+.gfeat/all_lr_mask_thr31_bin.nii.gz')
  487. spinal_mask = nb.load('/mnt/lxm2/2025/03_Tens/LASSOPCR/group_mask_gm.nii.gz')
  488. # Load all boostraps
  489. bootstrapped = np.vstack(np.stack([np.load(opj(outpath, 'bootsamples', f))
  490. for f in os.listdir(opj(outpath, 'bootsamples'))
  491. if 'bootsamples' in f], axis=0))
  492. assert bootstrapped.shape[0] == nbootstraps
  493. # Get bootstraped statistics and threshold (as in nltools)
  494. # Zscore
  495. boot_z = bootstrapped.mean(axis=0)/bootstrapped.std(axis=0)
  496. # boot_z[bootstrapped.mean(axis=0) == 0] = 0
  497. unmask(boot_z[:brain_v], mask_img).to_filename(opj(outpath, 'brain_'+name + '_bootz.nii'))
  498. unmask(boot_z[brain_v:], spinal_mask).to_filename(opj(outpath, 'spinal_'+name + '_bootz.nii'))
  499. # P vals
  500. boot_pval = 2 * (1 - norm.cdf(np.abs(boot_z)))
  501. unmask(boot_pval[:brain_v], mask_img).to_filename(opj(outpath, 'brain_'+name + '_boot_pvals.nii'))
  502. unmask(boot_pval[brain_v:], spinal_mask).to_filename(opj(outpath, 'spinal_'+name + '_boot_pvals.nii'))
  503. def fdr(p, q=0.05):
  504. s = np.sort(p)
  505. nvox = p.shape[0]
  506. null = np.array(range(1, nvox + 1), dtype="float") * q / nvox
  507. below = np.where(s <= null)[0]
  508. return s[max(below)] if len(below) else -1 # p_fdr
  509. # FDR orrected z
  510. boot_z_fdr = np.where(boot_pval < fdr(boot_pval, q=0.05), boot_z, 0)
  511. boot_z_unc001 = np.where(boot_pval < 0.001, boot_z, 0)
  512. boot_z_unc005 = np.where(boot_pval < 0.005, boot_z, 0)
  513. boot_z_unc01 = np.where(boot_pval < 0.01, boot_z, 0)
  514. unmask(boot_z_fdr[:brain_v], mask_img).to_filename(opj(outpath,
  515. 'brain'+ name + '_bootz_fdr05.nii'))
  516. unmask(boot_z_unc001[:brain_v], mask_img).to_filename(opj(outpath,
  517. 'brain'+ name + '_bootz_unc001.nii'))
  518. unmask(boot_z_unc005[:brain_v], mask_img).to_filename(opj(outpath,
  519. 'brain'+ name + '_bootz_unc005.nii'))
  520. unmask(boot_z_unc01[:brain_v], mask_img).to_filename(opj(outpath,
  521. 'brain'+ name + '_bootz_unc01.nii'))
  522. unmask(boot_z_fdr[brain_v:], spinal_mask).to_filename(opj(outpath,
  523. 'spianl'+ name + '_bootz_fdr05.nii'))
  524. unmask(boot_z_unc001[brain_v:], spinal_mask).to_filename(opj(outpath,
  525. 'spianl'+ name + '_bootz_unc001.nii'))
  526. unmask(boot_z_unc005[brain_v:], spinal_mask).to_filename(opj(outpath,
  527. 'spianl'+ name + '_bootz_unc005.nii'))
  528. unmask(boot_z_unc01[brain_v:], spinal_mask).to_filename(opj(outpath,
  529. 'spianl'+ name + '_bootz_unc01.nii'))
  530. # %%
  531. boot_z_fdr_brain = np.where(boot_pval[:brain_v] < fdr(boot_pval[:brain_v], q=0.05), boot_z[:brain_v], 0)
  532. unmask(boot_z_fdr_brain, mask_img).to_filename(opj(outpath, 'only_brain_'+name + '_bootz_fdr05.nii'))
  533. boot_z_fdr_spinal = np.where(boot_pval[brain_v:] < fdr(boot_pval[brain_v:], q=0.05), boot_z[brain_v:], 0)
  534. unmask(boot_z_fdr_spinal, spinal_mask).to_filename(opj(outpath, 'only_spinal_'+name + '_bootz_fdr05.nii'))
  535. # %% [markdown]
  536. # # Orignial Pipeline
  537. # %%
  538. # all_sub = open('/home/lxm/2_lxm/2025/03_Tens/scripts/all.list').read().splitlines()
  539. # r_list = [x for x in all_sub if '_r' in x]
  540. # l_list = [x for x in all_sub if '_l' in x]
  541. # y_all_r = np.array([np.loadtxt(f'/mnt/lxm2/2025/03_Tens/0data/time_pr/{sub}_pre_pr.txt').mean() for sub in r_list])
  542. # y_all_l = np.array([np.loadtxt(f'/mnt/lxm2/2025/03_Tens/0data/time_pr/{sub}_pre_pr.txt').mean() for sub in l_list])
  543. # import numpy as np
  544. # import nibabel as nb
  545. # from nilearn.image import binarize_img,threshold_img
  546. # from joblib import Parallel, delayed
  547. # brain_mask_img = nb.load('/mnt/lxm2/2025/03_Tens/3group_level/all_lr+.gfeat/all_lr_mask_thr31_bin.nii.gz')
  548. # spinal_mask_img = nb.load('/home/lxm/2_lxm/2025/03_Tens/LASSOPCR/group_mask_gm.nii.gz')
  549. # brain_mask = brain_mask_img.get_fdata().astype(bool).ravel() # (n_vox_brain,)
  550. # spinal_mask = spinal_mask_img.get_fdata().astype(bool).ravel() # (n_vox_spinal,)
  551. # # 把两张掩膜长度记录下来,后面拼接用
  552. # len_brain, len_spinal = brain_mask.sum(), spinal_mask.sum()
  553. # def load_subject(sub_id, prefix):
  554. # """
  555. # 读一个受试者的脑 + 脊髓 COPE,返回 (len_brain + len_spinal,) 的 1-D 特征向量
  556. # """
  557. # # 路径
  558. # brain_p = f'{prefix}/brain/{sub_id}.feat/reg_standard/stats/cope1.nii.gz'
  559. # spinal_p = f'{prefix}/spinal/{sub_id}.feat/stats/cope1_template.nii.gz'
  560. # brain_data = nb.load(brain_p).get_fdata().ravel()[brain_mask] # (len_brain,)
  561. # spinal_data = nb.load(spinal_p).get_fdata().ravel()[spinal_mask] # (len_spinal,)
  562. # return np.concatenate((brain_data, spinal_data), axis=0)
  563. # # ── 2. 并行读取 ─────────────────────────────────────────────
  564. # prefix = '/mnt/lxm2/2025/03_Tens/2fst_level'
  565. # # 左右两组
  566. # all_data = Parallel(n_jobs=-1, backend='loky', verbose=5)(
  567. # delayed(load_subject)(sub, prefix) for sub in l_list
  568. # )
  569. # test_data = Parallel(n_jobs=-1, backend='loky', verbose=5)(
  570. # delayed(load_subject)(sub, prefix) for sub in r_list
  571. # )
  572. # all_data = np.vstack(all_data) # shape = (n_L, len_brain + len_spinal)
  573. # test_data = np.vstack(test_data) # shape = (n_R, len_brain + len_spinal)
  574. # # ── 3. 组装后续矩阵 / 标签 / 分组 ───────────────────────────
  575. # # all_copes = np.vstack((all_data, test_data))
  576. # all_copes = np.vstack((all_data, test_data))
  577. # all_y = np.hstack((y_all_l, y_all_r))
  578. # groups = np.tile(np.arange(len(y_all_l)), 2)
  579. # from sklearn.model_selection import GroupShuffleSplit
  580. # group_split = GroupShuffleSplit(n_splits=2, test_size=0.33, random_state=42)
  581. # # 拆分数据集,确保同一组数据不会同时出现在训练集和测试集中
  582. # for train_index, test_index in group_split.split(all_copes, groups=groups):
  583. # train_set = all_copes[train_index]
  584. # train_y = all_y[train_index]
  585. # test_set = all_copes[test_index]
  586. # test_y = all_y[test_index]
  587. # train_groups = groups[train_index]
  588. # test_groups = groups[test_index]
  589. # train_id = [r_list[x] for x in train_groups]
  590. # test_id = [r_list[x] for x in test_groups]
  591. # outdir = '/home/lxm/2_lxm/2025/03_Tens/manuscript_FINAL/0data'
  592. # if not os.path.exists(outdir):
  593. # os.makedirs(outdir)
  594. # np.save(os.path.join(outdir,'d1_train_set.npy'),train_set)
  595. # np.save(os.path.join(outdir,'d1_test_set.npy'),test_set)
  596. # np.save(os.path.join(outdir,'d1_train_y.npy'),train_y)
  597. # np.save(os.path.join(outdir,'d1_train_pred.npy'),y_pred)
  598. # np.save(os.path.join(outdir,'d1_test_y.npy'),test_y)
  599. # np.save(os.path.join(outdir,'d1_test_pred.npy'),lassopcr.predict(test_set))
  600. # np.save(os.path.join(outdir,'d2_qh_lp_pred.npy'),lassopcr.predict(qh_lp_copes))
  601. # np.save(os.path.join(outdir,'d2_qh_hp_pred.npy'),lassopcr.predict(qh_hp_copes))
  602. # np.save(os.path.join(outdir,'d2_qh_hp_y.npy'),real_hp)
  603. # np.save(os.path.join(outdir,'d2_qh_lp_y.npy'),real_lp)
  604. # np.save(os.path.join(outdir,'d1_train_group.npy'),train_groups)
  605. # np.save(os.path.join(outdir,'d1_test_group.npy'),test_groups)
  606. # np.save(os.path.join(outdir,'d2_qh_lp_pred.npy'), qh_lp_copes)
  607. # np.save(os.path.join(outdir,'d2_qh_hp_pred.npy'), qh_hp_copes)

01_model_training.ipynb at commit 660ab60, under MIT · at the source

Overview

Authors: Xiao-Min Lin1,2, Xiao-Shuo Zhang1,2, Hang Zhou3, Xiu-Yi Han1,2, Zhao-Xing Wei1,2,4, Tor D Wager4, Irene Tracey5, Ji-Xin Liu6, Cun-Zhi Liu3, Ya-Zhuo Kong1,2,5
  1. State Key Laboratory of Cognitive Science and Mental Health, Institute of Psychology, Chinese Academy of Sciences, Beijing 100101, China
  2. Department of Psychology, University of Chinese Academy of Sciences, Beijing 100049, China
  3. International Acupuncture and Moxibustion Innovation Institute, School of Acupuncture-Moxibustion and Tuina, Beijing University of Chinese Medicine, Beijing 100029, China
  4. Department of Psychological and Brain Sciences, Dartmouth College, Hanover, NH 03755, USA
  5. Wellcome Centre for Integrative Neuroimaging, FMRIB, Nuffield Department of Clinical Neurosciences, University of Oxford, Oxford OX3 9DU, UK
  6. Center for Brain Imaging, School of Life Science and Technology, Xidian University, Xi’an 710126, China
Journal: Cell reports. Medicine, volume 7, issue 7, article 102793
Dates: received 8 September 2025; accepted 10 April 2026; published online 18 June 2026; in print July 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1016/j.xcrm.2026.102793 · PMID 42309066 · PMCID PMC13400141 · OpenAlex W7165040625
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), human (organism), pain (population)
Methods: Connectivity, Statistics, Smoothing, state filtering, decompositions, Machine learning, Preprocessing, Spectral & time-frequency, fMRI & imaging
Keywords: corticospinal fMRI, pain biomarker, neuromodulation, chronic pain, acupuncture
MeSH: Chronic Pain*, Pain Perception*, Pyramidal Tracts*, Adult, Female, Humans, Magnetic Resonance Imaging, Male, Transcutaneous Electric Nerve Stimulation (* major topic)
Topic: Pain Mechanisms and Treatments (Physiology, Medicine), according to OpenAlex
Funding: Shaanxi Province Health Commission (2025TD-03); Beijing Natural Science Foundation (IS23108); National Natural Science Foundation of China (82572197, 82441056); National Key Research and Development Program of China Stem Cell and Translational Research (2022YFC3500603); National Key Research and Development Program of China
Citations: cited by 1 paper (Europe PMC); 51 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repositories

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

buer19970329/corticospinal-pain-intensity-pattern

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 660ab60aa75bfc2c7f21a7bbc1aaa2f7e9a784b6, 29 May 2026
Languages: Jupyter (3), Shell (1)
Size: 39 files, 4 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, 3 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (3 files), NumPy (3 files), pandas (3 files), SciPy (3 files), seaborn (3 files), NiBabel (2 files), Nilearn (2 files), scikit-learn (2 files), FSL (1 file), Pingouin (1 file), statsmodels (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
5 files

hmmlearn/hmmlearn

License: BSD-3-Clause
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: e01a10e99df1042e4c1e6b7c822fd292dd37502f, 31 October 2024
Languages: Python (32), C++ (1)
Size: 53 files, 33 scripts
Software Heritage: archived
Found in: the resources table
Holds: README, license file, environment (pyproject.toml, setup.py), tests, continuous integration, documentation
Not found: CITATION.cff
Tools: NumPy (29 files), scikit-learn (14 files), SciPy (11 files), Matplotlib (5 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
35 files

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

Tracing map

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

What the map holds:

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

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

Data

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

Code and data availability statement

The paper has a code and data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1016/j.xcrm.2026.102793.

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, 10 authors, 5 keywords, 9 MeSH terms, 5 funders, 50 references.

Cite

This paper

Lin, X.-M., Zhang, X.-S., Zhou, H., Han, X.-Y., Wei, Z.-X., Wager, T. D., Tracey, I., Liu, J.-X., Liu, C.-Z., & Kong, Y.-Z. (2026). A predictive corticospinal model for pain perception. Cell reports. Medicine, 7(7), 102793. https://doi.org/10.1016/j.xcrm.2026.102793

BibTeX

@article{lin2026predictive,
author = {Lin, Xiao-Min and Zhang, Xiao-Shuo and Zhou, Hang and Han, Xiu-Yi and Wei, Zhao-Xing and Wager, Tor D and Tracey, Irene and Liu, Ji-Xin and Liu, Cun-Zhi and Kong, Ya-Zhuo},
title = {{A predictive corticospinal model for pain perception}},
journal = {Cell reports. Medicine},
year = {2026},
month = jun,
volume = {7},
number = {7},
pages = {102793},
publisher = {Elsevier},
issn = {2666-3791},
doi = {10.1016/j.xcrm.2026.102793},
url = {https://doi.org/10.1016/j.xcrm.2026.102793},
pmid = {42309066},
pmcid = {PMC13400141}
}

RIS

TY - JOUR
AU - Lin, Xiao-Min
AU - Zhang, Xiao-Shuo
AU - Zhou, Hang
AU - Han, Xiu-Yi
AU - Wei, Zhao-Xing
AU - Wager, Tor D
AU - Tracey, Irene
AU - Liu, Ji-Xin
AU - Liu, Cun-Zhi
AU - Kong, Ya-Zhuo
TI - A predictive corticospinal model for pain perception
T2 - Cell reports. Medicine
J2 - Cell Rep Med
PY - 2026
DA - 2026/06/18
VL - 7
IS - 7
SP - 102793
SN - 2666-3791
PB - Elsevier
DO - 10.1016/j.xcrm.2026.102793
UR - https://doi.org/10.1016/j.xcrm.2026.102793
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.xcrm.2026.102793",
"type": "article-journal",
"title": "A predictive corticospinal model for pain perception",
"container-title": "Cell reports. Medicine",
"author": [
{
"family": "Lin",
"given": "Xiao-Min"
},
{
"family": "Zhang",
"given": "Xiao-Shuo"
},
{
"family": "Zhou",
"given": "Hang"
},
{
"family": "Han",
"given": "Xiu-Yi"
},
{
"family": "Wei",
"given": "Zhao-Xing"
},
{
"family": "Wager",
"given": "Tor D"
},
{
"family": "Tracey",
"given": "Irene"
},
{
"family": "Liu",
"given": "Ji-Xin"
},
{
"family": "Liu",
"given": "Cun-Zhi"
},
{
"family": "Kong",
"given": "Ya-Zhuo"
}
],
"container-title-short": "Cell Rep Med",
"volume": "7",
"issue": "7",
"page": "102793",
"DOI": "10.1016/j.xcrm.2026.102793",
"PMID": "42309066",
"PMCID": "PMC13400141",
"ISSN": "2666-3791",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.xcrm.2026.102793",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
18
]
]
}
}

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-74743-0 [code]
Meta-analytic evidence for distinct neural correlates of conditioned versus verbally induced placebo analgesia.
Journal: Nature communications
In common: Pingouin, FSL, Nilearn, 8 other tools, pain, 2 references
[2] doi:10.1038/s41467-026-71568-9 [code]
Convergent and selective representations of pain, appetitive processes, aversive processes, and cognitive control in the insula.
Journal: Nature communications
In common: FSL, Nilearn, NiBabel, 6 other tools, pain, 4 references
[3] doi:10.1038/s41467-026-71963-2 [code]
Spinal cord structural and functional architecture and its shared organization with the brain across the adult lifespan.
Journal: Nature communications
In common: Pingouin, FSL, Nilearn, 8 other tools, 2 references
[4] doi:10.1038/s41597-026-07377-y [code]
An open-access multi-site fMRI dataset for investigating conscious visual perception.
Journal: Scientific data
In common: Pingouin, FSL, Nilearn, 8 other tools, fMRI
[5] doi:10.1038/s41467-026-75662-w [code]
Distinct Roles of Deep and Superficial Cortical Layers in Tone Prediction, Comparison, and Adaptation in Human Auditory Cortices.
Journal: Nature communications
In common: Pingouin, FSL, Nilearn, 8 other tools
[6] doi:10.1038/s41597-026-07350-9 [code]
An open multi-center MEG-EEG dataset for studying conscious visual perception.
Journal: Scientific data
In common: Pingouin, FSL, Nilearn, 8 other tools
[7] doi:10.1093/nc/niag029 [code]
A data-driven approach to identifying and evaluating connectivity-based neural correlates of conscious visual perception.
Journal: Neuroscience of consciousness
In common: Pingouin, FSL, Nilearn, 8 other tools
[8] doi:10.1038/s41467-026-75661-x [code]
A neural signature of sleep deprivation in the human brain.
Journal: Nature communications
In common: Nilearn, NiBabel, statsmodels, 6 other tools, 2 references
[9] doi:10.1371/journal.pbio.3003856 [code]
Aging and metabolism contribute separately to brain-body health.
Journal: PLoS biology
In common: FSL, Nilearn, NiBabel, 7 other tools, 1 reference
[10] doi:10.1162/imag.a.1245 [code]
Towards precision EEG connectomics: Evaluating the benefits of dense sampling.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Pingouin, FSL, Nilearn, 7 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.