OSCR

Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex.

Code ↔ Paper

15 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 15 matches
  1. [1] § Materials and methods › Short‑latency spike–time interaction analysis ↔ code/old_new_transimition_UPGRADED.ipynb, lines 390–454 · score 0.75 · 20–50 ms, excess coincidence, normalized CCG, subtracted, baseline, lag
  2. [2] § Materials and methods › Modulation index (MI) ↔ code/specturm_PLV_MI.ipynb, lines 323–394 · score 0.71 · instantaneous phase, amplitude envelope, phase amplitude, MI, Hilbert, signal
  3. [3] § Materials and methods › Local field potential (LFP) analysis ↔ code/specturm_PLV_MI.ipynb, lines 396–445 · score 0.70 · 30–60 Hz, 60–90 Hz, 4–12 Hz, LFP, gamma, 30 Hz
  4. [4] § Materials and methods › Assembly detection ↔ code/assemble_withoutswr.ipynb, lines 158–247 · score 0.67 · FastICA, Pastur, eigenvalues, variance, threshold, Component
  5. [5] § Materials and methods › Population decoding ↔ code/decoding.ipynb, lines 276–299 · score 0.66 · naive Bayes, GaussianNB, score, classifier, decoding, training
  6. [6] § Materials and methods › Population decoding ↔ code/decoding.ipynb, lines 383–472 · score 0.65 · ROC curve, ROC AUC, predicted, decoding, probabilities, class
  7. [7] § Materials and methods › Theta phase locking of single units ↔ code/specturm_PLV_MI.ipynb, lines 508–563 · score 0.62 · Theta cycles, 4–12 Hz, troughs, tetrode
  8. [8] § Materials and methods › Short‑latency spike–time interaction analysis ↔ code/old_new_transimition_UPGRADED.ipynb, lines 390–454 · score 0.62 · excess coincidence, ms bin, CCGs, lag, coupling, window
  9. [9] § Materials and methods › Phase‑locking value (PLV) ↔ code/specturm_PLV_MI.ipynb, lines 153–208 · score 0.60 · signal.butter, signal.filtfilt, transform, PLV, filtered
  10. [10] § Results › State‑dependent oscillatory coordination between dCA1 and mOFC changed across learning ↔ code/specturm_PLV_MI.ipynb, lines 396–445 · score 0.60 · 30–60 Hz, 60–90 Hz, 4–12 Hz, PLV, gamma, 30 Hz
  11. [11] § Materials and methods › Phase‑locking value (PLV) ↔ code/SWR.ipynb, lines 145–200 · score 0.57 · signal.butter, signal.filtfilt, transform, filtered
  12. [12] § Materials and methods › Assembly detection ↔ code/SWR.ipynb, lines 145–200 · score 0.52 · FastICA, PCA, variance, Component
  13. [13] § Materials and methods › Heatmap ↔ code/spatial_rate_map.ipynb, lines 151–238 · score 0.51 · spatial rate maps, spike maps, tracked, Heatmap, binned
  14. [14] § Materials and methods › Statistical analyses ↔ code/old_new_transimition_UPGRADED.ipynb, lines 457–479 · score 0.51 · Benjamini Hochberg, discovery, rank, FDR
  15. [15] § Materials and methods › Short‑latency spike–time interaction analysis ↔ code/old_new_transimition_UPGRADED.ipynb, lines 522–599 · score 0.50 · jittered surrogate, empirical, ms, spike

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 · 651 lines · 23 KB · no license · 5 matches

  1. # %%
  2. import numpy as np
  3. import os
  4. %matplotlib inline
  5. import matplotlib.pyplot as plt
  6. import pandas as pd
  7. import math
  8. import matplotlib
  9. from matplotlib.colors import ListedColormap
  10. import cv2
  11. from scipy import stats
  12. import scipy.fft as fft
  13. from scipy import signal
  14. from sklearn.decomposition import FastICA, PCA
  15. from scipy.signal import hilbert
  16. # %%
  17. def mkdir(path):
  18. folder = os.path.exists(path)
  19. if not folder: #Check whether the folder exists; create it if it does not exist
  20. os.makedirs(path)
  21. # %%
  22. sessionname = 'lw0150523'
  23. # %%
  24. v = 10
  25. windows_hz = 1
  26. overlap = 0.9
  27. samples = 20000
  28. newfreq = 1000
  29. times = 4
  30. lowband = 1
  31. highband = 400
  32. timewindow = 2*newfreq
  33. pin1 = 0
  34. pin = 150
  35. lowband_theta = 4
  36. highband_theta = 12
  37. lowband_lowgamma = 30
  38. highband_lowgamma = 60
  39. lowband_highgamma = 60
  40. highband_highgamma = 90
  41. ampchannel = 64
  42. vediofreq = 50
  43. amplitudefreq = 20000
  44. vedioampinter = amplitudefreq // vediofreq
  45. # %%
  46. dlc_base_path = 'D:/tlw/DLC/'
  47. xy_base = 'D:/tlw/coor/'
  48. phy_base = 'D:/tlw/tlw-phy/'
  49. trialname_base = 'D:/tlw/trialname/'
  50. cell_type_base = 'D:/tlw/cell_type/'
  51. reward_pos_base = 'D:/tlw/maze_reward_ratio/reward_pos/'
  52. periodon_base = 'D:/tlw/periodon_time/'
  53. veloc_direction_base = 'D:/tlw/veloc_direction/'
  54. ratio_base = 'D:/tlw/maze_reward_ratio/ratio/'
  55. heatmap_base = 'D:/tlw/heatmap/'
  56. through_times_base = 'D:/tlw/through_time/'
  57. specturm_save_base = 'D:/tlw/specturm/'
  58. pte_save_base = 'D:/tlw/PTE/'
  59. plv_save_base = 'D:/tlw/PLV/'
  60. mi_save_path = 'D:/tlw/MI/'
  61. thetacycle_save_base = 'D:/tlw/thetacycle/'
  62. dlc_path = dlc_base_path + sessionname
  63. phy_path = phy_base + sessionname
  64. trialname_path = trialname_base + sessionname
  65. coor_path = xy_base + sessionname
  66. reward_pos_path = reward_pos_base + sessionname
  67. periodon_path = periodon_base + sessionname
  68. veloc_direction_path = veloc_direction_base + sessionname
  69. cell_type_path = cell_type_base + sessionname
  70. ratio_path = ratio_base + sessionname
  71. heatmap_path = heatmap_base + sessionname
  72. through_times_path = through_times_base + sessionname
  73. specturm_save_path = specturm_save_base + sessionname
  74. mkdir(specturm_save_path)
  75. pte_save_path = pte_save_base + sessionname
  76. mkdir(pte_save_path)
  77. plv_save_path = plv_save_base + sessionname
  78. mkdir(plv_save_path)
  79. mi_save_path = mi_save_path + sessionname
  80. mkdir(mi_save_path)
  81. thetacycle_save_path = thetacycle_save_base + sessionname
  82. mkdir(thetacycle_save_path)
  83. # %%
  84. trialname = np.load(trialname_path + '-foruse.npy', allow_pickle=True).item()
  85. reward_pos = np.load(reward_pos_path + '.npy')
  86. ratio = np.load(ratio_path + '.npy')
  87. trial_period_time = pd.read_excel(periodon_path + '.xlsx')
  88. cell_type = np.load(cell_type_path+'.npy', allow_pickle=True).item()
  89. pre_xcoord = np.load(coor_path+'/'+trialname['pre']+'-head.npy')
  90. periodstarts = np.asarray(trial_period_time.iloc[0, 1:])
  91. periodends = np.asarray(trial_period_time.iloc[1, 1:])
  92. spike_time = np.load(phy_path+"/spike_times.npy")
  93. spike_clusters = np.load(phy_path+"/spike_clusters.npy")
  94. cluster_group = pd.read_csv(phy_path+'/cluster_group.tsv', delimiter='\t')
  95. cluster_group = np.asarray(cluster_group)
  96. good_index = np.where(cluster_group[:, 1]=='good')[0]
  97. good_cluster = cluster_group[:, 0][good_index]
  98. ofc_pyr_clu = np.asarray(cell_type['ofc_pyr'])
  99. hpc_pyr_clu = np.asarray(cell_type['hpc_pyr'])
  100. ofc_int_clu = np.asarray(cell_type['ofc_inter'])
  101. hpc_int_clu = np.asarray(cell_type['hpc_inter'])
  102. ofc_pyr_id = np.asarray([np.where(good_cluster==ci)[0] for ci in ofc_pyr_clu])
  103. hpc_pyr_id = np.asarray([np.where(good_cluster==ci)[0] for ci in hpc_pyr_clu])
  104. ofc_int_id = np.asarray([np.where(good_cluster==ci)[0] for ci in ofc_int_clu])
  105. hpc_int_id = np.asarray([np.where(good_cluster==ci)[0] for ci in hpc_int_clu])
  106. trace_pre = np.load(coor_path + '/' + trialname['pre'] + '-head.npy')
  107. trace_post = np.load(coor_path + '/' + trialname['post'] + '-head.npy')
  108. trial_learning = trialname['learning']
  109. trialall = np.append(np.append(trialname['pre'], trialname['learning']), trialname['post'])
  110. # %%
  111. def read_bi(path, ch):
  112. data = open(path, 'rb')
  113. data = np.fromfile(data, np.int16)
  114. data = data.reshape([-1, ch])
  115. return data
  116. # %%
  117. ampdata = read_bi(phy_path+'/amplifier.dat', ampchannel)
  118. # %%
  119. ch_ofc = [10] ### Changes when calculating MI, PLV, and PTE
  120. ch_hpc = [22]
  121. ch_ofc_invariance = 10 ############# Used to save amplitude envelopes and phases; unchanged
  122. ch_hpc_invariance = 22
  123. # %%
  124. ampdata.shape
  125. # %%
  126. def resample(data, orifreq, newfreq):
  127. sample = orifreq // newfreq
  128. return data[::sample]
  129. def butterfilt(data, fs, lowband, highband, times):
  130. ## filter
  131. fn = fs/2
  132. w1 = lowband / fn
  133. w2 = highband / fn
  134. [b,a] = signal.butter(times, [w1, w2], 'bandpass')
  135. filted_data = signal.filtfilt(b, a, data)
  136. return filted_data
  137. def ICA(data, n_components):
  138. model = FastICA(n_components=n_components, whiten="arbitrary-variance")
  139. down_data = model.fit_transform(data) #
  140. return down_data
  141. def run_pca(data, n_components):
  142. pca = PCA(n_components=n_components)
  143. H = pca.fit_transform(data)
  144. return H
  145. def gaussian_filter(img, K_size=3, sigma=1.3):
  146. H, W = img.shape
  147. ## Zero padding
  148. pad = K_size // 2
  149. out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float64)
  150. out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float64)
  151. ## prepare Kernel
  152. K = np.zeros((K_size, K_size), dtype=np.float64)
  153. for x in range(-pad, -pad + K_size):
  154. for y in range(-pad, -pad + K_size):
  155. K[y + pad, x + pad] = np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
  156. K /= (2 * np.pi * sigma * sigma)
  157. K /= K.sum()
  158. tmp = out.copy()
  159. # filtering
  160. for y in range(H):
  161. for x in range(W):
  162. out[pad + y, pad + x] = np.sum(K * tmp[y: y + K_size, x: x + K_size])
  163. out = out[pad: pad + H, pad: pad + W]
  164. return out
  165. # %%
  166. def remove50(data, samples):
  167. b, a = signal.iirnotch(50, 10, samples)
  168. return signal.filtfilt(b, a, data)
  169. def prepocess(data, orifreq, newfreq, times, lowband, highband):
  170. down_data = resample(data, orifreq, newfreq)
  171. filt_data = butterfilt(down_data, newfreq, lowband, highband, times)
  172. # Remove baseline drift
  173. filted = signal.detrend(filt_data)
  174. # plt.plot(filt_data[:10000], color='r')
  175. # plt.plot(filted[:10000], color='g')
  176. # plt.show()
  177. return filted
  178. def cal_spec_epoch(filted_data, windows_hz, overlap, newfreq):
  179. l = len(filted_data)
  180. windows = math.floor(newfreq/windows_hz)
  181. windows_overlaped = math.floor(windows*overlap)
  182. f, t, sxx = signal.spectrogram(filted_data, newfreq, nperseg=windows, noverlap=windows_overlaped)
  183. fw, Pwelch_spec = signal.welch(filted_data, newfreq, scaling='spectrum')
  184. return f, t, sxx, fw, Pwelch_spec
  185. # %%
  186. def get_spectrumall(names, ofc_ch, hpc_ch, windows, overlap, samples, newfreq, times, lowband, highband, savepath):
  187. channels = ofc_ch + hpc_ch
  188. for name in names:
  189. label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
  190. ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq
  191. start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq
  192. for i in channels:
  193. data = ampdata[trial_period_time[name][0]:trial_period_time[name][1], i]*0.195
  194. filted_data = prepocess(data, samples, newfreq, times, lowband, highband)
  195. # plt.plot(filted_data[:1000], c='y')
  196. # plt.show()
  197. # plt.close()
  198. f, t, sxx, fw, Pwelch_spec = cal_spec_epoch(filted_data, windows, overlap, newfreq)
  199. dbsxx = 10*np.log10(sxx)
  200. dbPwelch_spec = 10*np.log10(Pwelch_spec)
  201. gfdbsxx = gaussian_filter(dbsxx, K_size=3, sigma=1.2)
  202. powerpad = np.zeros((sxx.shape[0]+1, sxx.shape[1]+1))
  203. powerpad[0, 1:] = t
  204. powerpad[1:, 0] = f
  205. powerpad[1:, 1:] = sxx
  206. if i in ofc_ch:
  207. area = '_ofc'
  208. else:
  209. area = '_hpc'
  210. save_name = savepath+'/'+name+area+str(pin1)+'-'+str(pin)
  211. np.save(save_name+'_spec_ch.npy', np.asarray([fw, Pwelch_spec]))
  212. np.save(save_name+'_spower.npy', powerpad)
  213. sid = np.where(abs(f - pin1)<5)[0][0]
  214. eid = np.where(abs(f - pin)<5)[0][0]
  215. plt.figure(figsize=(15, 3))
  216. plt.pcolormesh(t, f[sid:eid], gfdbsxx[sid:eid, :], shading='gourand', cmap='jet')
  217. plt.colorbar()
  218. plt.xlabel("window time")
  219. plt.ylabel("frenqunce (Hz)")
  220. plt.title(name+'trial_'+str(i)+area+'_point')
  221. for et in ends_trial:
  222. plt.axvline(et, color='grey', linestyle=':', linewidth=2)
  223. plt.xticks(ends_trial, label_trial)
  224. plt.savefig(save_name+'_power.png')
  225. plt.show()
  226. plt.close()
  227. plt.semilogy(fw[sid:eid], dbPwelch_spec[sid:eid])
  228. plt.xlabel('frequency [Hz]')
  229. plt.ylabel('PSD')
  230. plt.grid()
  231. plt.title(name+'trial_'+str(i)+area+'_point')
  232. plt.savefig(save_name+'_spec.png')
  233. plt.show()
  234. plt.close()
  235. return ofc_ch, hpc_ch
  236. get_spectrumall(trial_learning, ch_ofc, ch_hpc, windows_hz, overlap, samples, newfreq, times, lowband, highband, specturm_save_path)
  237. # %%
  238. SWR_base = 'D:/tlw/SWR/'
  239. SWR_path = SWR_base + sessionname
  240. swr_start_session = np.load(SWR_path+'/swrstart.npy', allow_pickle=True).item()
  241. swr_spike_session = np.load(SWR_path+'/swrspike.npy', allow_pickle=True).item()
  242. # %%
  243. ### MI
  244. binnum = 36
  245. savename = ['theta-lg', 'theta-hg']
  246. def phase_amp(data, fs):
  247. analytical_signal = hilbert(data)
  248. amplitude_envelop = np.abs(analytical_signal)
  249. instantanous_phase = np.angle(analytical_signal)
  250. instantanous_frequency = (np.diff(instantanous_phase) / (2.0*np.pi) * fs)
  251. return amplitude_envelop, instantanous_phase, instantanous_frequency
  252. for name in trial_learning:
  253. swr_start = swr_start_session[name]
  254. label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
  255. ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
  256. start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
  257. data_ofc_trial = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc[0]] * 0.195
  258. data_hpc_trial = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc[0]] * 0.195
  259. data_ofc_lg = prepocess(data_ofc_trial, samples, newfreq, times, lowband_lowgamma, highband_lowgamma)
  260. data_ofc_hg = prepocess(data_ofc_trial, samples, newfreq, times, lowband_highgamma, highband_highgamma)
  261. data_hpc_theta = prepocess(data_hpc_trial, samples, newfreq, times, lowband_theta, highband_theta)
  262. results = np.zeros((2, len(label_trial)))
  263. for sessionid, l, s, e in zip(range(len(label_trial)), label_trial, start_trial, ends_trial):
  264. if e-s < 100:
  265. results[ig, sessionid] = 0
  266. continue
  267. lg_ofcamplitude_envelop, lg_ofcinstantanous_phase, lg_ofcinstantanous_frequency = phase_amp(data_ofc_lg[int(s):int(e)], newfreq)
  268. hg_ofcamplitude_envelop, hg_ofcinstantanous_phase, hg_ofcinstantanous_frequency = phase_amp(data_ofc_hg[int(s):int(e)], newfreq)
  269. hpcamplitude_envelop, hpcinstantanous_phase, hpcinstantanous_frequency = phase_amp(data_hpc_theta[int(s):int(e)], newfreq)
  270. hpcinstantanous_degree = hpcinstantanous_phase * 180 / np.pi
  271. try:
  272. swr_start_k = swr_start * newfreq
  273. for sk in swr_start_k:
  274. hpcamplitude_envelop[int(sk):int(sk)+newfreq*0.1] = -1
  275. hpcinstantanous_degree[int(sk):int(sk)+newfreq*0.1] = -1
  276. except:
  277. pass
  278. for ig, amplitude_envelop, sn in zip(range(2), [lg_ofcamplitude_envelop, hg_ofcamplitude_envelop], savename):
  279. bin = np.linspace(0, 360, binnum+1) -180
  280. p = np.zeros(binnum)
  281. for i in range(binnum):
  282. index = np.where((hpcinstantanous_degree >= bin[i]) & (hpcinstantanous_degree < bin[i+1]))
  283. p[i] = np.sum(amplitude_envelop[index])
  284. pi = p / np.sum(p)
  285. hmax = np.log2(binnum)
  286. h = - np.sum(pi * np.log2(pi))
  287. MI = (hmax - h) / hmax
  288. results[ig, sessionid] = MI
  289. figpath = mi_save_path+'/'+name+'-'+str(ch_ofc[0])+'-'+str(ch_hpc[0])
  290. with pd.ExcelWriter(mi_save_path + '/' + name + '_ch' + str(ch_ofc[0]) + '-with-ch' + str(ch_hpc[0]) + '_MI.xlsx') as writer:
  291. df = pd.DataFrame(results, columns=label_trial)
  292. df.to_excel(writer, index=False)
  293. # %%
  294. ## PLV
  295. lfpband = [[[4,12], [4,12]], [[4,12],[30, 60]], [[4,12],[60, 90]], [[30,60],[30,60]], [[60,90],[60, 90]], [[30,60],[60, 90]]] ### ofc theta; hpc theta,gamma
  296. n_m = [[1,1], [1,15],[1,25],[1,1],[1,1],[1,10]]
  297. bandname = ['-theta_theta-', '-theta_lg-', '-theta_hg-', '-lg_lg-', '-hg_hg-', '-lg_hg-']
  298. def PLV(data, n, m):
  299. return np.abs(np.sum(np.exp(1j*(m*data[:, 0]-n*data[:, 1]))))/len(data[:, 0])
  300. for name in trial_learning:
  301. label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
  302. ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
  303. start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
  304. data_ofc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc[0]] * 0.195
  305. data_hpc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc[0]] * 0.195
  306. for lfp, nm, saven in zip(lfpband, n_m, bandname):
  307. data_ofc_trial = prepocess(data_ofc_trials, samples, newfreq, times, lfp[0][0], lfp[0][1])
  308. data_hpc_trial = prepocess(data_hpc_trials, samples, newfreq, times, lfp[1][0], lfp[1][1])
  309. result = dict()
  310. for l, s, e in zip(label_trial, start_trial, ends_trial):
  311. plv = np.zeros(nm[1])
  312. if e-s > 100:
  313. dataputin = np.stack([data_ofc_trial[int(s):int(e)], data_hpc_trial[int(s):int(e)]], axis=1) #
  314. complex_series = hilbert(dataputin, axis=0)
  315. phase = np.angle(complex_series)
  316. try:
  317. swr_start_k = swr_start * newfreq
  318. for sk in swr_start_k:
  319. phase[int(sk):int(sk)+newfreq*0.1] = 0
  320. except:
  321. pass
  322. for mi in range(0, nm[1]):
  323. plv[mi] = PLV(phase, 1, mi+1)
  324. result[l] = plv
  325. with pd.ExcelWriter(plv_save_path + '/' + name + saven + '_ch' + str(ch_ofc[0]) + '-with-ch' + str(ch_hpc[0]) + '_PLV.xlsx') as writer:
  326. for i, bn in enumerate(label_trial):
  327. df = pd.DataFrame(result[bn], columns=[bn])
  328. df.to_excel(writer, startcol=i, index=False)
  329. # %%
  330. ### Save amp and phase
  331. lfpband = [[4,12], [30, 60], [60, 90]]
  332. bandname = ['-theta-', '-lg-', '-hg-']
  333. for name in trial_learning:
  334. label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
  335. ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
  336. start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
  337. data_ofc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc_invariance] * 0.195
  338. data_hpc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc_invariance] * 0.195
  339. for lfp, saven in zip(lfpband, bandname):
  340. data_ofc_trial = prepocess(data_ofc_trials, samples, newfreq, times, lfp[0], lfp[1])
  341. data_hpc_trial = prepocess(data_hpc_trials, samples, newfreq, times, lfp[0], lfp[1])
  342. ofc_amps = []
  343. ofc_phas = []
  344. hpc_amps = []
  345. hpc_phas = []
  346. for l, s, e in zip(label_trial, start_trial, ends_trial):
  347. if e-s < 100:
  348. ofc_amps.append([0])
  349. ofc_phas.append([0])
  350. hpc_amps.append([0])
  351. hpc_phas.append([0])
  352. else:
  353. complex_series_ofc = hilbert(data_ofc_trial[int(s):int(e)], axis=0)
  354. amplitude_envelop_ofc = np.abs(complex_series_ofc)
  355. instantanous_phase_ofc = np.angle(complex_series_ofc)
  356. ofc_amps.append(amplitude_envelop_ofc)
  357. ofc_phas.append(instantanous_phase_ofc)
  358. complex_series_hpc = hilbert(data_hpc_trial[int(s):int(e)], axis=0)
  359. amplitude_envelop_hpc = np.abs(complex_series_hpc)
  360. instantanous_phase_hpc = np.angle(complex_series_hpc)
  361. hpc_amps.append(amplitude_envelop_hpc)
  362. hpc_phas.append(instantanous_phase_hpc)
  363. with pd.ExcelWriter(specturm_save_path+'/'+name + saven + 'ofc.xlsx') as writer:
  364. for ii, ll in enumerate(label_trial):
  365. ofcampdf = pd.DataFrame(ofc_amps[ii], columns=[ll])
  366. ofcampdf.to_excel(writer, index=False, startcol=ii, sheet_name='envelop')
  367. ofcphadf = pd.DataFrame(ofc_phas[ii], columns=[ll])
  368. ofcphadf.to_excel(writer, index=False, startcol=ii, sheet_name='phase')
  369. with pd.ExcelWriter(specturm_save_path+'/'+name + saven + 'hpc.xlsx') as writer:
  370. for i, l in enumerate(label_trial):
  371. hpcampdf = pd.DataFrame(hpc_amps[i], columns=[l])
  372. hpcampdf.to_excel(writer, index=False, startcol=i, sheet_name='envelop')
  373. hpcphadf = pd.DataFrame(hpc_phas[i], columns=[l])
  374. hpcphadf.to_excel(writer, index=False, startcol=i, sheet_name='phase')
  375. # %%
  376. ### theta cycle
  377. def peak_minma(data, times):
  378. # Peak detection
  379. peak_ind, _ = signal.find_peaks(data)
  380. # Trough detection
  381. minima_ind = signal.argrelextrema(data, np.less)
  382. minima_ind = minima_ind[0]
  383. return peak_ind, minima_ind
  384. def smooth(data):
  385. k = np.asarray([0.05, 0.10, 0.70, 0.10, 0.05])
  386. pad_data = np.insert(data, 0, [0, 0])
  387. pad_data = np.append(pad_data, [0, 0])
  388. temp_data = np.zeros_like(data)
  389. for i in range(2, len(pad_data)-3):
  390. temp_data[i-2] = np.sum(pad_data[i-2:i+3] * k)
  391. return temp_data
  392. def get_theta_arfa_ratio(name, downrate, represent):
  393. eeg_data = ampdata[trial_period_time[name][0]:trial_period_time[name][1], represent]*0.195
  394. # Select theta from one tetrode for coupling analysis 6
  395. data = resample(eeg_data, amplitudefreq, downrate)
  396. data = butterfilt(data, downrate, 1, 30, 4)
  397. times = np.arange(len(data)) / downrate
  398. period = np.zeros_like(data)
  399. windows = math.floor(downrate/1)
  400. windows_overlaped = math.floor(windows*0.9)
  401. f, t, sxx = signal.spectrogram(data, downrate, nperseg=windows, noverlap=windows_overlaped) #, nperseg=200, noverlap=50
  402. arfaband = [1,4]
  403. thetaband = [4,12]
  404. arfaid = np.where((f>=arfaband[0]) & (f<=arfaband[1]))[0]
  405. thetaid = np.where((f>[thetaband[0]]) & (f<=[thetaband[1]]))
  406. arfapower = np.sum(sxx[arfaid], axis=0)
  407. thetapower = np.sum(sxx[thetaid], axis=0)
  408. thetaperiodid = np.where(thetapower >= 2*arfapower)[0]
  409. continueid = np.where((thetaperiodid[1:] - thetaperiodid[:-1]) > 1)[0]
  410. periodstart = t[np.append(np.asarray([thetaperiodid[0]]),thetaperiodid[1:][continueid])]
  411. periodend = t[np.append(thetaperiodid[:-1][continueid],np.asarray([thetaperiodid[-1]]))]
  412. for pp in range(len(periodstart)):
  413. period[int(periodstart[pp]*downrate):int(periodend[pp]*downrate)] = 1
  414. return data, times, period
  415. # %%
  416. def get_theta_(name, downrate, savepath, samples, vediof, represent): #, datpath
  417. data, times, thetaperiod = get_theta_arfa_ratio(name, downrate, represent)
  418. inter = samples // downrate
  419. veloc = np.load(veloc_direction_path+'/'+name+'-veloc.npy')
  420. #Points with speed below 4 are excluded from theta extraction
  421. interval = downrate // vediof
  422. avail_ = np.array(veloc >= 4)
  423. avail_point = np.tile(avail_, (interval, 1))
  424. avail_point = avail_point.flatten('F')
  425. if len(data)>len(avail_point):
  426. data = data[:len(avail_point)]
  427. thetaperiod = thetaperiod[:len(avail_point)]
  428. times = times[:len(avail_point)]
  429. elif len(data)<len(avail_point):
  430. avail_point = avail_point[:len(data)]
  431. peak_ind, minima_ind = peak_minma(data, times)
  432. ind_array = np.zeros(len(data))
  433. ind_array[peak_ind] = 1
  434. ind_array[minima_ind] = -1
  435. avail_ind = ind_array * avail_point * thetaperiod
  436. #Segment theta
  437. theta_start = []
  438. theta_peak = []
  439. theta_end = []
  440. pointer = np.argmax(avail_ind==-1)
  441. while pointer < len(data)-60:
  442. if (pointer != len(data)) & (avail_ind[pointer] == -1):
  443. temp_start = pointer
  444. pointer += 1
  445. while (pointer != len(data)-1) & (avail_ind[pointer] == 0):
  446. pointer += 1
  447. if (avail_ind[pointer] == 1) & (pointer != len(data)-1):
  448. temp_peak = pointer
  449. pointer += 1
  450. while (pointer != len(data)-1) & (avail_ind[pointer] == 0):
  451. pointer += 1
  452. if avail_ind[pointer] == -1:
  453. temp_end = pointer
  454. if (temp_end - temp_start > 60) or (temp_end - temp_start < 20):
  455. continue
  456. else:
  457. ### Check amplitude; theta amplitude 100-150
  458. # plt.plot(data[temp_start:temp_end])
  459. # plt.show()
  460. if data[temp_peak] > 80:
  461. theta_start.append(temp_start)
  462. theta_peak.append(temp_peak)
  463. theta_end.append(temp_end)
  464. # plt.plot(data[temp_start-2:temp_end+2])
  465. # plt.plot(temp_peak-temp_start+3, data[temp_peak],"*")
  466. # plt.savefig('t')
  467. # plt.close()
  468. print(pointer, len(data))
  469. continue
  470. pointer += 1
  471. theta_peak = np.asarray(theta_peak)*inter
  472. theta_start = np.asarray(theta_start)*inter
  473. theta_end = np.asarray(theta_end)*inter
  474. np.save(savepath+'/'+'theta_peak.npy', theta_peak) ## theta_peak_ofc
  475. np.save(savepath+'/'+'theta_start.npy', theta_start)
  476. np.save(savepath+'/'+'theta_end.npy', theta_end)
  477. return theta_start, theta_peak, theta_end
  478. represent = 14
  479. for i, name in enumerate(trial_learning):
  480. savepathi = thetacycle_save_path + '/' + name
  481. mkdir(savepathi)
  482. theta_start, theta_peak, theta_end = get_theta_(name, newfreq, savepathi, samples, vediofreq, represent)

specturm_PLV_MI.ipynb, no license · at the source

Overview

Authors: Jiasong Li1, Lingwei Tang1, Xinhang Wei1, Yumin Chen1, Haibing Xu1
ORCID iDs: Haibing Xu
  1. Key Laboratory of Mental Health of the Ministry of Education, Guangdong‑Hong Kong‑Macao Greater Bay Area Center for Brain Science and Brain‑Inspired Intelligence, Department of Neurobiology, School of Basic Medical Sciences, Southern Medical University, Guangzhou, China
Institutions: Southern Medical University (China)
Journal: PLoS biology, volume 24, issue 5, article e3003824
Dates: received 16 December 2025; accepted 13 May 2026; published online 29 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pbio.3003824 · PMID 42213668 · PMCID PMC13221071 · OpenAlex W7162783674
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: rat (organism), systems (subfield)
Methods: Spectral & time-frequency, Connectivity, Statistics, Smoothing, state filtering, decompositions, Machine learning, Evoked potentials, Graphs, fMRI & imaging, Single-unit activity, calcium imaging
MeSH: CA1 Region, Hippocampal*, Learning*, Prefrontal Cortex*, Animals, Goals, Male, Maze Learning, Memory, Neurons, Rats, Rats, Long-Evans (* major topic)
Journal subjects: Biology and Life Sciences, Cell Biology, Cellular Types, Animal Cells, Neurons, Neuroscience, Cellular Neuroscience, Cognitive Science, Cognitive Psychology, Learning, Psychology, Social Sciences, Learning and Memory, Behavior, Anatomy, Brain, Hippocampus, Medicine and Health Sciences, Interneurons, Engineering and Technology, Signal Processing, Signal Filtering, Animal Behavior, Animal Migration, Animal Navigation, Zoology, Physiology, Electrophysiology, Membrane Potential, Action Potentials, Neurophysiology
Topic: Memory and Neural Mechanisms (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: National Major Science and Technology Projects of China (2022ZD0205000); National Natural Science Foundation of China (National Science Foundation of China) (32171038, W243058); Guangdong Basic and Applied Basic Research Foundation (2022A515011896, 2024A1515011033)
Citations: not cited yet (Europe PMC); 98 references in the paper

Abstract

Flexible goal‑directed navigation requires integrating changing goal information with a stable spatial map, yet how cortico-hippocampal circuits accomplish this remains unclear. We simultaneously recorded medial orbitofrontal cortex (mOFC) and dorsal CA1 (dCA1) while rats learned daily changing goal locations on a cheeseboard maze. Rats rapidly learned new goal locations and retained memory for them in the post‑probe session. Both regions contained goal‑related neuronal representations, but their profiles differed: dCA1 showed stronger spatial specificity, whereas mOFC showed more prominent learning‑related updating of goal‑related activity. Combining dCA1 and mOFC activity improved decoding of behavioral stage and learning block relative to either region alone, consistent with complementary contributions to ongoing behavior and learning state. Across learning, these population‑level differences were accompanied by stronger theta‑range synchronization and theta–gamma coupling during navigation than during goal periods. A recurrent network model with dynamic synaptic efficacy captured qualitative features of efficient acquisition and flexible goal updating, providing a candidate computational framework for how learning‑related temporal coordination could contribute to adaptive navigation.

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

Repository

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

OSF a24pj

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Languages: Jupyter (21), Python (1)
Size: 24 files, 22 scripts
Software Heritage: not checked
Found in: “Data Availability”
Holds: 21 notebooks
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (19 files), Matplotlib (15 files), pandas (14 files), SciPy (10 files), OpenCV (8 files), scikit-learn (5 files), PyTorch (4 files), Plotly (2 files), Pillow (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
  • 28 September 2026: the link answers (HTTP 200)
19 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:

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

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

Data

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

Data Availability

Analysis code and processed data supporting the conclusions of this study are deposited on OSF: https://doi.org/10.17605/OSF.IO/A24PJ.

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

Versions

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

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 11 MeSH terms, 3 funders, 98 references.

Cite

This paper

Li, J., Tang, L., Wei, X., Chen, Y., & Xu, H. (2026). Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex. PLoS biology, 24(5), e3003824. https://doi.org/10.1371/journal.pbio.3003824

BibTeX

@article{li2026flexible,
author = {Li, Jiasong and Tang, Lingwei and Wei, Xinhang and Chen, Yumin and Xu, Haibing},
title = {{Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex}},
journal = {PLoS biology},
year = {2026},
month = may,
volume = {24},
number = {5},
pages = {e3003824},
publisher = {PLOS},
issn = {1544-9173},
doi = {10.1371/journal.pbio.3003824},
url = {https://doi.org/10.1371/journal.pbio.3003824},
pmid = {42213668},
pmcid = {PMC13221071}
}

RIS

TY - JOUR
AU - Li, Jiasong
AU - Tang, Lingwei
AU - Wei, Xinhang
AU - Chen, Yumin
AU - Xu, Haibing
TI - Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex
T2 - PLoS biology
J2 - PLoS Biol
PY - 2026
DA - 2026/05/29
VL - 24
IS - 5
SP - e3003824
SN - 1544-9173
PB - PLOS
DO - 10.1371/journal.pbio.3003824
UR - https://doi.org/10.1371/journal.pbio.3003824
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pbio.3003824",
"type": "article-journal",
"title": "Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex",
"container-title": "PLoS biology",
"author": [
{
"family": "Li",
"given": "Jiasong"
},
{
"family": "Tang",
"given": "Lingwei"
},
{
"family": "Wei",
"given": "Xinhang"
},
{
"family": "Chen",
"given": "Yumin"
},
{
"family": "Xu",
"given": "Haibing"
}
],
"container-title-short": "PLoS Biol",
"volume": "24",
"issue": "5",
"page": "e3003824",
"DOI": "10.1371/journal.pbio.3003824",
"PMID": "42213668",
"PMCID": "PMC13221071",
"ISSN": "1544-9173",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pbio.3003824",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
29
]
]
}
}

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.1002/hipo.70131 [code]
Decoding Medial Entorhinal Cortical Dynamics Produces Planning-Like Alternations in Hippocampal theta Sequences.
Journal: Hippocampus
In common: OpenCV, scikit-learn, pandas, 3 other tools, systems, 5 references
[2] doi:10.1038/s41467-026-77240-6
Prefrontal-thalamic goal states organize spatially aligned hippocampal maps.
Journal: Nature communications
In common: rat, systems, 8 references
[3] doi:10.1038/s41593-026-02388-9 [code]
Hippocampal CA3 connectomics reveals a gradient of mossy fiber inputs and selective feedforward inhibition onto pyramidal cells.
Journal: Nature neuroscience
In common: Plotly, OpenCV, Pillow, 6 other tools, systems, 1 reference
[4] doi:10.1038/s41593-026-02357-2 [code]
Experience reorganizes content-specific memory traces in macaques.
Journal: Nature neuroscience
In common: scikit-learn, pandas, SciPy, 2 other tools, 4 references
[5] doi:10.1002/hbm.70469 [code]
VarCoNet: A Variability-Aware Self-Supervised Framework for Functional Connectome Extraction From Resting-State fMRI.
Journal: Human brain mapping
In common: Plotly, OpenCV, Pillow, 6 other tools, 1 reference
[6] doi:10.1038/s41593-026-02232-0 [code]
Entorhinal cortex represents task-relevant remote locations independently of CA1.
Journal: Nature neuroscience
In common: OpenCV, Pillow, PyTorch, 5 other tools, systems, 1 reference
[7] doi:10.3389/fnsys.2026.1822122 [code]
Convergence-divergence circuits for multimodal integration of innate and learned opponent valences.
Journal: Frontiers in systems neuroscience
In common: Plotly, Pillow, PyTorch, 5 other tools, systems, 1 reference
[8] doi:10.1073/pnas.2517639123 [code]
Transformations of the spatial activity manifold convey aversive information in CA3.
Journal: Proceedings of the National Academy of Sciences of the United States of America
In common: scikit-learn, pandas, SciPy, 2 other tools, systems, 4 references
[9] doi:10.1016/j.isci.2026.116825 [code]
Social hierarchy shapes behavioral and transcriptional responses to chronic stress and ketamine in male mice.
Journal: iScience
In common: Plotly, OpenCV, Pillow, 6 other tools, systems
[10] doi:10.1093/sleep/zsag168 [code]
Deltas' and spindles' cross-area synchronization and ripple subtypes.
Journal: Sleep
In common: Plotly, scikit-learn, SciPy, 2 other tools, rat, 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.