OSCR

Replay of procedural memory is independent of the hippocampus.

Code ↔ Paper

19 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 19 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 › LFP analysis ↔ preprocessing/LFP_spindle_processing.ipynb, lines 1–125 · score 0.92 · spindle events, Gaussian window, upper threshold, lower threshold, LFP, Hilbert
  2. [2] § Methods › Video-tracking analysis ↔ preprocessing/predictor_feature_extraction.ipynb, lines 197–264 · score 0.77 · Hausdorff distances, movement variability, Tracking points, radius, trajectories, segmented
  3. [3] § Methods › LFP analysis ↔ preprocessing/LFP_spindle_processing.ipynb, lines 1–125 · score 0.71 · Event duration, LFP, Hilbert, envelope, Gaussian, peak
  4. [4] § Methods › Statistical analysis ↔ ED_5/ED5_plots.ipynb, lines 159–259 · score 0.68 · pairwise PERMANOVA, signed rank, posthocs, Bonferroni, Wilcoxon, Shapiro
  5. [5] § Methods › Statistical analysis ↔ ED_6/ED6_plots.ipynb, lines 505–605 · score 0.68 · pairwise PERMANOVA, signed rank, posthocs, Bonferroni, Wilcoxon, Shapiro
  6. [6] § Results › DLS is required for a multistep procedural memory task ↔ figure1/Fig1_plots.ipynb, lines 431–485 · score 0.67 · Tukey HSD, way ANOVA, eta squared, variance, Cohen, Boxplots
  7. [7] § Methods › Statistical analysis ↔ ED_8/Utilities/utils.py, lines 12–69 · score 0.66 · canonical mode, variance explained, bootstrap, redundancy, CCA, component
  8. [8] § Methods › PP-Seq replay detection ↔ src/PPSeq.jl, lines 43–102 · score 0.66 · collapsed Gibbs sampling, PP Seq, likelihood, posterior, probabilistic, latent
  9. [9] § Methods › LFP analysis ↔ ED_6/ED6_plots.ipynb, lines 11–79 · score 0.64 · frequency band, spectral power, LFP, transform, spindle, 0.5 Hz
  10. [10] § Results › DLS is required for a multistep procedural memory task ↔ ED_1/ED1_plots.ipynb, lines 107–170 · score 0.61 · way ANOVA, post hoc, eta squared, Tukey, Cohen, DLS
  11. [11] § Methods › LFP analysis ↔ ED_5/ED5_plots.ipynb, lines 11–99 · score 0.56 · sleep state, LFP, velocity, ratio, NREM, broadband
  12. [12] § Results › An unsupervised approach for replay detection ↔ src/PPSeq.jl, lines 43–102 · score 0.55 · collapsed Gibbs sampling, latent events, PP Seq, spikes, model
  13. [13] § Results › Procedural memory formation and replay are independent of the hippocampus ↔ figure5/Fig5_plots.ipynb, lines 255–332 · score 0.54 · pairwise PERMANOVA, warp factors, Bonferroni, boxplots, permutation, reverse
  14. [14] § Methods › Tissue processing and image analysis ↔ code/@BT/BT.m, lines 1–47 · score 0.53 · scanImage, BakingTray, wrapper, microscope, serial
  15. [15] § Results › Procedural memory formation and replay are independent of the hippocampus ↔ ED_5/ED5_plots.ipynb, lines 159–259 · score 0.53 · pairwise PERMANOVA, warp factors, Bonferroni, R2, boxplots, permutation
  16. [16] § Methods › LFP analysis ↔ preprocessing/predictor_feature_extraction.ipynb, lines 13–121 · score 0.52 · tracking points, noisy, camera, Epochs, split, movement
  17. [17] § Methods › PP-Seq replay detection ↔ src/model/model.jl, lines 148–198 · score 0.51 · background firing, firing rate, width, log, model, Seq
  18. [18] § Methods › PP-Seq replay detection ↔ src/utils/config.jl, the whole file · a weak match · score 0.51 · background firing, firing rate, width, spikes, Seq, neuron
  19. [19] § Methods › Bayesian decoders ↔ preprocessing/PPseq_awake_postprocess.ipynb, lines 312–420 · score 0.50 · tracking position, task space, radius, bins, port, spiking

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 · 538 lines · 20 KB · MIT · 3 matches

  1. # %% [markdown]
  2. # # import
  3. # %%
  4. from Utilities.utils import *
  5. # Get the current working directory
  6. current_working_dir = os.path.join(Path(os.getcwd()).parent,'data')
  7. ED7_data_dict = load_h5(os.path.join(current_working_dir,r"ED7_data.h5"))
  8. # %% [markdown]
  9. # # figure A
  10. # %%
  11. data= ED7_data_dict['spectrogram_data']
  12. log_power = data["log_power"]
  13. frequencies = data["frequencies"]
  14. times = data["times"]
  15. t_points_cut = data["t_points_cut"]
  16. delta_cut = data["delta_cut"]
  17. theta_r_cut = data["theta_r_cut"]
  18. average_velocity_cut = data["average_velocity_cut"]
  19. nrem_spans = data["nrem_spans"]
  20. rem_spans = data["rem_spans"]
  21. spectrogram_params = data["spectrogram_params"]
  22. span_params = data["span_params"]
  23. # Figure
  24. fig, [ax, ax1, ax2, ax3] = plt.subplots(4, 1, figsize=(5, 8))
  25. # --- Spectrogram ---
  26. im = ax.imshow(
  27. log_power,
  28. aspect="auto",
  29. origin="lower",
  30. cmap=spectrogram_params["cmap"],
  31. extent=[
  32. 0,
  33. times.max(),
  34. frequencies.min(),
  35. frequencies.max()
  36. ],
  37. vmin=spectrogram_params["vmin"],
  38. vmax=spectrogram_params["vmax"]
  39. )
  40. ax.set_ylabel("Frequency (Hz)")
  41. ax.set_xlabel("Time (s)")
  42. ax.set_title("Spectrogram of LFP Data")
  43. ax.set_ylim(*spectrogram_params["freq_ylim"])
  44. # --- Delta ---
  45. ax1.plot(
  46. t_points_cut,
  47. delta_cut / np.std(delta_cut),
  48. c="k"
  49. )
  50. ax1.set_title("blue = NREM | red = REM")
  51. ax1.set_ylabel("delta power")
  52. # --- Theta ratio ---
  53. ax2.plot(
  54. t_points_cut,
  55. theta_r_cut / np.std(theta_r_cut),
  56. c="k"
  57. )
  58. ax2.set_ylabel("theta power (relative to broadband)")
  59. # --- Movement ---
  60. ax3.plot(
  61. t_points_cut,
  62. average_velocity_cut / np.std(average_velocity_cut),
  63. c="k"
  64. )
  65. ax3.set_xlabel("time (10s of seconds)")
  66. ax3.set_ylabel("movement")
  67. # --- Sleep state shading ---
  68. axs = [ax1, ax2, ax3]
  69. shade_spans(
  70. axs,
  71. nrem_spans,
  72. color=span_params["nrem_color"],
  73. bin_width=span_params["bin_width"],
  74. alpha=span_params["alpha"]
  75. )
  76. shade_spans(
  77. axs,
  78. rem_spans,
  79. color=span_params["rem_color"],
  80. bin_width=span_params["bin_width"],
  81. alpha=span_params["alpha"]
  82. )
  83. plt.tight_layout()
  84. plt.show()
  85. # %% [markdown]
  86. # # figure B
  87. # %%
  88. nrem_reactivations_per_min = ED7_data_dict['nrem_master']['reactivations_per_min']
  89. rem_reactivations_per_min = ED7_data_dict['rem_master']['reactivations_per_min']
  90. # replace nan values with 0
  91. nrem_reactivations_per_min = [0 if np.isnan(item) else item for item in nrem_reactivations_per_min]
  92. rem_reactivations_per_min = [0 if np.isnan(item) else item for item in rem_reactivations_per_min]
  93. ## PLOT
  94. fig, ax = plt.subplots(figsize=(2, 5))
  95. ax.plot(np.zeros(len(nrem_reactivations_per_min)), nrem_reactivations_per_min, 'o', color = '#69BD45')
  96. ax.boxplot(nrem_reactivations_per_min, positions=[0.3], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#69BD45', color='#69BD45'), medianprops=dict(color='#EE7832'))
  97. ax.plot(np.ones(len(rem_reactivations_per_min)), rem_reactivations_per_min, 'o', color = '#33495C')
  98. ax.boxplot(rem_reactivations_per_min, positions=[0.7], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#33495C', color='#33495C'), medianprops=dict(color='#EE7832'))
  99. ax.set_ylabel('Reactivations per minute')
  100. ax.set_title('nrem vs rem')
  101. ## STATS
  102. a = [x for x in nrem_reactivations_per_min if not np.isnan(x)]
  103. b = [x for x in rem_reactivations_per_min if not np.isnan(x)]
  104. print(scipy.stats.shapiro(a))
  105. print(scipy.stats.shapiro(b))
  106. # p is not greater than 0.05 for both, so we reject the null hypothesis that the data is normally distributed
  107. # non parametric t test, using scipy Wilcoxon Rank-Sum test
  108. print(scipy.stats.wilcoxon(a, b))
  109. effect_size(x=a, y=b, test='wilcoxon')
  110. # %% [markdown]
  111. # # figure C
  112. # %%
  113. nrem_event_lens = ED7_data_dict['nrem_master']['event_lens']
  114. rem_event_lens = ED7_data_dict['rem_master']['event_lens']
  115. nrem_event_lens = [np.nanmean(item) for item in nrem_event_lens]
  116. rem_event_lens = [np.nanmean(item) for item in rem_event_lens]
  117. ### PLOT
  118. fig, ax = plt.subplots(figsize=(2, 5))
  119. ax.plot(np.zeros(len(nrem_event_lens)), nrem_event_lens, 'o', color = '#69BD45')
  120. ax.boxplot(nrem_event_lens, positions=[0.3], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#69BD45', color='#69BD45'), medianprops=dict(color='#EE7832'))
  121. ax.plot(np.ones(len(rem_event_lens)), rem_event_lens, 'o', color = '#32495C')
  122. ax.boxplot([x for x in rem_event_lens if not np.isnan(x)], positions=[0.7], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#32495C', color='#32495C'), medianprops=dict(color='#EE7832'))
  123. ax.set_ylabel('Reactivations event lengths (s)')
  124. ax.set_title('nrem vs rem')
  125. ### STATS
  126. a = [x for x in nrem_event_lens if not np.isnan(x)]
  127. b = [x for x in rem_event_lens if not np.isnan(x)]
  128. print(scipy.stats.shapiro(a))
  129. print(scipy.stats.shapiro(b))
  130. # p is greater than 0.05 for both, so we fail to reject the null hypothesis that the data is normally distributed
  131. print(scipy.stats.wilcoxon(nrem_event_lens, rem_event_lens,nan_policy='omit'))
  132. print(effect_size(x=nrem_event_lens, y=rem_event_lens, test='wilcoxon'))
  133. # %% [markdown]
  134. # # figure D
  135. # %%
  136. bins_ = [0.1, 0.2, 1,2, 5, 10,20,40]
  137. animals_list = ED7_data_dict['nrem_master']['animals']
  138. nrem_f_warp_factors, nrem_r_warp_factors, nrem_forward_total, nrem_reverse_total = extract_mean_warps(pd.DataFrame(ED7_data_dict['nrem_master']['regression']), bins_,animals_list)
  139. nrem_proportion_forward_v_reverse = np.array(nrem_forward_total)/np.array(nrem_reverse_total)
  140. rem_f_warp_factors, rem_r_warp_factors, rem_forward_total, rem_reverse_total = extract_mean_warps(pd.DataFrame(ED7_data_dict['rem_master']['regression']), bins_,animals_list)
  141. rem_proportion_forward_v_reverse = np.array(rem_forward_total)/np.array(rem_reverse_total)
  142. ############################################################### PLOT
  143. fig,ax = plt.subplots(1, 1,figsize=(10, 5))
  144. color_ = '#69BD45'
  145. plot_warp_factors(ax, nrem_f_warp_factors, nrem_r_warp_factors, bins_, color_)
  146. color_ = '#32495C'
  147. plot_warp_factors(ax, rem_f_warp_factors, rem_r_warp_factors, bins_, color_)
  148. ax.set_title('nrem vs rem')
  149. plt.show()
  150. ## STATS
  151. print(scipy.stats.shapiro([item for sublist in nrem_f_warp_factors for item in sublist]))
  152. print(scipy.stats.shapiro([item for sublist in nrem_r_warp_factors for item in sublist]))
  153. print(scipy.stats.shapiro([item for sublist in rem_f_warp_factors for item in sublist]))
  154. print(scipy.stats.shapiro([item for sublist in rem_r_warp_factors for item in sublist]))
  155. print('----------------------------')
  156. print('permanova - forward reverse')
  157. print('----------------------------')
  158. permanova_forward_vs_reverse(nrem_f_warp_factors, nrem_r_warp_factors)
  159. print('-------------------')
  160. permanova_forward_vs_reverse(rem_f_warp_factors, rem_r_warp_factors)
  161. print('----------------------------')
  162. print('permanova - group differences')
  163. print('----------------------------')
  164. # PERMANOVA late vs early diff
  165. el_grouping = group_difference_permanova(nrem_f_warp_factors, nrem_f_warp_factors, rem_f_warp_factors, rem_f_warp_factors)
  166. print('----------------------------')
  167. print('posthoc - group differences')
  168. print('----------------------------')
  169. # Combine:
  170. combined_data = np.vstack([
  171. np.asarray(nrem_f_warp_factors),
  172. np.asarray(nrem_r_warp_factors),
  173. np.asarray(rem_f_warp_factors),
  174. np.asarray(rem_r_warp_factors)
  175. ])
  176. combined_labels = np.array(el_grouping)
  177. feature_results = pairwise_permanova_by_feature(
  178. combined_data,
  179. combined_labels,
  180. method='bonferroni',
  181. permutations=10000
  182. )
  183. print("Significant feature-wise pairwise PERMANOVA results (α=0.05):")
  184. for res in feature_results:
  185. p = res["p_value"]
  186. if p < 0.05:
  187. stars = '***' if p < 0.001 else '**' if p < 0.01 else '*'
  188. print(f"Feature {res['feature']}: {res['group1']} vs {res['group2']}")
  189. print(f" statistic = {res['test_stat']:.4f}, p (corr.) = {p:.4g} {stars}")
  190. print(f"R2 = {res['R2']}")
  191. print("---")
  192. #### PLOT inset
  193. fig, ax = plt.subplots(figsize=(2, 4))
  194. ax.plot(np.zeros(len(nrem_proportion_forward_v_reverse)),nrem_proportion_forward_v_reverse,'o', color = '#69BD45')
  195. ax.boxplot([x for x in nrem_proportion_forward_v_reverse if not np.isnan(x)], positions=[0.3], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#69BD45', color='#69BD45'), medianprops=dict(color='#EE7832'))
  196. ax.plot(np.ones(len(rem_proportion_forward_v_reverse)),rem_proportion_forward_v_reverse,'o', color = '#32495C')
  197. ax.boxplot([x for x in rem_proportion_forward_v_reverse if not np.isnan(x)], positions=[0.7], widths=0.1, patch_artist=True, boxprops=dict(facecolor='#32495C', color='#32495C'), medianprops=dict(color='#EE7832'))
  198. ax.set_title('nrem vs rem')
  199. plt.show()
  200. ### STATS for inset
  201. print('Inset: Difference from expected ------------------------')
  202. # Perform one-sample t-test
  203. statistic, p_value = ttest_1samp(nrem_proportion_forward_v_reverse, 1.0)
  204. # Print the test statistic and p-value
  205. print("Test statistic:", statistic)
  206. print("P-value:", p_value)
  207. print(effect_size(x=nrem_proportion_forward_v_reverse,test='one_sample_ttest',popmean = 1))
  208. print('--------------------')
  209. # Perform one-sample t-test
  210. statistic, p_value = ttest_1samp(rem_proportion_forward_v_reverse, 1.0, nan_policy="omit")
  211. # Print the test statistic and p-value
  212. print("Test statistic:", statistic)
  213. print("P-value:", p_value)
  214. rem_proportion_forward_v_reverse_nanr = rem_proportion_forward_v_reverse[~np.isnan(rem_proportion_forward_v_reverse)]
  215. print(effect_size(x=rem_proportion_forward_v_reverse_nanr,test='one_sample_ttest',popmean = 1))
  216. print('----------------------')
  217. print('Inset: comparison forward/reverse ------------------------')
  218. print(scipy.stats.shapiro(nrem_proportion_forward_v_reverse))
  219. print(scipy.stats.shapiro(rem_proportion_forward_v_reverse))
  220. # not all normal so use wilcoxn signed rank
  221. print(scipy.stats.wilcoxon(nrem_proportion_forward_v_reverse, rem_proportion_forward_v_reverse,nan_policy='omit'))
  222. print(effect_size(x=nrem_proportion_forward_v_reverse, y=rem_proportion_forward_v_reverse, test='wilcoxon'))
  223. # %% [markdown]
  224. # # figure E
  225. # %%
  226. group1_data, group2_data = plot_decay(ED7_data_dict['nrem_master']['binned_rate'] ,ED7_data_dict['nrem_master']['bins_relative_so'],ED7_data_dict['rem_master']['binned_rate'] ,ED7_data_dict['rem_master']['bins_relative_so'], '#69BD45','#32495C','nrem vs rem')
  227. plt.show()
  228. print('-----------------------------------------')
  229. ###################### STATS for inset
  230. ###################### STATS
  231. df1 = pd.DataFrame(group1_data)
  232. df2 = pd.DataFrame(group2_data)
  233. # Fit linear regression for Group 1
  234. model_group1 = sm.OLS.from_formula('y ~ x', data=df1).fit()
  235. model_group2 = sm.OLS.from_formula('y ~ x', data=df2).fit()
  236. print('PLOT 2:')
  237. # Print the summary of each model
  238. print("Group 1 (NREM):")
  239. # print(model_group1.summary())
  240. print('model p value (f statistic) = ')
  241. print(model_group1.f_pvalue)
  242. print('r2 = ')
  243. print(model_group1.rsquared)
  244. print("Group 2 (REM):")
  245. # print(model_group1.summary())
  246. print('model p value (f statistic) = ')
  247. print(model_group2.f_pvalue)
  248. print('r2 = ')
  249. print(model_group2.rsquared)
  250. ## STATS
  251. # Combine the data into one DataFrame
  252. data = pd.concat([df1, df2], axis=0)
  253. # Create a grouping variable
  254. groups = np.array(['nrem'] * len(df1) + ['rem'] * len(df2))
  255. # Perform MANOVA
  256. manova = MANOVA.from_formula('x + y ~ groups', data=data)
  257. # Print the MANOVA results
  258. print(manova.mv_test())
  259. # Compute partial eta-squared
  260. eta_squared = compute_partial_eta_squared(manova.mv_test())
  261. print("Partial eta-squared for each effect:", eta_squared)
  262. # %% [markdown]
  263. # # figure F
  264. # %%
  265. fig,[ax,ax2] = plt.subplots(1, 2,figsize=(10, 4))
  266. all_chunk_reverse_start_mean, all_chunk_forward_start_mean, all_chunk_reverse_end_mean, all_chunk_forward_end_mean = extract_start_end_points(pd.DataFrame(ED7_data_dict['rem_master']['start_end']))
  267. plot_start_end_times(all_chunk_reverse_start_mean,all_chunk_forward_start_mean,all_chunk_reverse_end_mean,all_chunk_forward_end_mean,ax,ax2,'REM','#32495C')
  268. fig,[ax,ax2] = plt.subplots(1, 2,figsize=(10, 4))
  269. all_chunk_reverse_start_mean, all_chunk_forward_start_mean, all_chunk_reverse_end_mean, all_chunk_forward_end_mean = extract_start_end_points(pd.DataFrame(ED7_data_dict['nrem_master']['start_end']))
  270. plot_start_end_times(all_chunk_reverse_start_mean,all_chunk_forward_start_mean,all_chunk_reverse_end_mean,all_chunk_forward_end_mean,ax,ax2,'NREM','#69BD45')
  271. plt.show()
  272. #### STATS
  273. nrem_all_chunk_reverse_start_mean, nrem_all_chunk_forward_start_mean, nrem_all_chunk_reverse_end_mean, nrem_all_chunk_forward_end_mean = extract_start_end_points(pd.DataFrame(ED7_data_dict['nrem_master']['start_end']))
  274. rem_all_chunk_reverse_start_mean, rem_all_chunk_forward_start_mean, rem_all_chunk_reverse_end_mean, rem_all_chunk_forward_end_mean = extract_start_end_points(pd.DataFrame(ED7_data_dict['rem_master']['start_end']))
  275. group1 = [x for x in nrem_all_chunk_reverse_start_mean if not np.isnan(x)]
  276. group2 = [x for x in nrem_all_chunk_forward_start_mean if not np.isnan(x)]
  277. group3 = [x for x in nrem_all_chunk_reverse_end_mean if not np.isnan(x)]
  278. group4 = [x for x in nrem_all_chunk_forward_end_mean if not np.isnan(x)]
  279. group5 = [x for x in rem_all_chunk_reverse_start_mean if not np.isnan(x)]
  280. group6 = [x for x in rem_all_chunk_forward_start_mean if not np.isnan(x)]
  281. group7 = [x for x in rem_all_chunk_reverse_end_mean if not np.isnan(x)]
  282. group8 = [x for x in rem_all_chunk_forward_end_mean if not np.isnan(x)]
  283. for group in [group1, group2, group3, group4, group5, group6, group7, group8]:
  284. print(scipy.stats.shapiro(group))
  285. df_nrem = pd.DataFrame({
  286. 'group': ['late'] * len(nrem_all_chunk_forward_start_mean),
  287. 'forward_start': nrem_all_chunk_forward_start_mean,
  288. 'forward_end': nrem_all_chunk_forward_end_mean,
  289. 'reverse_start': nrem_all_chunk_reverse_start_mean,
  290. 'reverse_end': nrem_all_chunk_reverse_end_mean,
  291. })
  292. df_rem = pd.DataFrame({
  293. 'group': ['early'] * len(rem_all_chunk_forward_start_mean),
  294. 'forward_start': rem_all_chunk_forward_start_mean,
  295. 'forward_end': rem_all_chunk_forward_end_mean,
  296. 'reverse_start': rem_all_chunk_reverse_start_mean,
  297. 'reverse_end': rem_all_chunk_reverse_end_mean,
  298. })
  299. print('_____________________________________________________________________________________________')
  300. # 1. Concatenate and clean
  301. df = pd.concat([df_nrem, df_rem], ignore_index=True)
  302. df_clean = df.dropna(subset=['forward_start','forward_end','reverse_start','reverse_end']).reset_index(drop=True)
  303. # 2. Build your feature matrix
  304. X = df_clean[['forward_start','forward_end','reverse_start','reverse_end']].values
  305. # 3. Compute Euclidean distances
  306. dist_array = squareform(pdist(X, metric='euclidean'))
  307. # 4. Create DistanceMatrix with simple integer-string IDs (0,1,2,…)
  308. ids = [str(i) for i in range(len(df_clean))]
  309. dm = DistanceMatrix(dist_array, ids=ids)
  310. # 5. Extract grouping as a plain list (length N)
  311. grouping = df_clean['group'].tolist()
  312. # 6. Run PERMANOVA
  313. result = permanova(distance_matrix=dm,
  314. grouping=grouping,
  315. permutations=999)
  316. print(result)
  317. #Compute R² manually (effect size)
  318. # ss_total = sum of squared distances / n
  319. D = dm.data # <-- this is the fix
  320. n = len(grouping)
  321. ss_total = np.sum(D**2) / n
  322. # ss_between: sum of squared group means
  323. group_labels = np.array(grouping)
  324. unique_groups = np.unique(group_labels)
  325. ss_between = 0
  326. for g in unique_groups:
  327. idx = np.where(group_labels == g)[0]
  328. Di = D[np.ix_(idx, idx)]
  329. ss_between += len(idx) * (Di.mean() ** 2)
  330. r2 = ss_between / ss_total
  331. print(f"PERMANOVA effect size R²: {r2:.5f}")
  332. # %% [markdown]
  333. # # figure G
  334. # %%
  335. rem_counts = collapse(convert_word_keys_to_numeric(ED7_data_dict['rem_master']['coactive_freqs']))
  336. nrem_counts = collapse(convert_word_keys_to_numeric(ED7_data_dict['nrem_master']['coactive_freqs']))
  337. colors = {"nrem": "#727272", "rem": "#74C269"}
  338. offset = 0.2
  339. # PLOT
  340. # ============================================================
  341. fig, (ax1, ax2) = plt.subplots(
  342. 1, 2, figsize=(4, 5),
  343. gridspec_kw={'width_ratios': [2, 10]}
  344. )
  345. # Left panel: coactive = 1 (median)
  346. for counts, color, off in [
  347. (rem_counts, colors["rem"], offset),
  348. (nrem_counts, colors["nrem"], -offset)
  349. ]:
  350. plot_group(ax1, counts, ['1'], off, color, np.median)
  351. ax1.set_xlim(0.5, 1.5)
  352. ax1.set_ylim(0, 1)
  353. ax1.set_ylabel('relative frequency')
  354. # Right panel: coactive >= 2 (mean)
  355. keys = [str(i) for i in range(2, 7)]
  356. for counts, color, off in [
  357. (rem_counts, colors["rem"], offset),
  358. (nrem_counts, colors["nrem"], -offset)
  359. ]:
  360. plot_group(ax2, counts, keys, off, color, np.mean)
  361. ax2.set_xlabel('number of coactive events')
  362. ax2.set_ylim(0, 0.4)
  363. plt.tight_layout()
  364. plt.show()
  365. # ============================================================
  366. # STATS
  367. # ============================================================
  368. permanova_coactive_freqs(convert_word_keys_to_numeric(ED7_data_dict['nrem_master']['coactive_freqs']), convert_word_keys_to_numeric(ED7_data_dict['rem_master']['coactive_freqs']))
  369. # %% [markdown]
  370. # # figure H
  371. # %%
  372. # PLOT
  373. plot_ordered_misrodered(ED7_data_dict['nrem_master']['ordered_misordered'],'nrem','ordered/misordered proportion')
  374. plot_ordered_misrodered(ED7_data_dict['rem_master']['ordered_misordered'],'rem','ordered/misordered proportion')
  375. # STATS
  376. list1 = [float(item[0]) for item in ED7_data_dict['nrem_master']['ordered_misordered']]
  377. list2 = [float(item[1]) for item in ED7_data_dict['nrem_master']['ordered_misordered']]
  378. list1= [x for x in list1 if not np.isnan(x)]
  379. list2= [x for x in list2 if not np.isnan(x)]
  380. permutation_test(list1, list2)
  381. print(f'cohens d = {cohens_d(list1, list2)}')
  382. print('------------------')
  383. list3 = [float(item[0]) for item in ED7_data_dict['rem_master']['ordered_misordered']]
  384. list4 = [float(item[1]) for item in ED7_data_dict['rem_master']['ordered_misordered']]
  385. list3= [x for x in list3 if not np.isnan(x)]
  386. list4= [x for x in list4 if not np.isnan(x)]
  387. permutation_test(list3, list4)
  388. print(f'cohens d = {cohens_d(list3, list4)}')
  389. # test for normality
  390. print('------------------')
  391. print(scipy.stats.shapiro(list1))
  392. print(scipy.stats.shapiro(list2))
  393. print(scipy.stats.shapiro(list3))
  394. print(scipy.stats.shapiro(list4))
  395. print('------------------')
  396. # parmanova between groups
  397. permanova_ordered_misordered(ED7_data_dict['nrem_master']['ordered_misordered'], ED7_data_dict['rem_master']['ordered_misordered'])
  398. # %% [markdown]
  399. # # figure I
  400. # %%
  401. plot_ordered_misrodered(ED7_data_dict['nrem_master']['task_nontask'],'nrem','task related/unrelated proportion')
  402. plot_ordered_misrodered(ED7_data_dict['rem_master']['task_nontask'],'rem','task related/unrelated proportion')
  403. # STATS
  404. list1 = [float(item[0]) for item in ED7_data_dict['nrem_master']['task_nontask']]
  405. list2 = [float(item[1]) for item in ED7_data_dict['nrem_master']['task_nontask']]
  406. list1= [x for x in list1 if not np.isnan(x)]
  407. list2= [x for x in list2 if not np.isnan(x)]
  408. permutation_test(list1, list2)
  409. print(f'cohens d = {cohens_d(list1, list2)}')
  410. print('------------------')
  411. list3 = [float(item[0]) for item in ED7_data_dict['rem_master']['task_nontask']]
  412. list4 = [float(item[1]) for item in ED7_data_dict['rem_master']['task_nontask']]
  413. list3= [x for x in list3 if not np.isnan(x)]
  414. list4= [x for x in list4 if not np.isnan(x)]
  415. permutation_test(list3, list4)
  416. print(f'cohens d = {cohens_d(list3, list4)}')
  417. # test for normality
  418. print(scipy.stats.shapiro(list1))
  419. print(scipy.stats.shapiro(list2))
  420. print(scipy.stats.shapiro(list3))
  421. print(scipy.stats.shapiro(list4))
  422. #permanova for nrem vs rem
  423. permanova_ordered_misordered(ED7_data_dict['rem_master']['task_nontask'], ED7_data_dict['rem_master']['task_nontask'])
  424. # %% [markdown]
  425. # # figure J
  426. # %%
  427. awake_seqbyseq_neuron_involvements = ED7_data_dict['neuron_involvement_master']['awake_seqbyseq_neuron_involvements']
  428. fig, ax = plt.subplots(1, 1,figsize=(5, 5))
  429. nrem_awake_sleep_relationship = return_binned_neuron_awake_sleep_rel(awake_seqbyseq_neuron_involvements,ED7_data_dict['nrem_master']['sleep_seqbyseq_neuron_involvements'])
  430. plot_awake_sleep_relationship(nrem_awake_sleep_relationship,'#69BD45',ax)
  431. rem_awake_sleep_relationship = return_binned_neuron_awake_sleep_rel(awake_seqbyseq_neuron_involvements,ED7_data_dict['rem_master']['sleep_seqbyseq_neuron_involvements'])
  432. plot_awake_sleep_relationship(rem_awake_sleep_relationship,'#32495C',ax)
  433. ax.set_title('nrem vs rem')
  434. ## STATS
  435. m =manova_groups_neuron_involvement(nrem_awake_sleep_relationship,rem_awake_sleep_relationship)
  436. eta_squared = compute_partial_eta_squared(m)
  437. print("Partial eta-squared for each effect:", eta_squared)
  438. # %%
  439. # %%
  440. # %%

ED5_plots.ipynb at commit 2e1ef18, under MIT · at the source

Overview

Authors: Emmett J. Thompson1, Lars B. Rollik1, Benjamin Waked1, Georgina Mills1, Sthitapranjya Pati1, Jasvin Kaur1, Ben Geva1, Haoyu Li1, Rodrigo Carrasco-Davis2, Tom George1, Clementine Domine2, William Dorrell2, Marcus Stephenson-Jones1
  1. Sainsbury Wellcome Centre for Neural Circuits and Behaviour, University College London,London, UK
  2. Gatsby Computational Neuroscience Unit, University College London,London, UK
Institutions: University College London (United Kingdom)
Journal: Nature neuroscience, volume 29, issue 9, pages 2237-2248
Dates: received 16 March 2026; accepted 9 June 2026; published online 23 July 2026; in print 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41593-026-02362-5 · PMID 42493550 · PMCID PMC13533836 · OpenAlex W7170145842
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: mouse (organism), cognitive (subfield)
Methods: Spectral & time-frequency, Connectivity, Statistics, Preprocessing, Evoked potentials, Machine learning, Single-unit activity, calcium imaging
Keywords: Consolidation, Hippocampus
MeSH: Hippocampus*, Memory*, Memory Consolidation*, Sleep*, Animals, Male, Mice, Mice, Inbred C57BL (* major topic)
Topic: Sleep and Wakefulness Research (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 73 references in the paper

Abstract

Sleep is crucial for consolidating all forms of memory and a core mechanism underlying this process is offline replay. Current models propose that replay originates in the hippocampus and triggers reactivation across cortical and subcortical networks. However, conflicting evidence about the role of the hippocampus in offline consolidation of nondeclarative memories raises the question of whether hippocampal replay drives their consolidation. Here we show that replay occurs in the dorsal striatum during offline consolidation of a procedural memory in mice, independently of the hippocampus, and that its content predicts subsequent performance improvements. Neural sequences linked to salient behavioral events were prioritized for replay, with positive and negative behavioral outcomes having opposing effects on individual replay events. All features of replay persisted despite complete bilateral hippocampal lesions. These findings demonstrate that procedural replay occurs independently of the hippocampus, indicating that replay-driven memory consolidation can operate through parallel, independent mechanisms.

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

SainsburyWellcomeCentre/BakingTray

License: LGPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 50eb5ca97a7477d768e10154413a4bf8103e2c59, 7 September 2026
Languages: MATLAB (332)
Size: 435 files, 332 scripts
Software Heritage: not archived
Found in: the text, “Tissue processing and image analysis”
Holds: README, license file, tests
Not found: CITATION.cff, environment file, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
334 files

Zenodo 363160

License: none: the authors keep all their rights
State: the link is dead, verified on 27 September 2026
Evidence: found in the paper
Software Heritage: not checked
Found in: the text, “Tissue processing and image analysis”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link is dead (HTTP 404)
  • 27 September 2026: the link is dead (HTTP 404)
At the source:

lindermanlab/ppseq.jl

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: e89078ccd100be5ddaf7b0ece014b98926f2a40b, 18 July 2023
Languages: Julia (20), Jupyter (3)
Size: 30 files, 23 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, environment (Project.toml), continuous integration, 3 notebooks
Not found: CITATION.cff, tests, documentation
Tools: Distributions.jl (2 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
25 files

stephensonjoneslab/thompson_et_al_2026

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 2e1ef18164faa4129eec848de30814e796d2712f, 8 May 2026
Languages: Jupyter (23), Python (20)
Size: 73 files, 43 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, environment (environment.yaml, requirements.txt), 23 notebooks
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NumPy (23 files), Matplotlib (22 files), pandas (22 files), SciPy (22 files), h5py (18 files), statsmodels (18 files), seaborn (15 files), Pingouin (6 files), Pillow (4 files), scikit-learn (2 files), scikit-posthocs (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
45 files

Code availability

The analysis code is publicly available at https://github.com/StephensonJonesLab/Thompson_et_al_2026/tree/V1.02 and https://github.com/lindermanlab/PPSeq.jl/pull/15.

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;
  • 398 scripts, each with its path and the digest of its content;
  • 19 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

The data that support the findings of this study are available via Zenodo at https://doi.org/10.5281/zenodo.20055819 (ref. 73). In addition, Allen Brain Atlas connectivity (https://connectivity.brain-map.org/) data were used to demarcate the corticostriatal projection patterns from prelimbic and cingulate cortex (experiment nos.: 157711748 and 112514202) and motor cortex (experiment nos.: 180720175 and 180709942). Source data are provided with this paper.

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 2, 28 September 2026

  • Publisher: n/a → Nature Portfolio

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 13 authors, 2 keywords, 8 MeSH terms, 2 funders, 73 references.

Cite

This paper

Thompson, E. J., Rollik, L. B., Waked, B., Mills, G., Pati, S., Kaur, J., Geva, B., Li, H., Carrasco-Davis, R., George, T., Domine, C., Dorrell, W., & Stephenson-Jones, M. (2026). Replay of procedural memory is independent of the hippocampus. Nature neuroscience, 29(9), 2237-2248. https://doi.org/10.1038/s41593-026-02362-5

BibTeX

@article{thompson2026replay,
author = {Thompson, Emmett J. and Rollik, Lars B. and Waked, Benjamin and Mills, Georgina and Pati, Sthitapranjya and Kaur, Jasvin and Geva, Ben and Li, Haoyu and Carrasco-Davis, Rodrigo and George, Tom and Domine, Clementine and Dorrell, William and Stephenson-Jones, Marcus},
title = {{Replay of procedural memory is independent of the hippocampus}},
journal = {Nature neuroscience},
year = {2026},
month = jul,
volume = {29},
number = {9},
pages = {2237--2248},
publisher = {Nature Portfolio},
issn = {1097-6256},
doi = {10.1038/s41593-026-02362-5},
url = {https://doi.org/10.1038/s41593-026-02362-5},
pmid = {42493550},
pmcid = {PMC13533836}
}

RIS

TY - JOUR
AU - Thompson, Emmett J.
AU - Rollik, Lars B.
AU - Waked, Benjamin
AU - Mills, Georgina
AU - Pati, Sthitapranjya
AU - Kaur, Jasvin
AU - Geva, Ben
AU - Li, Haoyu
AU - Carrasco-Davis, Rodrigo
AU - George, Tom
AU - Domine, Clementine
AU - Dorrell, William
AU - Stephenson-Jones, Marcus
TI - Replay of procedural memory is independent of the hippocampus
T2 - Nature neuroscience
J2 - Nat Neurosci
PY - 2026
DA - 2026/07/23
VL - 29
IS - 9
SP - 2237
EP - 2248
SN - 1097-6256
PB - Nature Portfolio
DO - 10.1038/s41593-026-02362-5
UR - https://doi.org/10.1038/s41593-026-02362-5
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41593-026-02362-5",
"type": "article-journal",
"title": "Replay of procedural memory is independent of the hippocampus",
"container-title": "Nature neuroscience",
"author": [
{
"family": "Thompson",
"given": "Emmett J."
},
{
"family": "Rollik",
"given": "Lars B."
},
{
"family": "Waked",
"given": "Benjamin"
},
{
"family": "Mills",
"given": "Georgina"
},
{
"family": "Pati",
"given": "Sthitapranjya"
},
{
"family": "Kaur",
"given": "Jasvin"
},
{
"family": "Geva",
"given": "Ben"
},
{
"family": "Li",
"given": "Haoyu"
},
{
"family": "Carrasco-Davis",
"given": "Rodrigo"
},
{
"family": "George",
"given": "Tom"
},
{
"family": "Domine",
"given": "Clementine"
},
{
"family": "Dorrell",
"given": "William"
},
{
"family": "Stephenson-Jones",
"given": "Marcus"
}
],
"container-title-short": "Nat Neurosci",
"volume": "29",
"issue": "9",
"page": "2237-2248",
"DOI": "10.1038/s41593-026-02362-5",
"PMID": "42493550",
"PMCID": "PMC13533836",
"ISSN": "1097-6256",
"publisher": "Nature Portfolio",
"URL": "https://doi.org/10.1038/s41593-026-02362-5",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
23
]
]
}
}

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/s41593-026-02232-0 [code]
Entorhinal cortex represents task-relevant remote locations independently of CA1.
Journal: Nature neuroscience
In common: Pingouin, h5py, Pillow, 9 other tools, mouse, 9 references
[2] doi:10.1038/s41593-026-02357-2 [code]
Experience reorganizes content-specific memory traces in macaques.
Journal: Nature neuroscience
In common: Image Processing Toolbox, Statistics and Machine Learning Toolbox, seaborn, 5 other tools, 5 references
[3] doi:10.1016/j.isci.2026.117375 [code]
Motor priming is associated with widespread recruitment into neural ensembles and more rapid ensemble transitions.
Journal: iScience
In common: scikit-posthocs, Pingouin, h5py, 9 other tools
[4] doi:10.1038/s41467-026-77318-1 [code]
Offline generative network reconfiguration guides insight-like accelerated learning by assimilation into schema in rats.
Journal: Nature communications
In common: Statistics and Machine Learning Toolbox, seaborn, scikit-learn, 3 other tools, 6 references
[5] doi:10.7554/elife.108023 [code]
Challenges in replay detection by TDLM in post-encoding resting state.
Journal: eLife
In common: statsmodels, Statistics and Machine Learning Toolbox, seaborn, 5 other tools, 5 references
[6] doi: [code]
Real-time closed-loop feedback system for mouse mesoscale cortical signal and movement control
Journal: eLife
In common: Pingouin, h5py, Pillow, 7 other tools, mouse, 2 references
[7] 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: scikit-posthocs, Pingouin, Pillow, 8 other tools, cognitive
[8] doi:10.1038/s41467-026-74823-1 [code]
Cerebellar activity is triggered by reach endpoint during learning of a complex locomotor task.
Journal: Nature communications
In common: scikit-posthocs, Pingouin, h5py, 7 other tools, mouse, 1 reference
[9] doi:10.1093/sleep/zsag168 [code]
Deltas' and spindles' cross-area synchronization and ripple subtypes.
Journal: Sleep
In common: Image Processing Toolbox, Statistics and Machine Learning Toolbox, scikit-learn, 3 other tools, 5 references
[10] doi:10.1038/s41467-026-76581-6 [code]
Thalamocortical bursts encode reward contingencies and drive associative learning.
Journal: Nature communications
In common: h5py, Pillow, Image Processing Toolbox, 6 other tools, mouse, 3 references

Contribute

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

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

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.