Flexible goal learning involves coordinated population activity in dCA1 and medial orbitofrontal cortex.
The 15 matches
- [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] § 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] § 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] § Materials and methods › Assembly detection ↔ code/assemble_withoutswr.ipynb, lines 158–247 · score 0.67 · FastICA, Pastur, eigenvalues, variance, threshold, Component
- [5] § Materials and methods › Population decoding ↔ code/decoding.ipynb, lines 276–299 · score 0.66 · naive Bayes, GaussianNB, score, classifier, decoding, training
- [6] § Materials and methods › Population decoding ↔ code/decoding.ipynb, lines 383–472 · score 0.65 · ROC curve, ROC AUC, predicted, decoding, probabilities, class
- [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] § 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] § 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] § 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] § Materials and methods › Phase‑locking value (PLV) ↔ code/SWR.ipynb, lines 145–200 · score 0.57 · signal.butter, signal.filtfilt, transform, filtered
- [12] § Materials and methods › Assembly detection ↔ code/SWR.ipynb, lines 145–200 · score 0.52 · FastICA, PCA, variance, Component
- [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] § Materials and methods › Statistical analyses ↔ code/old_new_transimition_UPGRADED.ipynb, lines 457–479 · score 0.51 · Benjamini Hochberg, discovery, rank, FDR
- [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
- # %%
- import numpy as np
- import os
- %matplotlib inline
- import matplotlib.pyplot as plt
- import pandas as pd
- import math
- import matplotlib
- from matplotlib.colors import ListedColormap
- import cv2
- from scipy import stats
- import scipy.fft as fft
- from scipy import signal
- from sklearn.decomposition import FastICA, PCA
- from scipy.signal import hilbert
- # %%
- def mkdir(path):
- folder = os.path.exists(path)
- if not folder: #Check whether the folder exists; create it if it does not exist
- os.makedirs(path)
- # %%
- sessionname = 'lw0150523'
- # %%
- v = 10
- windows_hz = 1
- overlap = 0.9
- samples = 20000
- newfreq = 1000
- times = 4
- lowband = 1
- highband = 400
- timewindow = 2*newfreq
- pin1 = 0
- pin = 150
- lowband_theta = 4
- highband_theta = 12
- lowband_lowgamma = 30
- highband_lowgamma = 60
- lowband_highgamma = 60
- highband_highgamma = 90
- ampchannel = 64
- vediofreq = 50
- amplitudefreq = 20000
- vedioampinter = amplitudefreq // vediofreq
- # %%
- dlc_base_path = 'D:/tlw/DLC/'
- xy_base = 'D:/tlw/coor/'
- phy_base = 'D:/tlw/tlw-phy/'
- trialname_base = 'D:/tlw/trialname/'
- cell_type_base = 'D:/tlw/cell_type/'
- reward_pos_base = 'D:/tlw/maze_reward_ratio/reward_pos/'
- periodon_base = 'D:/tlw/periodon_time/'
- veloc_direction_base = 'D:/tlw/veloc_direction/'
- ratio_base = 'D:/tlw/maze_reward_ratio/ratio/'
- heatmap_base = 'D:/tlw/heatmap/'
- through_times_base = 'D:/tlw/through_time/'
- specturm_save_base = 'D:/tlw/specturm/'
- pte_save_base = 'D:/tlw/PTE/'
- plv_save_base = 'D:/tlw/PLV/'
- mi_save_path = 'D:/tlw/MI/'
- thetacycle_save_base = 'D:/tlw/thetacycle/'
- dlc_path = dlc_base_path + sessionname
- phy_path = phy_base + sessionname
- trialname_path = trialname_base + sessionname
- coor_path = xy_base + sessionname
- reward_pos_path = reward_pos_base + sessionname
- periodon_path = periodon_base + sessionname
- veloc_direction_path = veloc_direction_base + sessionname
- cell_type_path = cell_type_base + sessionname
- ratio_path = ratio_base + sessionname
- heatmap_path = heatmap_base + sessionname
- through_times_path = through_times_base + sessionname
- specturm_save_path = specturm_save_base + sessionname
- mkdir(specturm_save_path)
- pte_save_path = pte_save_base + sessionname
- mkdir(pte_save_path)
- plv_save_path = plv_save_base + sessionname
- mkdir(plv_save_path)
- mi_save_path = mi_save_path + sessionname
- mkdir(mi_save_path)
- thetacycle_save_path = thetacycle_save_base + sessionname
- mkdir(thetacycle_save_path)
- # %%
- trialname = np.load(trialname_path + '-foruse.npy', allow_pickle=True).item()
- reward_pos = np.load(reward_pos_path + '.npy')
- ratio = np.load(ratio_path + '.npy')
- trial_period_time = pd.read_excel(periodon_path + '.xlsx')
- cell_type = np.load(cell_type_path+'.npy', allow_pickle=True).item()
- pre_xcoord = np.load(coor_path+'/'+trialname['pre']+'-head.npy')
- periodstarts = np.asarray(trial_period_time.iloc[0, 1:])
- periodends = np.asarray(trial_period_time.iloc[1, 1:])
- spike_time = np.load(phy_path+"/spike_times.npy")
- spike_clusters = np.load(phy_path+"/spike_clusters.npy")
- cluster_group = pd.read_csv(phy_path+'/cluster_group.tsv', delimiter='\t')
- cluster_group = np.asarray(cluster_group)
- good_index = np.where(cluster_group[:, 1]=='good')[0]
- good_cluster = cluster_group[:, 0][good_index]
- ofc_pyr_clu = np.asarray(cell_type['ofc_pyr'])
- hpc_pyr_clu = np.asarray(cell_type['hpc_pyr'])
- ofc_int_clu = np.asarray(cell_type['ofc_inter'])
- hpc_int_clu = np.asarray(cell_type['hpc_inter'])
- ofc_pyr_id = np.asarray([np.where(good_cluster==ci)[0] for ci in ofc_pyr_clu])
- hpc_pyr_id = np.asarray([np.where(good_cluster==ci)[0] for ci in hpc_pyr_clu])
- ofc_int_id = np.asarray([np.where(good_cluster==ci)[0] for ci in ofc_int_clu])
- hpc_int_id = np.asarray([np.where(good_cluster==ci)[0] for ci in hpc_int_clu])
- trace_pre = np.load(coor_path + '/' + trialname['pre'] + '-head.npy')
- trace_post = np.load(coor_path + '/' + trialname['post'] + '-head.npy')
- trial_learning = trialname['learning']
- trialall = np.append(np.append(trialname['pre'], trialname['learning']), trialname['post'])
- # %%
- def read_bi(path, ch):
- data = open(path, 'rb')
- data = np.fromfile(data, np.int16)
- data = data.reshape([-1, ch])
- return data
- # %%
- ampdata = read_bi(phy_path+'/amplifier.dat', ampchannel)
- # %%
- ch_ofc = [10] ### Changes when calculating MI, PLV, and PTE
- ch_hpc = [22]
- ch_ofc_invariance = 10 ############# Used to save amplitude envelopes and phases; unchanged
- ch_hpc_invariance = 22
- # %%
- ampdata.shape
- # %%
- def resample(data, orifreq, newfreq):
- sample = orifreq // newfreq
- return data[::sample]
- def butterfilt(data, fs, lowband, highband, times):
- ## filter
- fn = fs/2
- w1 = lowband / fn
- w2 = highband / fn
- [b,a] = signal.butter(times, [w1, w2], 'bandpass')
- filted_data = signal.filtfilt(b, a, data)
- return filted_data
- def ICA(data, n_components):
- model = FastICA(n_components=n_components, whiten="arbitrary-variance")
- down_data = model.fit_transform(data) #
- return down_data
- def run_pca(data, n_components):
- pca = PCA(n_components=n_components)
- H = pca.fit_transform(data)
- return H
- def gaussian_filter(img, K_size=3, sigma=1.3):
- H, W = img.shape
- ## Zero padding
- pad = K_size // 2
- out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float64)
- out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float64)
- ## prepare Kernel
- K = np.zeros((K_size, K_size), dtype=np.float64)
- for x in range(-pad, -pad + K_size):
- for y in range(-pad, -pad + K_size):
- K[y + pad, x + pad] = np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
- K /= (2 * np.pi * sigma * sigma)
- K /= K.sum()
- tmp = out.copy()
- # filtering
- for y in range(H):
- for x in range(W):
- out[pad + y, pad + x] = np.sum(K * tmp[y: y + K_size, x: x + K_size])
- out = out[pad: pad + H, pad: pad + W]
- return out
- # %%
- def remove50(data, samples):
- b, a = signal.iirnotch(50, 10, samples)
- return signal.filtfilt(b, a, data)
- def prepocess(data, orifreq, newfreq, times, lowband, highband):
- down_data = resample(data, orifreq, newfreq)
- filt_data = butterfilt(down_data, newfreq, lowband, highband, times)
- # Remove baseline drift
- filted = signal.detrend(filt_data)
- # plt.plot(filt_data[:10000], color='r')
- # plt.plot(filted[:10000], color='g')
- # plt.show()
- return filted
- def cal_spec_epoch(filted_data, windows_hz, overlap, newfreq):
- l = len(filted_data)
- windows = math.floor(newfreq/windows_hz)
- windows_overlaped = math.floor(windows*overlap)
- f, t, sxx = signal.spectrogram(filted_data, newfreq, nperseg=windows, noverlap=windows_overlaped)
- fw, Pwelch_spec = signal.welch(filted_data, newfreq, scaling='spectrum')
- return f, t, sxx, fw, Pwelch_spec
- # %%
- def get_spectrumall(names, ofc_ch, hpc_ch, windows, overlap, samples, newfreq, times, lowband, highband, savepath):
- channels = ofc_ch + hpc_ch
- for name in names:
- label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
- ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq
- start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq
- for i in channels:
- data = ampdata[trial_period_time[name][0]:trial_period_time[name][1], i]*0.195
- filted_data = prepocess(data, samples, newfreq, times, lowband, highband)
- # plt.plot(filted_data[:1000], c='y')
- # plt.show()
- # plt.close()
- f, t, sxx, fw, Pwelch_spec = cal_spec_epoch(filted_data, windows, overlap, newfreq)
- dbsxx = 10*np.log10(sxx)
- dbPwelch_spec = 10*np.log10(Pwelch_spec)
- gfdbsxx = gaussian_filter(dbsxx, K_size=3, sigma=1.2)
- powerpad = np.zeros((sxx.shape[0]+1, sxx.shape[1]+1))
- powerpad[0, 1:] = t
- powerpad[1:, 0] = f
- powerpad[1:, 1:] = sxx
- if i in ofc_ch:
- area = '_ofc'
- else:
- area = '_hpc'
- save_name = savepath+'/'+name+area+str(pin1)+'-'+str(pin)
- np.save(save_name+'_spec_ch.npy', np.asarray([fw, Pwelch_spec]))
- np.save(save_name+'_spower.npy', powerpad)
- sid = np.where(abs(f - pin1)<5)[0][0]
- eid = np.where(abs(f - pin)<5)[0][0]
- plt.figure(figsize=(15, 3))
- plt.pcolormesh(t, f[sid:eid], gfdbsxx[sid:eid, :], shading='gourand', cmap='jet')
- plt.colorbar()
- plt.xlabel("window time")
- plt.ylabel("frenqunce (Hz)")
- plt.title(name+'trial_'+str(i)+area+'_point')
- for et in ends_trial:
- plt.axvline(et, color='grey', linestyle=':', linewidth=2)
- plt.xticks(ends_trial, label_trial)
- plt.savefig(save_name+'_power.png')
- plt.show()
- plt.close()
- plt.semilogy(fw[sid:eid], dbPwelch_spec[sid:eid])
- plt.xlabel('frequency [Hz]')
- plt.ylabel('PSD')
- plt.grid()
- plt.title(name+'trial_'+str(i)+area+'_point')
- plt.savefig(save_name+'_spec.png')
- plt.show()
- plt.close()
- return ofc_ch, hpc_ch
- get_spectrumall(trial_learning, ch_ofc, ch_hpc, windows_hz, overlap, samples, newfreq, times, lowband, highband, specturm_save_path)
- # %%
- SWR_base = 'D:/tlw/SWR/'
- SWR_path = SWR_base + sessionname
- swr_start_session = np.load(SWR_path+'/swrstart.npy', allow_pickle=True).item()
- swr_spike_session = np.load(SWR_path+'/swrspike.npy', allow_pickle=True).item()
- # %%
- ### MI
- binnum = 36
- savename = ['theta-lg', 'theta-hg']
- def phase_amp(data, fs):
- analytical_signal = hilbert(data)
- amplitude_envelop = np.abs(analytical_signal)
- instantanous_phase = np.angle(analytical_signal)
- instantanous_frequency = (np.diff(instantanous_phase) / (2.0*np.pi) * fs)
- return amplitude_envelop, instantanous_phase, instantanous_frequency
- for name in trial_learning:
- swr_start = swr_start_session[name]
- label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
- ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
- start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
- data_ofc_trial = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc[0]] * 0.195
- data_hpc_trial = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc[0]] * 0.195
- data_ofc_lg = prepocess(data_ofc_trial, samples, newfreq, times, lowband_lowgamma, highband_lowgamma)
- data_ofc_hg = prepocess(data_ofc_trial, samples, newfreq, times, lowband_highgamma, highband_highgamma)
- data_hpc_theta = prepocess(data_hpc_trial, samples, newfreq, times, lowband_theta, highband_theta)
- results = np.zeros((2, len(label_trial)))
- for sessionid, l, s, e in zip(range(len(label_trial)), label_trial, start_trial, ends_trial):
- if e-s < 100:
- results[ig, sessionid] = 0
- continue
- lg_ofcamplitude_envelop, lg_ofcinstantanous_phase, lg_ofcinstantanous_frequency = phase_amp(data_ofc_lg[int(s):int(e)], newfreq)
- hg_ofcamplitude_envelop, hg_ofcinstantanous_phase, hg_ofcinstantanous_frequency = phase_amp(data_ofc_hg[int(s):int(e)], newfreq)
- hpcamplitude_envelop, hpcinstantanous_phase, hpcinstantanous_frequency = phase_amp(data_hpc_theta[int(s):int(e)], newfreq)
- hpcinstantanous_degree = hpcinstantanous_phase * 180 / np.pi
- try:
- swr_start_k = swr_start * newfreq
- for sk in swr_start_k:
- hpcamplitude_envelop[int(sk):int(sk)+newfreq*0.1] = -1
- hpcinstantanous_degree[int(sk):int(sk)+newfreq*0.1] = -1
- except:
- pass
- for ig, amplitude_envelop, sn in zip(range(2), [lg_ofcamplitude_envelop, hg_ofcamplitude_envelop], savename):
- bin = np.linspace(0, 360, binnum+1) -180
- p = np.zeros(binnum)
- for i in range(binnum):
- index = np.where((hpcinstantanous_degree >= bin[i]) & (hpcinstantanous_degree < bin[i+1]))
- p[i] = np.sum(amplitude_envelop[index])
- pi = p / np.sum(p)
- hmax = np.log2(binnum)
- h = - np.sum(pi * np.log2(pi))
- MI = (hmax - h) / hmax
- results[ig, sessionid] = MI
- figpath = mi_save_path+'/'+name+'-'+str(ch_ofc[0])+'-'+str(ch_hpc[0])
- with pd.ExcelWriter(mi_save_path + '/' + name + '_ch' + str(ch_ofc[0]) + '-with-ch' + str(ch_hpc[0]) + '_MI.xlsx') as writer:
- df = pd.DataFrame(results, columns=label_trial)
- df.to_excel(writer, index=False)
- # %%
- ## PLV
- 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
- n_m = [[1,1], [1,15],[1,25],[1,1],[1,1],[1,10]]
- bandname = ['-theta_theta-', '-theta_lg-', '-theta_hg-', '-lg_lg-', '-hg_hg-', '-lg_hg-']
- def PLV(data, n, m):
- return np.abs(np.sum(np.exp(1j*(m*data[:, 0]-n*data[:, 1]))))/len(data[:, 0])
- for name in trial_learning:
- label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
- ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
- start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
- data_ofc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc[0]] * 0.195
- data_hpc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc[0]] * 0.195
- for lfp, nm, saven in zip(lfpband, n_m, bandname):
- data_ofc_trial = prepocess(data_ofc_trials, samples, newfreq, times, lfp[0][0], lfp[0][1])
- data_hpc_trial = prepocess(data_hpc_trials, samples, newfreq, times, lfp[1][0], lfp[1][1])
- result = dict()
- for l, s, e in zip(label_trial, start_trial, ends_trial):
- plv = np.zeros(nm[1])
- if e-s > 100:
- dataputin = np.stack([data_ofc_trial[int(s):int(e)], data_hpc_trial[int(s):int(e)]], axis=1) #
- complex_series = hilbert(dataputin, axis=0)
- phase = np.angle(complex_series)
- try:
- swr_start_k = swr_start * newfreq
- for sk in swr_start_k:
- phase[int(sk):int(sk)+newfreq*0.1] = 0
- except:
- pass
- for mi in range(0, nm[1]):
- plv[mi] = PLV(phase, 1, mi+1)
- result[l] = plv
- with pd.ExcelWriter(plv_save_path + '/' + name + saven + '_ch' + str(ch_ofc[0]) + '-with-ch' + str(ch_hpc[0]) + '_PLV.xlsx') as writer:
- for i, bn in enumerate(label_trial):
- df = pd.DataFrame(result[bn], columns=[bn])
- df.to_excel(writer, startcol=i, index=False)
- # %%
- ### Save amp and phase
- lfpband = [[4,12], [30, 60], [60, 90]]
- bandname = ['-theta-', '-lg-', '-hg-']
- for name in trial_learning:
- label_trial = np.load(through_times_path+'/'+name+'-label_all.npy')
- ends_trial = np.load(through_times_path+'/'+name+'-end_all.npy') / vediofreq * newfreq
- start_trial = np.load(through_times_path+'/'+name+'-start_all.npy') / vediofreq * newfreq
- data_ofc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_ofc_invariance] * 0.195
- data_hpc_trials = ampdata[trial_period_time[name][0]:trial_period_time[name][1], ch_hpc_invariance] * 0.195
- for lfp, saven in zip(lfpband, bandname):
- data_ofc_trial = prepocess(data_ofc_trials, samples, newfreq, times, lfp[0], lfp[1])
- data_hpc_trial = prepocess(data_hpc_trials, samples, newfreq, times, lfp[0], lfp[1])
- ofc_amps = []
- ofc_phas = []
- hpc_amps = []
- hpc_phas = []
- for l, s, e in zip(label_trial, start_trial, ends_trial):
- if e-s < 100:
- ofc_amps.append([0])
- ofc_phas.append([0])
- hpc_amps.append([0])
- hpc_phas.append([0])
- else:
- complex_series_ofc = hilbert(data_ofc_trial[int(s):int(e)], axis=0)
- amplitude_envelop_ofc = np.abs(complex_series_ofc)
- instantanous_phase_ofc = np.angle(complex_series_ofc)
- ofc_amps.append(amplitude_envelop_ofc)
- ofc_phas.append(instantanous_phase_ofc)
- complex_series_hpc = hilbert(data_hpc_trial[int(s):int(e)], axis=0)
- amplitude_envelop_hpc = np.abs(complex_series_hpc)
- instantanous_phase_hpc = np.angle(complex_series_hpc)
- hpc_amps.append(amplitude_envelop_hpc)
- hpc_phas.append(instantanous_phase_hpc)
- with pd.ExcelWriter(specturm_save_path+'/'+name + saven + 'ofc.xlsx') as writer:
- for ii, ll in enumerate(label_trial):
- ofcampdf = pd.DataFrame(ofc_amps[ii], columns=[ll])
- ofcampdf.to_excel(writer, index=False, startcol=ii, sheet_name='envelop')
- ofcphadf = pd.DataFrame(ofc_phas[ii], columns=[ll])
- ofcphadf.to_excel(writer, index=False, startcol=ii, sheet_name='phase')
- with pd.ExcelWriter(specturm_save_path+'/'+name + saven + 'hpc.xlsx') as writer:
- for i, l in enumerate(label_trial):
- hpcampdf = pd.DataFrame(hpc_amps[i], columns=[l])
- hpcampdf.to_excel(writer, index=False, startcol=i, sheet_name='envelop')
- hpcphadf = pd.DataFrame(hpc_phas[i], columns=[l])
- hpcphadf.to_excel(writer, index=False, startcol=i, sheet_name='phase')
- # %%
- ### theta cycle
- def peak_minma(data, times):
- # Peak detection
- peak_ind, _ = signal.find_peaks(data)
- # Trough detection
- minima_ind = signal.argrelextrema(data, np.less)
- minima_ind = minima_ind[0]
- return peak_ind, minima_ind
- def smooth(data):
- k = np.asarray([0.05, 0.10, 0.70, 0.10, 0.05])
- pad_data = np.insert(data, 0, [0, 0])
- pad_data = np.append(pad_data, [0, 0])
- temp_data = np.zeros_like(data)
- for i in range(2, len(pad_data)-3):
- temp_data[i-2] = np.sum(pad_data[i-2:i+3] * k)
- return temp_data
- def get_theta_arfa_ratio(name, downrate, represent):
- eeg_data = ampdata[trial_period_time[name][0]:trial_period_time[name][1], represent]*0.195
- # Select theta from one tetrode for coupling analysis 6
- data = resample(eeg_data, amplitudefreq, downrate)
- data = butterfilt(data, downrate, 1, 30, 4)
- times = np.arange(len(data)) / downrate
- period = np.zeros_like(data)
- windows = math.floor(downrate/1)
- windows_overlaped = math.floor(windows*0.9)
- f, t, sxx = signal.spectrogram(data, downrate, nperseg=windows, noverlap=windows_overlaped) #, nperseg=200, noverlap=50
- arfaband = [1,4]
- thetaband = [4,12]
- arfaid = np.where((f>=arfaband[0]) & (f<=arfaband[1]))[0]
- thetaid = np.where((f>[thetaband[0]]) & (f<=[thetaband[1]]))
- arfapower = np.sum(sxx[arfaid], axis=0)
- thetapower = np.sum(sxx[thetaid], axis=0)
- thetaperiodid = np.where(thetapower >= 2*arfapower)[0]
- continueid = np.where((thetaperiodid[1:] - thetaperiodid[:-1]) > 1)[0]
- periodstart = t[np.append(np.asarray([thetaperiodid[0]]),thetaperiodid[1:][continueid])]
- periodend = t[np.append(thetaperiodid[:-1][continueid],np.asarray([thetaperiodid[-1]]))]
- for pp in range(len(periodstart)):
- period[int(periodstart[pp]*downrate):int(periodend[pp]*downrate)] = 1
- return data, times, period
- # %%
- def get_theta_(name, downrate, savepath, samples, vediof, represent): #, datpath
- data, times, thetaperiod = get_theta_arfa_ratio(name, downrate, represent)
- inter = samples // downrate
- veloc = np.load(veloc_direction_path+'/'+name+'-veloc.npy')
- #Points with speed below 4 are excluded from theta extraction
- interval = downrate // vediof
- avail_ = np.array(veloc >= 4)
- avail_point = np.tile(avail_, (interval, 1))
- avail_point = avail_point.flatten('F')
- if len(data)>len(avail_point):
- data = data[:len(avail_point)]
- thetaperiod = thetaperiod[:len(avail_point)]
- times = times[:len(avail_point)]
- elif len(data)<len(avail_point):
- avail_point = avail_point[:len(data)]
- peak_ind, minima_ind = peak_minma(data, times)
- ind_array = np.zeros(len(data))
- ind_array[peak_ind] = 1
- ind_array[minima_ind] = -1
- avail_ind = ind_array * avail_point * thetaperiod
- #Segment theta
- theta_start = []
- theta_peak = []
- theta_end = []
- pointer = np.argmax(avail_ind==-1)
- while pointer < len(data)-60:
- if (pointer != len(data)) & (avail_ind[pointer] == -1):
- temp_start = pointer
- pointer += 1
- while (pointer != len(data)-1) & (avail_ind[pointer] == 0):
- pointer += 1
- if (avail_ind[pointer] == 1) & (pointer != len(data)-1):
- temp_peak = pointer
- pointer += 1
- while (pointer != len(data)-1) & (avail_ind[pointer] == 0):
- pointer += 1
- if avail_ind[pointer] == -1:
- temp_end = pointer
- if (temp_end - temp_start > 60) or (temp_end - temp_start < 20):
- continue
- else:
- ### Check amplitude; theta amplitude 100-150
- # plt.plot(data[temp_start:temp_end])
- # plt.show()
- if data[temp_peak] > 80:
- theta_start.append(temp_start)
- theta_peak.append(temp_peak)
- theta_end.append(temp_end)
- # plt.plot(data[temp_start-2:temp_end+2])
- # plt.plot(temp_peak-temp_start+3, data[temp_peak],"*")
- # plt.savefig('t')
- # plt.close()
- print(pointer, len(data))
- continue
- pointer += 1
- theta_peak = np.asarray(theta_peak)*inter
- theta_start = np.asarray(theta_start)*inter
- theta_end = np.asarray(theta_end)*inter
- np.save(savepath+'/'+'theta_peak.npy', theta_peak) ## theta_peak_ofc
- np.save(savepath+'/'+'theta_start.npy', theta_start)
- np.save(savepath+'/'+'theta_end.npy', theta_end)
- return theta_start, theta_peak, theta_end
- represent = 14
- for i, name in enumerate(trial_learning):
- savepathi = thetacycle_save_path + '/' + name
- mkdir(savepathi)
- theta_start, theta_peak, theta_end = get_theta_(name, newfreq, savepathi, samples, vediofreq, represent)
specturm_PLV_MI.ipynb, no license · at the source
Overview
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
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
- 28 September 2026: the link answers (HTTP 200)
19 files
- code/
RNN/ , Python, 467 linesparameters.py - code/
RNN/ , Jupyter, 540 linessynaptic_network.ipynb - code/
RNN/ , Jupyter, 558 linessynaptic_network_remap.i pynb - code/
RNN/ , Jupyter, 508 lineswithout_synaptic_network .ipynb - code/
RNN/ , Jupyter, 508 lineswithoutconnect_network.i pynb - code/
SWR.ipynb , Jupyter, 627 lines, 2 matches - code/
assemble_withoutswr.ipyn , Jupyter, 527 lines, 1 matchb - code/
check_dlc.ipynb , Jupyter, 113 lines - code/
coupling_thetastage.ipyn , Jupyter, 450 linesb - code/
decoding.ipynb , Jupyter, 475 lines, 2 matches - code/
merge_ampdata.ipynb , Jupyter, 61 lines - code/
old_new_transimition_UPG , Jupyter, 1,286 lines, 4 matchesRADED.ipynb - code/
spatial_goal_distance.ip , Jupyter, 359 linesynb - code/
spatial_rate_map.ipynb , Jupyter, 321 lines, 1 match - code/
spatial_relate.ipynb , Jupyter, 323 lines - code/
specturm_PLV_MI.ipynb , Jupyter, 651 lines, 5 matches - code/
stage_time.ipynb , Jupyter, 216 lines - code/
veloc_dirc_goal_modelati , Jupyter, 246 lineson.ipynb - code/
veloc_direction.ipynb , Jupyter, 215 lines
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://
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://
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/
url = {https://
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/
VL - 24
IS - 5
SP - e3003824
SN - 1544-9173
PB - PLOS
DO - 10.1371/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1371/
"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":
"volume": "24",
"issue": "5",
"page": "e3003824",
"DOI": "10.1371/
"PMID": "42213668",
"PMCID": "PMC13221071",
"ISSN": "1544-9173",
"publisher": "PLOS",
"URL": "https://
"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: HippocampusIn 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 communicationsIn 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 neuroscienceIn 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 neuroscienceIn common: scikit-learn, pandas, SciPy, 2 other tools, 4 references
- [5] doi:10.1038/s41593-026-02232-0 [code]
- Entorhinal cortex represents task-relevant remote locations independently of CA1.Journal: Nature neuroscienceIn common: OpenCV, Pillow, PyTorch, 5 other tools, systems, 1 reference
- [6] doi:10.3389/fnsys.2026.1822122 [code]
- Convergence-divergence circuits for multimodal integration of innate and learned opponent valences.Journal: Frontiers in systems neuroscienceIn common: Plotly, Pillow, PyTorch, 5 other tools, systems, 1 reference
- [7] 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 AmericaIn common: scikit-learn, pandas, SciPy, 2 other tools, systems, 4 references
- [8] doi:10.1016/j.isci.2026.116825 [code]
- Social hierarchy shapes behavioral and transcriptional responses to chronic stress and ketamine in male mice.Journal: iScienceIn common: Plotly, OpenCV, Pillow, 6 other tools, systems
- [9] doi:10.1093/sleep/zsag168 [code]
- Deltas' and spindles' cross-area synchronization and ripple subtypes.Journal: SleepIn common: Plotly, scikit-learn, SciPy, 2 other tools, rat, 3 references
- [10] doi:10.1016/j.celrep.2026.117646 [code]
- Medial entorhinal-hippocampal desynchronization parallels the emergence of memory impairment in a mouse model of Alzheimer's disease pathology.Journal: Cell reportsIn common: OpenCV, pandas, SciPy, 2 other tools, systems, 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.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 19 scripts, and 15 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:271f5e8dfd6be24c…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[.
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.
