mark example cells in dataoverview
This commit is contained in:
parent
f1883a834b
commit
21fb68d81b
6
Makefile
6
Makefile
@ -9,7 +9,7 @@ TXTFILE=$(TEXBASE).txt
|
||||
PDFFIGURES=$(shell sed -n -e '/^[^%].*includegraphics/{s/^.*includegraphics.*{\([^}]*\)}.*/\1.pdf/;p}' $(TEXFILE))
|
||||
|
||||
PT=$(wildcard *.py)
|
||||
PYTHONFILES=$(filter-out plotstyle.py, $(PT))
|
||||
PYTHONFILES=$(filter-out plotstyle.py spectral.py, $(PT))
|
||||
PYTHONPDFFILES=$(PYTHONFILES:.py=.pdf)
|
||||
|
||||
REVISION=e3814a1be539f9424c17b7bd7ef45a8826a9f1e2
|
||||
@ -38,7 +38,7 @@ watchplots :
|
||||
|
||||
# compile manuscript #################################################
|
||||
bib: $(TEXBASE).bbl
|
||||
$(TEXBASE).bbl: $(TEXFILE) $(BIBFILE)
|
||||
$(TEXBASE).bbl: $(TEXFILE) $(BIBFILE) $(PYTHONPDFFILES) plotstyle.py
|
||||
lualatex $(TEXFILE)
|
||||
bibtex $(TEXBASE)
|
||||
lualatex $(TEXFILE)
|
||||
@ -49,7 +49,7 @@ $(TEXBASE).bbl: $(TEXFILE) $(BIBFILE)
|
||||
@sed -n -e '1,/You.ve used/p' $(TEXBASE).blg
|
||||
|
||||
pdf: $(PDFFILE)
|
||||
$(PDFFILE) : $(TEXFILE)
|
||||
$(PDFFILE) : $(TEXFILE) $(PYTHONPDFFILES) plotstyle.py
|
||||
lualatex -interaction=scrollmode $< | tee /dev/stderr | fgrep -q "Rerun to get cross-references right" && lualatex -interaction=scrollmode $< || true
|
||||
|
||||
again :
|
||||
|
@ -40,8 +40,8 @@ def plot_response_spectrum(ax, s, eodf, rate, freqs, prr):
|
||||
ax.show_spines('b')
|
||||
mask = (freqs > 30) & (freqs < 890)
|
||||
ax.plot(freqs[mask], power_db[mask], **s.lsC1)
|
||||
ax.plot(freqs[eod_i], power_db[eod_i], **s.psA1c)
|
||||
ax.plot(freqs[rate_i], power_db[rate_i], **s.psA2c)
|
||||
ax.plot(freqs[eod_i], power_db[eod_i], **s.psFEOD)
|
||||
ax.plot(freqs[rate_i], power_db[rate_i], **s.psF0)
|
||||
ax.set_xlim(0, 900)
|
||||
ax.set_ylim(-25, 5)
|
||||
ax.set_xticks_delta(300)
|
||||
|
@ -10,8 +10,16 @@ from plotstyle import plot_style, lighter, significance_str
|
||||
data_path = Path('data')
|
||||
|
||||
|
||||
punit_example = [['2020-10-27-ag-invivo-1', 0],
|
||||
['2020-10-27-ag-invivo-1', 1]]
|
||||
ampul_example = [['2012-05-15-ac', 3],
|
||||
['2012-05-15-ac', 1]]
|
||||
from punitexamplecell import example_cells as punit_examples
|
||||
from ampullaryexamplecell import example_cells as ampul_examples
|
||||
|
||||
|
||||
def plot_corr(ax, data, xcol, ycol, zcol, zmin, zmax, xpdfmax, cmap, color,
|
||||
nli_thresh):
|
||||
nli_thresh, example=[], examples=[]):
|
||||
ax.axhline(nli_thresh, color='k', ls=':', lw=0.5)
|
||||
"""
|
||||
for c in np.unique(data('cell')):
|
||||
@ -26,7 +34,21 @@ def plot_corr(ax, data, xcol, ycol, zcol, zmin, zmax, xpdfmax, cmap, color,
|
||||
ymax = ax.get_ylim()[1]
|
||||
mask = (data(xcol) < xmax) & (data(ycol) < ymax)
|
||||
sc = ax.scatter(data[mask, xcol], data[mask, ycol], c=data[mask, zcol],
|
||||
s=3, clip_on=False, cmap=cmap, vmin=zmin, vmax=zmax, zorder=20)
|
||||
s=4, marker='o', linewidth=0, edgecolors='none',
|
||||
clip_on=False, cmap=cmap, vmin=zmin, vmax=zmax, zorder=20)
|
||||
if 'stimindex' in data:
|
||||
for cell, run in example:
|
||||
mask = (data('cell') == cell) & (data('stimindex') == run)
|
||||
ax.scatter(data[mask, xcol], data[mask, ycol], c=data[mask, zcol],
|
||||
s=6, marker='^', linewidth=0.5, edgecolors='black',
|
||||
clip_on=False, cmap=cmap, vmin=zmin, vmax=zmax,
|
||||
zorder=20)
|
||||
for cell, run in examples:
|
||||
mask = (data('cell') == cell) & (data('stimindex') == run)
|
||||
ax.scatter(data[mask, xcol], data[mask, ycol], c=data[mask, zcol],
|
||||
s=5, marker='o', linewidth=0.5, edgecolors='black',
|
||||
clip_on=False, cmap=cmap, vmin=zmin, vmax=zmax,
|
||||
zorder=20)
|
||||
# color bar:
|
||||
fig = ax.get_figure()
|
||||
cax = ax.inset_axes([1.3, 0, 0.04, 1])
|
||||
@ -91,10 +113,11 @@ def plot_cvbase_nli_punit(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xlabel('CV$_{\\rm base}$')
|
||||
ax.set_ylabel('SI($r$)')
|
||||
ax.set_xlim(0, 1.5)
|
||||
ax.set_ylim(0, 6)
|
||||
ax.set_ylim(0, 7.2)
|
||||
ax.set_yticks_delta(2)
|
||||
cax = plot_corr(ax, data, 'cvbase', ycol, 'respmod2', 0, 250, 3,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
punit_example, punit_examples)
|
||||
cax.set_ylabel('Response mod.', 'Hz')
|
||||
|
||||
|
||||
@ -102,17 +125,20 @@ def plot_cvstim_nli_punit(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xlabel('CV$_{\\rm stim}$')
|
||||
ax.set_ylabel('SI($r$)')
|
||||
ax.set_xlim(0, 1.6)
|
||||
ax.set_ylim(0, 6)
|
||||
ax.set_ylim(0, 7.2)
|
||||
ax.set_xticks_delta(0.5)
|
||||
ax.set_yticks_delta(2)
|
||||
#cax = plot_corr(ax, data, 'cvstim', ycol, 'respmod2', 0, 250, 2,
|
||||
# 'coolwarm', color, nli_thresh)
|
||||
# 'coolwarm', color, nli_thresh,
|
||||
# punit_example, punit_examples)
|
||||
#cax.set_ylabel('Response mod.', 'Hz')
|
||||
#cax = plot_corr(ax, data, 'cvstim', ycol, 'cvbase', 0, 1.5, 2,
|
||||
# 'coolwarm', color, nli_thresh)
|
||||
# 'coolwarm', color, nli_thresh,
|
||||
# punit_example, punit_examples)
|
||||
#cax.set_ylabel('CV$_{\\rm base}$')
|
||||
cax = plot_corr(ax, data, 'cvstim', ycol, 'ratebase', 50, 450, 2,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
punit_example, punit_examples)
|
||||
cax.set_ylabel('$r$', 'Hz')
|
||||
|
||||
|
||||
@ -120,10 +146,11 @@ def plot_mod_nli_punit(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xlabel('Response modulation', 'Hz')
|
||||
ax.set_ylabel('SI($r$)')
|
||||
ax.set_xlim(0, 250)
|
||||
ax.set_ylim(0, 6)
|
||||
ax.set_ylim(0, 7.2)
|
||||
ax.set_yticks_delta(2)
|
||||
cax = plot_corr(ax, data, 'respmod2', ycol, 'cvbase', 0, 1.5, 0.016,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
punit_example, punit_examples)
|
||||
cax.set_ylabel('CV$_{\\rm base}$')
|
||||
|
||||
|
||||
@ -135,7 +162,8 @@ def plot_cvbase_nli_ampul(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xticks_delta(0.1)
|
||||
ax.set_yticks_delta(5)
|
||||
cax = plot_corr(ax, data, 'cvbase', ycol, 'respmod2', 0, 80, 20,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
ampul_example, ampul_examples)
|
||||
cax.set_ylabel('Response mod.', 'Hz')
|
||||
|
||||
|
||||
@ -147,14 +175,17 @@ def plot_cvstim_nli_ampul(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xticks_delta(0.2)
|
||||
ax.set_yticks_delta(5)
|
||||
#cax = plot_corr(ax, data, 'cvstim', ycol, 'respmod2', 0, 80, 6,
|
||||
# 'coolwarm', color, nli_thresh)
|
||||
# 'coolwarm', color, nli_thresh,
|
||||
# ampul_example, ampul_examples)
|
||||
#cax.set_ylabel('Response mod.', 'Hz')
|
||||
#cax = plot_corr(ax, data, 'cvstim', ycol, 'cvbase', 0, 0.2, 6,
|
||||
# 'coolwarm', color, nli_thresh)
|
||||
# 'coolwarm', color, nli_thresh,
|
||||
# ampul_example, ampul_examples)
|
||||
#cax.set_ylabel('CV$_{\\rm base}$')
|
||||
#cax.set_yticks_delta(0.1)
|
||||
cax = plot_corr(ax, data, 'cvstim', ycol, 'ratebase', 90, 180, 6,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
ampul_example, ampul_examples)
|
||||
cax.set_ylabel('$r$', 'Hz')
|
||||
cax.set_yticks_delta(30)
|
||||
|
||||
@ -167,7 +198,8 @@ def plot_mod_nli_ampul(ax, data, ycol, nli_thresh, color):
|
||||
ax.set_xticks_delta(20)
|
||||
ax.set_yticks_delta(5)
|
||||
cax = plot_corr(ax, data, 'respmod2', ycol, 'cvbase', 0, 0.2, 0.06,
|
||||
'coolwarm', color, nli_thresh)
|
||||
'coolwarm', color, nli_thresh,
|
||||
ampul_example, ampul_examples)
|
||||
cax.set_ylabel('CV$_{\\rm base}$')
|
||||
cax.set_yticks_delta(0.1)
|
||||
|
||||
|
@ -417,7 +417,7 @@ We here analyze nonlinear responses in two types of primary electroreceptor affe
|
||||
\section{Introduction}
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{plot_chi2.pdf}
|
||||
%\includegraphics[width=\columnwidth]{plot_chi2.pdf}
|
||||
\caption{\label{fig:lifresponse} First- (linear) and second-order response functions of the leaky integrate-and-fire model. \figitem{A} Magnitude of the first-order response function $|\chi_1(f)|$, also known as the ``gain'' function, quantifies the response amplitude relative to the stimulus amplitude, both measured at the stimulus frequency. \figitem{B} Magnitude of the second-order response function $|\chi_2(f_1, f_2)|$ quantifies the response at the sum of two stimulus frequencies. For linear systems, the second-order response function is zero, because linear systems do not create new frequencies and thus there is no response at the sum of the two frequencies. The plots show the analytical solutions from \citep{Lindner2001} and \citep{Voronenko2017} with $\mu = 1.1$ and $D = 0.001$. Note that the leaky integrate-and-fire model is formulated without dimensions, frequencies are given in multiples of the inverse membrane time constant.}
|
||||
\end{figure*}
|
||||
We like to think about signal encoding in terms of linear relations with unique mapping of a given input value to a certain output of the system under consideration. Indeed, such linear methods, for example the transfer function or first-oder susceptibility shown in figure~\ref{fig:lifresponse}, have been widely and successfully applied to describe and predict neuronal responses and are an invaluable tool to characterize neural systems \citep{Borst1999}. Nonlinear mechanisms, on the other hand, are key on different levels of neural processing. Deciding for one action over another is a nonlinear process on the systemic level. On the cellular level, spiking neurons are inherently nonlinear. Whether an action potential is elicited depends on the membrane potential to exceed a threshold \citep{Hodgkin1952, Koch1995}. Because of such nonlinearities, understanding and predicting neuronal responses to sensory stimuli is in general a difficult task.
|
||||
@ -431,7 +431,7 @@ Here we search for such weakly nonlinear responses in electroreceptors of the tw
|
||||
\section{Results}
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{motivation.pdf}
|
||||
%\includegraphics[width=\columnwidth]{motivation.pdf}
|
||||
\caption{\label{fig:motivation} Nonlinearity in an electrophysiologically recorded P-unit of \lepto{} in a three-fish setting (cell identifier ``2021-08-03-ac"). Receiver with EOD frequency $\feod{} =664$\,Hz encounters fish with EOD frequencies $f_{1}=631$\,Hz and $f_{2}=797$\,Hz. Both foreign signals have the same strength relative to the own field amplitude (10\,\% contrast). Top row: Sketch of signal processing in the nonlinear system (black box). Second row: Interference of the receiver EOD with the EODs of other fish, bold line highlights the amplitude modulation. Third row: Respective spike trains of the recorded P-unit. Fourth row: Firing rate, estimated by convolution of the spike trains with a Gaussian kernel ($\sigma = 1$\,ms). Bottom row: Power spectrum of the firing rate. \figitem{A} Baseline condition: The cell is driven by the self-generated field alone. The baseline firing rate \fbase{} dominates the power spectrum of the firing rate ($f_{base} = 139$\,Hz). \figitem{B} The receiver's EOD and a foreign fish with an EOD frequency $f_{1}=631$\,Hz are present. EOD interference induces an amplitude modulation, referred to as beat. \figitem{C} The receiver and a fish with an EOD frequency $f_{2}=797$\,Hz are present. The resulting beat is faster as the difference between the individual frequencies is larger. \figitem{D} All three fish with the EOD frequencies \feod{}, $f_{1}$ and $f_{2}$ are present, a second-order amplitude modulation occurs, commonly referred to as envelope. Nonlinear peaks occur at the sum and difference of the two beat frequencies in the power spectrum of the firing rate.
|
||||
}
|
||||
\end{figure*}
|
||||
@ -447,7 +447,7 @@ When stimulating with both foreign signals simultaneously, additional peaks appe
|
||||
\subsection{Linear and weakly nonlinear regimes}
|
||||
|
||||
\begin{figure*}[p]
|
||||
\includegraphics[width=\columnwidth]{nonlin_regime.pdf}
|
||||
\includegraphics[width=\columnwidth]{regimes}
|
||||
\caption{\label{fig:nonlin_regime} Linear and nonlinear responses of a model P-unit in a three-fish setting in dependence on increasing stimulus amplitudes. The model P-unit was stimulated with two sinewaves of equal amplitude (contrast) at difference frequencies $\bone=30$\,Hz and $\btwo=130$\,Hz relative the receiver's EOD frequency. \btwo{} was set to match the baseline firing rate \fbase{} of the P-unit. The model used has the cell identifier 2013-01-08-aa (table~\ref{modelparams}). \figitem{A--D} Top: the stimulus, an amplitude modulation of the receiver's EOD resulting from the stimulation with the two sine waves. The contrasts of both beats increase from \panel{A} to \panel{D} as indicated. Middle: Spike raster of the model P-unit response. Bottom: power spectrum of the firing rate estimated from the spike raster with a Gaussian kernel ($\sigma=1$\,ms). \figitem{A} At low stimulus contrasts the response is linear. The only peaks in the response spectrum are at the two stimulating beat frequencies (green and purple marker) and their amplitudes increase linearly with stimulus contrast (thin lines). \figitem{B} At intermediate stimulus contrasts, nonlinear responses appear at the sum and the difference of the stimulus frequencies (orange and red marker). Their amplitudes grow quadraticlaly with stimulus constrast (thin lines). \figitem{C} At stronger stimulation the amplitudes of these nonlinear repsonses deviate from the quadratic dependency on stimulus contrast. \figitem{D} At higher stimulus contrasts additional peaks appear in the power spectrum. \figitem{E} Amplitude of the linear (at $\Delta f_1$ and $\Delta f_2$) and nonlinear (at $\Delta f_2 - \Delta f_1$ and $\Delta f_1 + \Delta f_2$) responses of the model P-unit as a function of beat contrast (thick lines). Thin lines indicate the initial linear and quadratic dependence on stimulus amplitude for the linear and nonlinear responses, respectively.}
|
||||
\end{figure*}
|
||||
|
||||
@ -467,8 +467,8 @@ In the following, however, we are interested in how the nonlinear responses depe
|
||||
Weakly nonlinear responses are expected in cells with sufficiently low intrinsic noise levels, i.e. low baseline CVs \citep{Voronenko2017}. P-units fire action potentials probabilistically phase-locked to the self-generated EOD \citep{Bastian1981a}. Skipping of EOD cycles leads to the characteristic multimodal ISI distribution with maxima at integer multiples of the EOD period (\subfigrefb{fig:punit}{A}). In this example, the baseline ISI distribution has a CV$_{\text{base}}$ of 0.2, which is at the lower end of the P-unit population \citep{Hladnik2023}. Spectral analysis of the baseline activity shows two major peaks: the first is located at the baseline firing rate \fbase, the second is located at the discharge frequency \feod{} of the electric organ and is flanked by two smaller peaks at $\feod \pm \fbase{}$ (\subfigref{fig:punit}{B}).
|
||||
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{cells_suscept.pdf}
|
||||
\begin{figure*}[p]
|
||||
\includegraphics[width=\columnwidth]{punitexamplecell}
|
||||
\caption{\label{fig:punit} Linear and nonlinear stimulus encoding in a low-CV P-unit (cell identifier ``2010-06-21-ai"). \figitem{A} Interspike interval (ISI) distribution of the cell's baseline activity, i.e. the cell is driven only by the unperturbed own electric field. The low CV of the ISIs indicates quite regular firing. \figitem{B} Power spectral density of the baseline response with peaks at the cell's baseline firing rate \fbase{} and the fish's EOD frequency \feod{}. \figitem{C} Random amplitude modulation stimulus (top, with cutoff frequency of 300\,Hz) and evoked responses (spike raster, bottom) of the same P-unit. The stimulus contrast (right) measures the strength of the AM. \figitem{D} Gain of the transfer function (first-order susceptibility), \eqnref{linearencoding_methods}, computed from the responses to 10\,\% (light purple) and 20\,\% contrast (dark purple) RAM stimulation of 10\,s duration. \figitem{E, F} Absolute value of the second-order susceptibility, \eqnref{eq:susceptibility}, for both the low and high stimulus contrast. Pink triangles mark vertical, horizontal, and diagonal lines where \fone, \ftwo{} or \fsum{} are equal to \fbase{}. \figitem{G} Second-order susceptibilities projected onto the diagonal (means of all anti-diagonals of the matrices shown in \panel{E, F}). Dots mark \fbase{}, horizontal dashed lines mark medians of the projected susceptibilities.}
|
||||
\end{figure*}
|
||||
|
||||
@ -483,8 +483,8 @@ In contrast, a high-CV P-unit (CV$_{\text{base}}=0.4$) does not exhibit pronounc
|
||||
|
||||
\subsection{Ampullary afferents exhibit strong nonlinear interactions}
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{ampullary.pdf}
|
||||
\begin{figure*}[p]
|
||||
\includegraphics[width=\columnwidth]{ampullaryexamplecell}
|
||||
\caption{\label{fig:ampullary} Linear and nonlinear stimulus encoding in an ampullary afferent (cell identifier ``2012-04-26-ae"). \figitem{A} Interspike interval (ISI) distribution of the cell's baseline activity. The very low CV of the ISIs indicates almost perfect periodic spiking. \figitem{B} Power spectral density of baseline activity with peaks at the cell's baseline firing rate and its harmonics. \figitem{C} Bad-limited white noise stimulus (top, with a cutoff frequency of 150\,Hz) added to the fish's self-generated electric field and spike raster of the evoked responses (bottom) for two stimulus contrasts as indicated (right). \figitem{D} Gain of the transfer function, \eqnref{linearencoding_methods}, of the responses to stimulation with 2\,\% (light green) and 20\,\% contrast (dark green) of 10\,s duration. \figitem{E, F} Absolute value of the second-order susceptibility, \eqnref{eq:susceptibility}, for both stimulus contrasts as indicated. Pink triangles indicate the baseline firing rate. \figitem{G} Projections of the second-order susceptibilities in \panel{E, F} onto the diagonal. }
|
||||
\end{figure*}
|
||||
|
||||
@ -495,7 +495,7 @@ Electric fish possess an additional electrosensory system, the passive or ampull
|
||||
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]
|
||||
\includegraphics[width=\columnwidth]{model_and_data.pdf}
|
||||
%\includegraphics[width=\columnwidth]{model_and_data.pdf}
|
||||
\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.}
|
||||
@ -554,7 +554,7 @@ Overall, observing \nli{} values greater than at least 1.6, even for a number of
|
||||
|
||||
|
||||
\begin{figure*}[tp]
|
||||
\includegraphics[width=\columnwidth]{data_overview_mod.pdf}
|
||||
\includegraphics[width=\columnwidth]{dataoverview}
|
||||
\caption{\label{fig:dataoverview} Nonlinear responses in P-units and ampullary cells. The second-order susceptibility is condensed into the peakedness of the nonlinearity, \nli{} \eqnref{eq:nli_equation}, that relates the amplitude of the projected susceptibility at a cell's baseline firing rate to its median (see \subfigrefb{fig:punit}{G}). Each of the recorded neurons contributes at maximum with two stimulus contrasts. Black squares and circles highlight recordings conducted in a single cell. Squares in \panel{A, C, E} correspond to the cell in \figrefb{fig:punit} and circles to the cell in \figrefb{fig:punithighcv}. Squares in \panel{B, D, F} correspond to the cell in \figrefb{fig:ampullary}. \figitem{A, B} There is a negative correlation between the CV during baseline and \nli. \figitem{C, D} There is a negative correlation between the CV during stimulation and \nli. \figitem{E, F} \nli{} is plotted against the response modulation, (see methods), an indicator of the subjective stimulus strength for a cell. There is a negative correlation between response modulation and \nli. Restricting the analysis to the weakest stimulus that was presented to each unique neuron, does not change the results. The number of unique neurons is 221 for P-units and 45 for ampullary cells.
|
||||
% The two example P-units shown before are highlighted with dark markers in \subfigrefb{fig:dataoverview}{A, C, E} (squares -- \figrefb{fig:punit}, circles -- \figrefb{fig:punithighcv}).
|
||||
% Several of the recorded neurons contribute with two samples to the population analysis as their responses have been recorded to two different contrasts of the same RAM stimulus. Higher stimulus contrasts lead to a stronger drive and thus stronger response modulations (see color code bar in \subfigref{fig:dataoverview}{A}, see methods).
|
||||
@ -562,12 +562,6 @@ Overall, observing \nli{} values greater than at least 1.6, even for a number of
|
||||
}
|
||||
\end{figure*}
|
||||
|
||||
\begin{figure*}[tp]
|
||||
\includegraphics[width=\columnwidth]{dataoverview}
|
||||
\caption{\label{fig:dataoverview} Nonlinear responses in P-units and ampullary cells.
|
||||
}
|
||||
\end{figure*}
|
||||
|
||||
\subsection{Low CVs and weak stimuli are associated with distinct nonlinearity in recorded electroreceptive neurons}
|
||||
Now we are prepared to evaluate our pool of 221 P-units and 47 ampullary afferents recorded in 71 specimen.
|
||||
\notejb{We need to state the number of trials}
|
||||
@ -588,7 +582,7 @@ The population of ampullary cells is generally more homogeneous, with lower base
|
||||
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{model_full.pdf}
|
||||
%\includegraphics[width=\columnwidth]{model_full.pdf}
|
||||
\caption{\label{fig:model_full} Using second-order susceptibility to predict responses to sine-wave stimuli. \figitem[]{A} Absolute value of the second-order susceptibility, \eqnref{eq:susceptibility}, for both positive and negative frequencies. \susceptf{} was estimated from $N=10^6$ segments of model simulations in the noise-split condition (cell 2013-01-08-aa, see table~\ref{modelparams} for model parameters). White lines indicate zero frequencies. Nonlinear responses at \fsum{} are quantified in the upper right and lower left quadrants. Nonlinear responses at \fdiff{} are quantified in the upper left and lower right quadrants. The baseline firing rate of this cell was at $\fbase=120$\,Hz. The position of the orange/red letters corresponds to the beat frequencies used for the stimulation with pure sine waves in the subsequent panels and indicates the sum/difference of those beat frequencies. \figitem{B--E} Black line -- power spectral density of model simulations in response to stimulation with two pure sine waves, \fone{} and \ftwo, in addition to the receiving fish's own EOD (three-fish scenario). The contrast of beat beats is 0.02. Colored circles highlight the height of selected peaks in the power spectrum. Grey line -- power spectral density of model in the baseline condition. \figitem{B} The sum of the two beat frequencies match \fbase{}. \figitem{C} The difference of \fone{} and \ftwo{} match \fbase{}. \figitem{D} Only the first beat frequency matches \fbase{}. \figitem{E} None of the two beat frequencies matches \fbase{}.}
|
||||
\end{figure*}
|
||||
|
||||
@ -768,7 +762,7 @@ Using \eqnref{eq:nli_equation} instead of \eqnref{eq:nli_equation2} for the esti
|
||||
|
||||
|
||||
\begin{figure*}[t]
|
||||
\includegraphics[width=\columnwidth]{flowchart.pdf}
|
||||
%\includegraphics[width=\columnwidth]{flowchart.pdf}
|
||||
\caption{\label{flowchart}
|
||||
Architecture of the P-unit model. Each row illustrates subsequent processing steps for three different stimulation regimes: (i) baseline activity without external stimulus, only the fish's self-generated EOD (the carrier, \eqnref{eq:eod}) is present. (ii) RAM stimulation, \eqnref{eq:ram_equation}. The amplitude of the EOD carrier is modulated with a weak (2\,\% contrast) band-limited white-noise stimulus. (iii) Noise split, \eqnsref{eq:ram_split}--\eqref{eq:Noise_split_intrinsic}, where 90\,\% of the intrinsic noise is replaced by a RAM stimulus, whose amplitude is scaled to maintain the mean firing rate and the CV of the ISIs of the model's baseline activity. As an example, simulations of the model for cell ``2012-07-03-ak'' are shown (table~\ref{modelparams}). \figitem{A} The stimuli are thresholded, \eqnref{eq:threshold2}, by setting all negative values to zero. \figitem{B} Subsequent low-pass filtering, \eqnref{eq:dendrite}, attenuates the carrier and carves out the AM signal. \figitem{C} Intrinsic Gaussian white-noise is added to the signals shown in \panel{B}. Note the reduced internal noise amplitude in the noise split (iii) condition. \figitem{D} Spiking output of the LIF model, \eqnsref{eq:LIF}--\eqref{spikethresh}, in response to the sum of \panel{B} and \panel{C}. \figitem{E} Power spectra of the LIF neuron's spiking activity. Both, baseline activity (\panel[i]{E}) and noise split (\panel[iii]{E}), have the same peaks in the response spectrum at $\fbase$, $f_{EOD} - \fbase$, $f_{EOD}$, and $f_{EOD} + \fbase$. With RAM stimulation (\panel[ii]{E}), the peak at the baseline firing rate, $\fbase$, is washed out.}
|
||||
\end{figure*}
|
||||
@ -884,7 +878,7 @@ CVs in P-units can range up to 1.5 \citep{Grewe2017, Hladnik2023}. We show the s
|
||||
|
||||
\label{S1:highcvpunit}
|
||||
\begin{figure*}[!ht]
|
||||
\includegraphics[width=\columnwidth]{cells_suscept_high_CV.pdf}
|
||||
%\includegraphics[width=\columnwidth]{cells_suscept_high_CV.pdf}
|
||||
\caption{\label{fig:punithighcv} Response of a noisy P-units (cell ``2018-08-24-af") with a relatively high baseline CV of 0.34 to RAM stimuli with two different contrasts. \figitem{A} Interspike intervals (ISI) distribution during baseline. \figitem{B} Baseline power spectrum. \figitem{C} Top: EOD carrier (gray) with RAM (red). Center: Spike trains in response to the 5\,\% RAM contrast. Bottom: Spike trains in response to the 10\,\% RAM contrast. \figitem{D} First-order susceptibility (\eqnref{linearencoding_methods}). \figitem{E} Absolute value $|\chi_2(f_1, f_2)|$ of the second-order susceptibility, \eqnref{eq:susceptibility}, for the 5\,\% RAM contrast. Pink lines -- edges of the structure when \fone, \ftwo{} or \fsum{} are equal to \fbase{}. \figitem{F} $|\chi_2(f_1, f_2)|$ for the 10\,\% RAM contrast. \figitem{G} Projected diagonals, calculated as the mean of the anti-diagonals of the matrices in \panel{E--F}. Gray dots: \fbase{}. Dashed lines: Medians of the projected diagonals.}
|
||||
\end{figure*}
|
||||
|
||||
|
33
plotstyle.py
33
plotstyle.py
@ -18,7 +18,8 @@ def significance_str(p):
|
||||
|
||||
def plot_style():
|
||||
palette = pt.palettes['muted']
|
||||
lwthick = 1.0
|
||||
lwthick = 1.6
|
||||
lwmid = 1.0
|
||||
lwthin = 0.5
|
||||
lwspines = 1.0
|
||||
names = ['A1', 'A2', 'A3',
|
||||
@ -36,6 +37,7 @@ def plot_style():
|
||||
class ns: pass
|
||||
ns.colors = palette
|
||||
ns.lwthick = lwthick
|
||||
ns.lwmid = lwmid
|
||||
ns.lwthin = lwthin
|
||||
ns.plot_width = 16.5
|
||||
pt.make_linepointfill_styles(ns, names, colors, dashes, markers,
|
||||
@ -54,19 +56,42 @@ def plot_style():
|
||||
lwthin)
|
||||
pt.make_line_styles(ns, 'ls', 'EOD', '', palette['gray'], '-', lwthin)
|
||||
pt.make_line_styles(ns, 'ls', 'AM', '', palette['red'], '-', lwthick)
|
||||
|
||||
ns.lsStim = dict(color='gray', lw=ns.lwmid)
|
||||
ns.lsRaster = dict(color='black', lw=ns.lwthin)
|
||||
ns.lsPower = dict(color='gray', lw=ns.lwmid)
|
||||
ns.lsF0 = dict(color='blue', lw=ns.lwthick)
|
||||
ns.lsF01 = dict(color='green', lw=ns.lwthick)
|
||||
ns.lsF02 = dict(color='purple', lw=ns.lwthick)
|
||||
ns.lsF012 = dict(color='orange', lw=ns.lwthick)
|
||||
ns.lsF01_2 = dict(color='red', lw=ns.lwthick)
|
||||
ns.lsF0m = dict(color=lighter('blue', 0.5), lw=ns.lwthin)
|
||||
ns.lsF01m = dict(color=lighter('green', 0.6), lw=ns.lwthin)
|
||||
ns.lsF02m = dict(color=lighter('purple', 0.5), lw=ns.lwthin)
|
||||
ns.lsF012m = dict(color=darker('orange', 0.9), lw=ns.lwthin)
|
||||
ns.lsF01_2m = dict(color=darker('red', 0.9), lw=ns.lwthin)
|
||||
|
||||
ns.psFEOD = dict(color='black', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
ns.psF0 = dict(color='blue', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
ns.psF01 = dict(color='green', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
ns.psF02 = dict(color='purple', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
ns.psF012 = dict(color='orange', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
ns.psF01_2 = dict(color='red', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
|
||||
ns.model_color1 = palette['purple']
|
||||
ns.model_color2 = lighter(ns.model_color1, 0.6)
|
||||
ns.punit_color1 = palette['blue']
|
||||
ns.punit_color2 = lighter(ns.punit_color1, 0.6)
|
||||
ns.ampul_color1 = palette['green']
|
||||
ns.ampul_color2 = lighter(ns.ampul_color1, 0.6)
|
||||
pt.make_line_styles(ns, 'ls', 'M%d', '', [ns.model_color1, ns.model_color2], '-', lwthick)
|
||||
pt.make_line_styles(ns, 'ls', 'M%d', '', [ns.model_color1, ns.model_color2], '-', lwmid)
|
||||
pt.make_point_styles(ns, 'ps', 'M%d', '', [ns.model_color1, ns.model_color2], '-', markers=('o', 1), markersizes=4)
|
||||
pt.make_line_styles(ns, 'ls', 'P%d', '', [ns.punit_color1, ns.punit_color2], '-', lwthick)
|
||||
pt.make_line_styles(ns, 'ls', 'P%d', '', [ns.punit_color1, ns.punit_color2], '-', lwmid)
|
||||
pt.make_point_styles(ns, 'ps', 'P%d', '', [ns.punit_color1, ns.punit_color2], '-', markers=('o', 1), markersizes=4)
|
||||
pt.make_line_styles(ns, 'ls', 'A%d', '', [ns.ampul_color1, ns.ampul_color2], '-', lwthick)
|
||||
pt.make_line_styles(ns, 'ls', 'A%d', '', [ns.ampul_color1, ns.ampul_color2], '-', lwmid)
|
||||
pt.make_point_styles(ns, 'ps', 'A%d', '', [ns.ampul_color1, ns.ampul_color2], '-', markers=('o', 1), markersizes=4)
|
||||
pt.make_line_styles(ns, 'ls', 'Diag', '', palette['white'], '--', lwthin)
|
||||
|
||||
pt.arrow_style(ns, 'Line', dist=3.0, style='>', shrink=0, lw=0.6,
|
||||
color=palette['black'], head_length=4, head_width=4,
|
||||
bbox=dict(boxstyle='round,pad=0.1', facecolor='white',
|
||||
|
@ -98,8 +98,8 @@ def plot_response_spectrum(ax, s, eodf, rate, freqs, prr):
|
||||
ax.show_spines('b')
|
||||
mask = freqs < 890
|
||||
ax.plot(freqs[mask], power_db[mask], **s.lsC1)
|
||||
ax.plot(freqs[eod_i], power_db[eod_i], **s.psA1c)
|
||||
ax.plot(freqs[rate_i], power_db[rate_i], **s.psA2c)
|
||||
ax.plot(freqs[eod_i], power_db[eod_i], **s.psFEOD)
|
||||
ax.plot(freqs[rate_i], power_db[rate_i], **s.psF0)
|
||||
ax.set_xlim(0, 900)
|
||||
ax.set_ylim(-25, 5)
|
||||
ax.set_xticks_delta(300)
|
||||
|
33
regimes.py
33
regimes.py
@ -8,7 +8,7 @@ from plotstyle import plot_style, lighter, darker
|
||||
|
||||
|
||||
data_path = Path('data')
|
||||
cell_path = data_path / 'cells'
|
||||
sims_path = data_path / 'simulations'
|
||||
|
||||
|
||||
def load_models(file):
|
||||
@ -116,7 +116,7 @@ def plot_am(ax, s, alpha, beatf1, beatf2, tmax):
|
||||
am = alpha*np.sin(2*np.pi*beatf1*time)
|
||||
am += alpha*np.sin(2*np.pi*beatf2*time)
|
||||
ax.show_spines('l')
|
||||
ax.plot(1000*time, -100*am, **s.lsStim)
|
||||
ax.plot(1000*time, -100*am, **s.lsAM)
|
||||
ax.set_xlim(0, 1000*tmax)
|
||||
ax.set_ylim(-50, 50)
|
||||
#ax.set_xlabel('Time', 'ms')
|
||||
@ -164,7 +164,7 @@ def plot_psd(ax, s, spikes, nfft, dt, beatf1, beatf2):
|
||||
psd /= freqs[1]
|
||||
ax.plot(freqs, decibel(psd), **s.lsPower)
|
||||
ax.plot(beatf2, decibel(peak_ampl(freqs, psd, beatf2)) + offs,
|
||||
label=r'$f_{\rm base}$', clip_on=False, **s.psF0)
|
||||
label=r'$r$', clip_on=False, **s.psF0)
|
||||
ax.plot(beatf1, decibel(peak_ampl(freqs, psd, beatf1)) + offs,
|
||||
label=r'$\Delta f_1$', clip_on=False, **s.psF01)
|
||||
ax.plot(beatf2, decibel(peak_ampl(freqs, psd, beatf2)) + offs + 4.5,
|
||||
@ -196,7 +196,7 @@ def peak_ampl(freqs, psd, f):
|
||||
|
||||
|
||||
def compute_peaks(name, cell, alpha_max, beatf1, beatf2, nfft, trials):
|
||||
data_file = cell_path / f'{name}-contrastpeaks.csv'
|
||||
data_file = sims_path / f'{name}-contrastpeaks.csv'
|
||||
data = TableData(data_file)
|
||||
return data
|
||||
"""
|
||||
@ -289,36 +289,15 @@ def plot_peaks(ax, s, data, alphas):
|
||||
|
||||
if __name__ == '__main__':
|
||||
parameters = load_models(data_path / 'punitmodels.csv')
|
||||
cell_name = '2013-01-08-aa-invivo-1' # 138Hz, CV=0.26: perfect!
|
||||
cell_name = '2013-01-08-aa-invivo-1' # 132Hz, CV=0.16: perfect!
|
||||
beatf1 = 40
|
||||
beatf2 = 138
|
||||
beatf2 = 132
|
||||
# cell_name = '2012-07-03-ak-invivo-1' # 128Hz, CV=0.24
|
||||
# cell_name = '2018-05-08-ae-invivo-1' # 142Hz, CV=0.48
|
||||
|
||||
cell = cell_parameters(parameters, cell_name)
|
||||
|
||||
s = plot_style()
|
||||
s.lwmid = 1.0
|
||||
s.lwthick = 1.6
|
||||
s.lsStim = dict(color='gray', lw=s.lwmid)
|
||||
s.lsRaster = dict(color='black', lw=s.lwthin)
|
||||
s.lsPower = dict(color='gray', lw=s.lwmid)
|
||||
s.lsF0 = dict(color='blue', lw=s.lwthick)
|
||||
s.lsF01 = dict(color='green', lw=s.lwthick)
|
||||
s.lsF02 = dict(color='purple', lw=s.lwthick)
|
||||
s.lsF012 = dict(color='orange', lw=s.lwthick)
|
||||
s.lsF01_2 = dict(color='red', lw=s.lwthick)
|
||||
s.lsF0m = dict(color=lighter('blue', 0.5), lw=s.lwthin)
|
||||
s.lsF01m = dict(color=lighter('green', 0.6), lw=s.lwthin)
|
||||
s.lsF02m = dict(color=lighter('purple', 0.5), lw=s.lwthin)
|
||||
s.lsF012m = dict(color=darker('orange', 0.9), lw=s.lwthin)
|
||||
s.lsF01_2m = dict(color=darker('red', 0.9), lw=s.lwthin)
|
||||
|
||||
s.psF0 = dict(color='blue', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
s.psF01 = dict(color='green', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
s.psF02 = dict(color='purple', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
s.psF012 = dict(color='orange', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
s.psF01_2 = dict(color='red', marker='o', linestyle='none', markersize=5, mec='none', mew=0)
|
||||
|
||||
nfft = 2**18
|
||||
fig, axs = plt.subplots(5, 4, cmsize=(s.plot_width, 0.8*s.plot_width),
|
||||
|
Loading…
Reference in New Issue
Block a user