def test_fit_neuron(img_dim, n_t, n_neu, seed): np.random.seed(seed) rfs = np.repeat(np.zeros(img_dim)[np.newaxis, :], n_neu, axis=0) for i in range(n_neu): a, b = np.random.randint(0, max(img_dim)), np.random.randint(0, max(img_dim)) r = np.random.randint(1, round(max(img_dim))) y, x = np.ogrid[-a:img_dim[0] - a, -b:img_dim[1] - b] mask = x * x + y * y <= r * r rfs[i, mask] = 1 imgs = np.random.rand(n_t, *img_dim) X = imgs.reshape([n_t, -1]) β = rfs.reshape([n_neu, -1]) for i in range(n_neu): # Prevent all 0s. β[i, np.random.randint(3, img_dim[0] * img_dim[1])] = 1 spks = X @ β.T spks += 0.01 * np.mean(spks) * np.random.normal(size=spks.shape) x = ReceptiveField(img_dim) x.fit_neuron(X, spks) print(np.corrcoef(x.rf_.flatten(), β.flatten())[0, 1]) assert np.corrcoef(x.rf_.flatten(), β.flatten())[0, 1] > 0.95
def test_regression_canonical_ridge(): loader = SpikeLoader.from_hdf5('tests/data/processed.hdf5') V1, V2 = loader.S[:, loader.pos['y'] >= 210], loader.S[:, loader.pos['y'] < 210] cca = CanonicalRidge().fit(V1, V2) V1s, V2s = cca.subtract_canon_comp(V1, V2) rf_v1 = ReceptiveField(loader.img_dim).fit_pc(loader.imgs_stim, V1s) rf_v2 = ReceptiveField(loader.img_dim).fit_pc(loader.imgs_stim, V2s) gnd = hdf5_load('tests/data/regression_test_data.hdf5', 'CanonicalRidge', arrs=['V1', 'V2']) assert np.mean((rf_v1.rf_ - gnd['V1']) / gnd['V1']) < 0.05 assert np.mean((rf_v2.rf_ - gnd['V2']) / gnd['V2']) < 0.05
def test_fit_regression(): loader = SpikeLoader.from_hdf5('tests/data/test_data.hdf5') gnd = hdf5_load('tests/data/test_data.hdf5', 'ReceptiveField', arrs=['neu', 'pc']) rf = ReceptiveField(loader.img_dim) rf.fit_neuron(loader.imgs_stim, loader.S) assert np.allclose(gnd['neu'], rf.rf_, atol=1e-4, rtol=1e-2) rf.fit_pc(loader.imgs_stim, loader.S) assert np.allclose(gnd['pc'], rf.rf_, atol=1e-4, rtol=1e-2)
def animate(i): if i % 5 == 0: print(i) im.set_data(test[i]) im.set_clim(u := -np.max(np.abs(test[i])), -u) ax.set_title(f'Neuron 11666. Step {i}.') return [im] # call the animator. blit=True means only re-draw the parts that have changed. anim = FuncAnimation(fig, animate, frames=30, blit=True) anim.save(f'test.mp4', fps=fps, extra_args=['-vcodec', 'libx264']) #%% f = SpikeLoader.from_hdf5() rf = ReceptiveField(f.img_dim) rf.fit_neuron(f.imgs_stim, f.S) #%% from src.receptive_field.rf import gen_rf_rank rf = gen_rf_rank(rf.rf_, n_pc=30) #%% choose = rf[11666, ...] x = GaborFit(n_iter=500, n_pc=0, optimizer={ 'name': 'adam', 'step_size': 2e-2 }).fit(choose[np.newaxis, ...]) y = np.array(x.params_fit).squeeze() z = GaborFit._make_gabor((16, 9), y)
import seaborn as sns from IPython import get_ipython from src.gabor_analysis.gabor_fit import GaborFit from src.receptive_field.rf import ReceptiveField from src.spikeloader import SpikeLoader from src.utils.plots import gabor_interactive get_ipython().run_line_magic("matplotlib", "inline") get_ipython().run_line_magic("config", "InlineBackend.figure_format='retina'") sns.set() # %% tags=["parameters"] path_loader = "data/superstim_TX60_allsort.hdf5" path_rf = "data/superstim_TX60_allsort.hdf5" path_gabor = "data/superstim_TX60_allsort_gabor.hdf5" # %% f = SpikeLoader.from_hdf5(path_loader) rf = ReceptiveField.from_hdf5(path_rf) g = GaborFit.from_hdf5(path_gabor) # %% g.plot_params(f.pos) # %% [markdown] # ## Interactive Plot # %% alt.renderers.enable("mimetype") gabor_interactive(f, g, n_samples=500)
def test_reshape_rf(img_dim, n): x = np.random.rand(n, *img_dim) coef = x.reshape([n, -1]).T assert np.allclose(ReceptiveField.reshape_rf(coef, img_dim, smooth=0), x)
# %% [markdown] """ # Ridge Regression for Receptive Field $\underbrace{Y}_{t×n} = \underbrace{X}_{t×px} \underbrace{β}_{px×n}$ where - $t$: number of time points - $n$: number of neurons - $px$: number of pixels in each image (stimulus) Solve for $\hat{β}$ where $\hat{β} = \arg\min_β ||Y-Xβ||_2 + λ||β||_2$. """ # %% loader = SpikeLoader.from_hdf5(path_loader) rf = ReceptiveField(loader.img_dim, lamda=1.1) rf.fit_neuron(loader.imgs_stim, loader.S) rf.plot() rf.save_append(path_loader, overwrite_group=True) # %% [markdown] """ ### Denoise We use PCA to denoise the RFs. However, the location of the RFs vary across the visual cortex and linear models are not translation and rotation-invariant. Therefore, we split the visual cortex into blocks and perform PCA separately for each block. """ # %% from pathlib import Path import numpy as np rf_pcaed = gen_rf_rank_regional(loader, rf, xy_div=(5, 3), plot=True)