[noisesplit] added 1% simulation

This commit is contained in:
Jan Benda 2025-05-17 23:39:33 +02:00
parent b16e4dea86
commit 7a451a82fa
2 changed files with 46 additions and 34 deletions

View File

@ -102,8 +102,9 @@ def plot_overn(ax, s, files, nmax=1e6):
ax.set_xticks_log(numticks=4)
ax.set_minor_xticks_log(numticks=8)
else:
ax.set_ylim(1e0, 1.3e3)
ax.set_ylim(4e0, 1.3e3)
#ax.set_minor_yticks_log(numticks=5)
ax.set_minor_yticks_off()
ax.set_xticks_log(numticks=5)
#ax.set_minor_xticks_log(numticks=6)
ax.set_xlabel('segments')
@ -218,73 +219,86 @@ def plot_noise_split(ax, contrast, noise_contrast, noise_frac,
axn.text(1, y, f'Intrinsic noise (${100*noise_frac:.0f}$\\,\\%)',
ha='right', transform=axn.transAxes, color=s.lsNoise['color'])
if noise_frac < 1:
axn.xscalebar(1, 0, 10, 'ms', ha='right')
axn.xscalebar(1, -0.1, 10, 'ms', ha='right')
return axr
if __name__ == '__main__':
#cell_name = ['2012-07-03-ak-invivo-1', 0]
cell_name = ['2017-07-18-ai-invivo-1', 1] # Take this! at 3% model, 5% data
nsmall = 100
nlarge = 1000000
contrast = 0.05
contrast = 0.01
wdt = 0.0001
wnoise = whitenoise(0, 300, wdt, 0.05, rng=np.random.default_rng(51234))
wtime = np.arange(len(wnoise))*wdt
s = plot_style()
fig, axs = plt.subplots(3, 4, cmsize=(s.plot_width, 0.7*s.plot_width),
fig, axs = plt.subplots(4, 4, cmsize=(s.plot_width, 0.83*s.plot_width),
width_ratios=[1, 0, 1, 1, 0.15, 1])
fig.subplots_adjust(leftm=8, rightm=1.5, topm=4, bottomm=4,
wspace=0.25, hspace=0.8)
fig.subplots_adjust(leftm=8, rightm=1.5, topm=3.5, bottomm=4,
wspace=0.25, hspace=0.6)
axs[0, 2].set_visible(False)
axs[0, 3].set_visible(False)
xt = -2.2
yt = 1.3
xt = -2.25
yt = 1.25
# data:
axs[0, 1].text(xt, yt, 'P-unit data', fontsize='large',
transform=axs[0, 1].transAxes, color=s.punit_color1)
data_contrast, ratebase, eodf = plot_chi2_data(axs[0, 1], s, cell_name[0],
axss = axs[0]
axss[1].text(xt, yt, 'P-unit data', fontsize='large',
transform=axss[1].transAxes, color=s.punit_color1)
data_contrast, ratebase, eodf = plot_chi2_data(axss[1], s, cell_name[0],
cell_name[1])
plot_ram(axs[0, 0], data_contrast, eodf, wtime, wnoise)
axs[0, 1].text(xt + 0.9, yt, f'$r={ratebase:.0f}$\\,Hz',
transform=axs[0, 1].transAxes, fontsize='large')
plot_ram(axss[0], data_contrast, eodf, wtime, wnoise)
axss[1].text(xt + 0.9, yt, f'$r={ratebase:.0f}$\\,Hz',
transform=axss[1].transAxes, fontsize='large')
# model:
# model 5%:
axss = axs[1]
data_files = sims_path.glob(f'chi2-noisen-{cell_name[0]}-{1000*data_contrast:03.0f}-*.npz')
files, nums = sort_files(cell_name[0], data_files, 2)
axss[1].text(xt, yt, 'P-unit model', fontsize='large',
transform=axs[1, 1].transAxes, color=s.model_color1)
plot_chi2_contrast(axss[1], axss[2], s, files, nums, nsmall, nlarge)
axr1 = plot_noise_split(axss[0], data_contrast, 0, 1, wtime, wnoise)
plot_overn(axss[3], s, files, nmax=1e6)
axss[3].legend(loc='lower center', bbox_to_anchor=(0.5, 1.2),
markerfirst=False, title='$|\\chi_2|$ percentiles')
# model 1%:
axss = axs[2]
data_files = sims_path.glob(f'chi2-noisen-{cell_name[0]}-{1000*contrast:03.0f}-*.npz')
files, nums = sort_files(cell_name[0], data_files, 2)
axs[1, 1].text(xt, yt, 'P-unit model', fontsize='large',
transform=axs[1, 1].transAxes, color=s.model_color1)
plot_chi2_contrast(axs[1, 1], axs[1, 2], s, files, nums, nsmall, nlarge)
axr1 = plot_noise_split(axs[1, 0], contrast, 0, 1, wtime, wnoise)
plot_overn(axs[1, 3], s, files, nmax=1e6)
axs[1, 3].legend(loc='lower center', bbox_to_anchor=(0.5, 1.1),
markerfirst=False, title='$|\\chi_2|$ percentiles')
plot_chi2_contrast(axss[1], axss[2], s, files, nums, nsmall, nlarge)
axr2 = plot_noise_split(axss[0], contrast, 0, 1, wtime, wnoise)
plot_overn(axss[3], s, files, nmax=1e6)
# model noise split:
axss = axs[3]
data_files = sims_path.glob(f'chi2-split-{cell_name[0]}-*.npz')
files, nums = sort_files(cell_name[0], data_files, 1)
axs[2, 1].text(xt, yt, 'P-unit model', fontsize='large',
transform=axs[2, 1].transAxes, color=s.model_color1)
axs[2, 1].text(xt + 0.9, yt, f'(noise split)', fontsize='large',
transform=axs[2, 1].transAxes)
noise_contrast, noise_frac = plot_chi2_split(axs[2, 1], axs[2, 2], s,
axss[1].text(xt, yt, 'P-unit model', fontsize='large',
transform=axss[1].transAxes, color=s.model_color1)
axss[1].text(xt + 0.9, yt, f'(noise split)', fontsize='large',
transform=axss[1].transAxes)
noise_contrast, noise_frac = plot_chi2_split(axss[1], axss[2], s,
files, nums, nsmall, nlarge)
axr2 = plot_noise_split(axs[2, 0], 0, noise_contrast, noise_frac,
axr3 = plot_noise_split(axss[0], 0, noise_contrast, noise_frac,
wtime, wnoise)
plot_overn(axs[2, 3], s, files, nmax=1e6)
plot_overn(axss[3], s, files, nmax=1e6)
fig.common_xticks(axs[:, 1])
fig.common_xticks(axs[:, 2])
fig.common_xticks(axs[:, 3])
fig.common_yticks(axs[1, 1:3])
fig.common_yticks(axs[2, 1:3])
fig.common_yticks(axs[3, 1:3])
fig.tag([axs[0, :2],
[axr1] + axs[1, 1:].tolist(),
[axr2] + axs[2, 1:].tolist()],
[axr2] + axs[2, 1:].tolist(),
[axr3] + axs[3, 1:].tolist()],
xoffs=[-4.5, 1, 1, -4.5], yoffs=2)
fig.savefig()
print()

View File

@ -494,10 +494,8 @@ Electric fish possess an additional electrosensory system, the passive or ampull
\subsection{Model-based estimation of the second-order susceptibility}
In the example recordings shown above (\figsrefb{fig:punit} and \fref{fig:ampullary}), we only observe nonlinear responses on the anti-diagonal of the second-order susceptibility, where the sum of the two stimulus frequencies matches the neuron's baseline firing rate, which is in line with theoretical expectations \citep{Voronenko2017,Franzen2023}. However, a pronounced nonlinear response at frequencies \foneb{} or \ftwob{}, although predicted by theory, cannot be observed. In the following, we investigate how these discrepancies can be understood.
\begin{figure*}[t]
\begin{figure*}[p]
\includegraphics[width=\columnwidth]{noisesplit}
\notejb{This model in the next figure shows a triangle for 3\% contrast ...}
\notejb{We cannot really make up this twist with the 3\% contrast not converging into a triangle.}
\caption{\label{fig:noisesplit} Estimation of second-order susceptibilities in the limit of weak stimuli. \figitem{A} \suscept{} estimated from $N=11$ 0.5\,s long segments of an electrophysiological recording of another low-CV P-unit (cell 2012-07-03-ak, $\fbase=120$\,Hz, CV=0.20) driven with a weak RAM stimulus with contrast 2.5\,\%. Pink edges mark the baseline firing rate where enhanced nonlinear responses are expected. \figitem[i]{B} \textit{Standard condition} of model simulations with intrinsic noise (bottom) and a RAM stimulus (top). \figitem[ii]{B} \suscept{} estimated from simulations of the cell's LIF model counterpart (cell 2012-07-03-ak, table~\ref{modelparams}) based on the same number of FFT segments $N=11$ as in the electrophysiological recording. \figitem[iii]{B} Same as \panel[ii]{B} but using $10^6$ segments. \figitem[i-iii]{C} Same as in \panel[i-iii]{B} but in the \textit{noise split} condition: there is no external RAM signal driving the model. Instead, a large part (90\,\%) of the total intrinsic noise is treated as a signal and is presented as an equivalent amplitude modulation (\signalnoise, center), while the intrinsic noise is reduced to 10\,\% of its original strength (see methods for details). Simulating one million segments, this reveals the full expected trangular structure of the second-order susceptibility.}
\end{figure*}