Captioned appendix figures.
Polished some figures. Shortened existing figure captions.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
444
main.tex
444
main.tex
@@ -228,6 +228,7 @@ intensity-invariant song representations, the interaction between these
|
|||||||
mechanisms, the overall capacity for intensity invariance in the system, and
|
mechanisms, the overall capacity for intensity invariance in the system, and
|
||||||
the ethological implications of our findings.
|
the ethological implications of our findings.
|
||||||
|
|
||||||
|
\newpage
|
||||||
\section{Methods}
|
\section{Methods}
|
||||||
% This maybe does not quite fit here, but it is the most general part of the
|
% This maybe does not quite fit here, but it is the most general part of the
|
||||||
% methods and applies throughout the whole section, so I put it here for now.
|
% methods and applies throughout the whole section, so I put it here for now.
|
||||||
@@ -289,8 +290,8 @@ the following sections.
|
|||||||
representations~(boxes) and transformations~(arrows) along
|
representations~(boxes) and transformations~(arrows) along
|
||||||
the model pathway. All representations are time-varying.
|
the model pathway. All representations are time-varying.
|
||||||
1st half: Preprocessing stage~(one-dimensional
|
1st half: Preprocessing stage~(one-dimensional
|
||||||
representation). 2nd half: Feature extraction
|
representations). 2nd half: Feature extraction
|
||||||
stage~(high-dimensional representation). }
|
stage~(high-dimensional representations). }
|
||||||
\label{fig:pathway}
|
\label{fig:pathway}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
@@ -347,8 +348,8 @@ the following feature extraction stage.
|
|||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_pre_stages.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_pre_stages.pdf}
|
||||||
\caption{\textbf{Representations of a song of \textit{O. rufipes} during
|
\caption{\textbf{Song representations during the preprocessing stage.}
|
||||||
the preprocessing stage.}
|
Example song of \textit{O. rufipes}.
|
||||||
\textbf{a}:~Bandpass filtered tympanal signal $\filt(t)$.
|
\textbf{a}:~Bandpass filtered tympanal signal $\filt(t)$.
|
||||||
\textbf{b}:~Signal envelope $\env(t)$.
|
\textbf{b}:~Signal envelope $\env(t)$.
|
||||||
\textbf{c}:~Logarithmically compressed envelope $\db(t)$.
|
\textbf{c}:~Logarithmically compressed envelope $\db(t)$.
|
||||||
@@ -483,14 +484,15 @@ or a simple linear classifier.
|
|||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_feat_stages.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_feat_stages.pdf}
|
||||||
\caption{\textbf{Representations of a song of \textit{O. rufipes} during
|
\caption{\textbf{Song representations during the feature extraction stage.}
|
||||||
the feature extraction stage.}
|
Example song of \textit{O. rufipes}.
|
||||||
Different color shades indicate different types of Gabor
|
Different color shades indicate different types of Gabor
|
||||||
kernels with specific lobe number $\kn$ and either $+$ or
|
kernels with specific lobe number $\kni$ and either $+$ or
|
||||||
$-$ sign, sorted (dark to light) first by increasing $\kn$
|
$-$ sign, sorted (dark to light) first by increasing
|
||||||
and then by sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then
|
$\kni$ and then by sign~($1\,\leq\,\kni\,\leq\,4$; first
|
||||||
$-$ for each $\kn$; two kernel widths $\kw$ of $4\,$ms and
|
$+$, then $-$ for each $\kni$; two kernel widths $\kwi$ of
|
||||||
$32\,$ms per type; 8 types, 16 kernels in total).
|
$4\,$ms and $32\,$ms per type; 8 types, 16 kernels in
|
||||||
|
total).
|
||||||
\textbf{a}:~Kernel-specific filter responses $c_i(t)$.
|
\textbf{a}:~Kernel-specific filter responses $c_i(t)$.
|
||||||
\textbf{b}:~Binary responses $b_i(t)$.
|
\textbf{b}:~Binary responses $b_i(t)$.
|
||||||
\textbf{c}:~Finalized features $f_i(t)$.}
|
\textbf{c}:~Finalized features $f_i(t)$.}
|
||||||
@@ -653,12 +655,13 @@ which is a reasonable assumption for the raw $\soc(t)$ and $\noc(t)$. However,
|
|||||||
the dependency of the ratio on $\sca$ is not necessarily the same for
|
the dependency of the ratio on $\sca$ is not necessarily the same for
|
||||||
representations that are transformed from $x(t)$ by nonlinear operations, since
|
representations that are transformed from $x(t)$ by nonlinear operations, since
|
||||||
these change the relationship of $\soc(t)$ and $\noc(t)$ in an unpredictable
|
these change the relationship of $\soc(t)$ and $\noc(t)$ in an unpredictable
|
||||||
fashion. Furthermore, the ratio is not a proper SNR of the representation
|
fashion~(see appendix Fig.\,\ref{fig:app_env-sd}). Furthermore, the ratio is
|
||||||
because it does not relate $\soc(t)$ to $\noc(t)$ within the representation but
|
not a proper SNR of the representation because it does not relate $\soc(t)$ to
|
||||||
rather the entire representation to $\noc(t)$ alone. However, it still provides
|
$\noc(t)$ within the representation but rather the entire representation to
|
||||||
a useful measure of the relative intensity of a representation with and without
|
$\noc(t)$ alone. However, it still provides a useful measure of the relative
|
||||||
$\soc(t)$, which is the closest we can get to the SNR of the representation. As
|
intensity of a representation with and without $\soc(t)$, which is the closest
|
||||||
such, the ratio of intensity measures is referred to as SNR in the following.
|
we can get to the SNR of the representation. As such, the ratio of intensity
|
||||||
|
measures is referred to as SNR in the following.
|
||||||
% Is this legal? "SNR" is much shorter than "ratio of intensity measure to the pure-noise reference measure".
|
% Is this legal? "SNR" is much shorter than "ratio of intensity measure to the pure-noise reference measure".
|
||||||
% Haven't used it much yet, sticked to "ratio" in most cases.
|
% Haven't used it much yet, sticked to "ratio" in most cases.
|
||||||
|
|
||||||
@@ -694,9 +697,10 @@ $\thr$ has been specified as a multiple of the pure-noise reference standard
|
|||||||
deviation $\sigma_{c_i}$ for input $x(t)=\noc(t)$. This ensures that $\thr$ as
|
deviation $\sigma_{c_i}$ for input $x(t)=\noc(t)$. This ensures that $\thr$ as
|
||||||
well as the resulting $b_i(t)$ and $f_i(t)$ are comparable across different
|
well as the resulting $b_i(t)$ and $f_i(t)$ are comparable across different
|
||||||
$k_i(t)$ because each pure-noise $c_i(t)$ approximately follows a normal
|
$k_i(t)$ because each pure-noise $c_i(t)$ approximately follows a normal
|
||||||
distribution~(see appendix
|
distribution around zero~(see appendix
|
||||||
Figs.\,\ref{fig:app_thresh-lp_kern-sd}-\ref{fig:app_field_kern-sd}).
|
Figs.\,\ref{fig:app_thresh-lp_kern-sd}-\ref{fig:app_field_kern-sd}).
|
||||||
|
|
||||||
|
\newpage
|
||||||
\section{Results}
|
\section{Results}
|
||||||
|
|
||||||
\subsection{Mechanisms driving the emergence of intensity invariance}
|
\subsection{Mechanisms driving the emergence of intensity invariance}
|
||||||
@@ -767,25 +771,23 @@ more robust input representation and higher input SNR.
|
|||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_rect_lp.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_rect_lp.pdf}
|
||||||
\caption{\textbf{Rectification and lowpass filtering improves SNR
|
\caption{\textbf{Rectification and lowpass filtering improves SNR
|
||||||
but does not contribute to intensity invariance.}
|
but does not contribute to intensity invariance.}
|
||||||
Input $\raw(t)$ consists of song component $\soc(t)$ scaled by
|
Input $\raw(t)$ consists of $\soc(t)$ scaled by $\sca$ with
|
||||||
$\sca$ with optional noise component $\noc(t)$ and is
|
optional $\noc(t)$ and is successively transformed into
|
||||||
successively transformed into tympanal signal $\filt(t)$ and
|
tympanal signal $\filt(t)$ and envelope $\env(t)$.
|
||||||
envelope $\env(t)$. Different line styles indicate different
|
\textbf{Top}:~Examples of $\filt(t)$ and $\env(t)$ for
|
||||||
cutoff frequencies $\fc$ of the lowpass filter extracting
|
different $\sca$.
|
||||||
$\env(t)$.
|
|
||||||
\textbf{Top}:~Example representations of $\filt(t)$ and
|
|
||||||
$\env(t)$ for different $\sca$.
|
|
||||||
\textbf{a}:~Noiseless case.
|
\textbf{a}:~Noiseless case.
|
||||||
\textbf{b}:~Noisy case.
|
\textbf{b}:~Noisy case.
|
||||||
\textbf{Bottom}:~Intensity measures over a range of $\sca$.
|
\textbf{Bottom}:~Intensity measures over $\sca$. Different
|
||||||
\textbf{c}:~Noiseless case: Standard deviations $\sigma_x$ of
|
line styles indicate different cutoff frequencies $\fc$ of the
|
||||||
$\filt(t)$ and $\env(t)$.
|
lowpass filter extracting $\env(t)$.
|
||||||
\textbf{d}:~Noisy case: Ratios of $\sigma_x$ of $\filt(t)$ and
|
\textbf{c}:~Noiseless case: Standard deviation $\sigma_x$ of
|
||||||
$\env(t)$ to the respective reference standard deviation
|
$\filt(t)$ and $\env(t)$, respectively.
|
||||||
$\sigma_{\eta}$ for input $\raw(t)=\noc(t)$.
|
\textbf{d}:~Noisy case: Ratio of $\sigma_x$ to the respective
|
||||||
\textbf{e}:~Ratios of $\sigma_x$ to $\sigma_{\eta}$ of
|
pure-noise reference $\sigma_{\eta}$ for $\sca=0$.
|
||||||
|
\textbf{e}:~Ratio of $\sigma_x$ to $\sigma_{\eta}$ of
|
||||||
$\env(t)$ as in \textbf{d} for different species (averaged
|
$\env(t)$ as in \textbf{d} for different species (averaged
|
||||||
over songs and recordings, see appendix
|
over songs and recordings, appendix
|
||||||
Fig.\,\ref{fig:app_rect-lp}).
|
Fig.\,\ref{fig:app_rect-lp}).
|
||||||
}
|
}
|
||||||
\label{fig:rect-lp}
|
\label{fig:rect-lp}
|
||||||
@@ -907,28 +909,26 @@ is a recurring phenomenon that is further addressed in the following sections.
|
|||||||
\caption{\textbf{Intensity invariance through logarithmic compression and
|
\caption{\textbf{Intensity invariance through logarithmic compression and
|
||||||
adaptation is restricted by the noise floor and decreases
|
adaptation is restricted by the noise floor and decreases
|
||||||
SNR.}
|
SNR.}
|
||||||
Input $\filt(t)$ consists of song component $\soc(t)$
|
Input $\filt(t)$ consists of $\soc(t)$
|
||||||
scaled by $\sca$ with optional noise component $\noc(t)$
|
scaled by $\sca$ with optional $\noc(t)$
|
||||||
and is successively transformed into envelope $\env(t)$,
|
and is successively transformed into envelope $\env(t)$,
|
||||||
logarithmically compressed envelope $\db(t)$, and
|
logarithmically compressed envelope $\db(t)$, and
|
||||||
intensity-adapted envelope $\adapt(t)$.
|
intensity-adapted envelope $\adapt(t)$.
|
||||||
\textbf{Top}:~Example representations of $\env(t)$,
|
\textbf{Top}:~Examples of $\env(t)$, $\db(t)$, and
|
||||||
$\db(t)$, and $\adapt(t)$ for different $\sca$.
|
$\adapt(t)$ for different $\sca$.
|
||||||
\textbf{a}:~Noiseless case.
|
\textbf{a}:~Noiseless case.
|
||||||
\textbf{b}:~Noisy case.
|
\textbf{b}:~Noisy case.
|
||||||
\textbf{Bottom}:~Intensity measures over a range of $\sca$.
|
\textbf{Bottom}:~Intensity measures over $\sca$.
|
||||||
\textbf{c}:~Noiseless case: Standard deviations $\sigma_x$
|
\textbf{c}:~Noiseless case: Standard deviation $\sigma_x$
|
||||||
of $\env(t)$, $\db(t)$, and $\adapt(t)$.
|
of $\env(t)$, $\db(t)$, and $\adapt(t)$, respectively.
|
||||||
\textbf{d}:~Noisy case: Ratios of $\sigma_x$ of $\env(t)$,
|
\textbf{d}:~Noisy case: Ratio of $\sigma_x$ to the
|
||||||
$\db(t)$, and $\adapt(t)$ to the respective reference
|
respective pure-noise reference $\sigma_{\eta}$ for
|
||||||
standard deviation $\sigma_{\eta}$ for input
|
$\sca=0$. Shaded areas indicate $5\,\%$ (dark grey) and
|
||||||
$\filt(t)=\noc(t)$. Shaded areas indicate $5\,\%$ (dark
|
$95\,\%$ (light grey) curve span for $\adapt(t)$.
|
||||||
grey) and $95\,\%$ (light grey) curve span for
|
\textbf{e}:~Ratio of $\sigma_x$ to $\sigma_{\eta}$ of
|
||||||
$\adapt(t)$.
|
|
||||||
\textbf{e}:~Ratios of $\sigma_x$ to $\sigma_{\eta}$ of
|
|
||||||
$\adapt(t)$ as in \textbf{d} for different species
|
$\adapt(t)$ as in \textbf{d} for different species
|
||||||
(averaged over songs and recordings, see appendix
|
(averaged over songs and recordings, appendix
|
||||||
Fig\,\ref{fig:app_log-hp_curves}). Dots indicate $95\,\%$
|
Fig.\,\ref{fig:app_log-hp_curves}). Dots indicate $95\,\%$
|
||||||
curve span per species.
|
curve span per species.
|
||||||
}
|
}
|
||||||
\label{fig:log-hp}
|
\label{fig:log-hp}
|
||||||
@@ -1043,33 +1043,32 @@ intensity invariance are further explored in a later section.
|
|||||||
\caption{\textbf{Intensity invariance through thresholding and temporal
|
\caption{\textbf{Intensity invariance through thresholding and temporal
|
||||||
averaging is mediated by the interaction of threshold
|
averaging is mediated by the interaction of threshold
|
||||||
value and noise floor.}
|
value and noise floor.}
|
||||||
Input $\adapt(t)$ consists of song component $\soc(t)$
|
Input $\adapt(t)$ consists $\soc(t)$ scaled by $\sca$ with
|
||||||
scaled by $\sca$ with optional noise component $\noc(t)$
|
optional $\noc(t)$ and is transformed into single kernel
|
||||||
and is transformed into single kernel response $c(t)$,
|
response $c(t)$, binary response $b(t)$, and feature
|
||||||
binary response $b(t)$, and feature $f(t)$. Different
|
$f(t)$. Different color shades indicate different
|
||||||
color shades indicate different threshold values $\Theta$
|
threshold values $\Theta$ (multiples of pure-noise
|
||||||
(multiples of reference standard deviation $\sigma_{\eta}$
|
standard deviation $\sigma_{\eta}$ of $c(t)$ for $\sca=0$,
|
||||||
of $c(t)$ for input $\adapt(t)=\noc(t)$, with darker
|
with darker colors for higher $\Theta$. See also appendix
|
||||||
colors for higher $\Theta$).
|
Fig.\,\ref{fig:app_thresh-lp_kern-sd}).
|
||||||
\textbf{Left}:~Noisy case: Example representations of
|
\textbf{Left}:~Noisy case: Examples of $\adapt(t)$ as well
|
||||||
$\adapt(t)$ as well as $c(t)$, $b(t)$, and $f(t)$ for
|
as $c(t)$, $b(t)$, and $f(t)$ for different $\sca$.
|
||||||
different $\sca$.
|
|
||||||
\textbf{a}:~$\adapt(t)$ with kernel $k(t)$ in black.
|
\textbf{a}:~$\adapt(t)$ with kernel $k(t)$ in black.
|
||||||
\textbf{b\,-\,d}: $c(t)$, $b(t)$, and $f(t)$ based on the
|
\textbf{b\,-\,d}: $c(t)$, $b(t)$, and $f(t)$ based on the
|
||||||
same $\adapt(t)$ from \textbf{a} but with different
|
same $\adapt(t)$ from \textbf{a} but for different
|
||||||
$\Theta$.
|
$\Theta$.
|
||||||
\textbf{Right}:~Average value $\mu_f$ of $f(t)$ for each
|
\textbf{Right}:~Average value $\mu_f$ of $f(t)$ for each
|
||||||
$\Theta$ from \textbf{b\,-\,d}. Dots indicate $95\,\%$
|
$\Theta$ from \textbf{b\,-\,d}. Dots indicate $95\,\%$
|
||||||
curve span (noisy case).
|
curve span (noisy case).
|
||||||
\textbf{e}:~$\mu_f$ over a range of $\sca$, once for the
|
\textbf{e}:~$\mu_f$ over $\sca$, once for the noisy case
|
||||||
noisy case (solid lines) and once for the noiseless case
|
(solid lines) and once for the noiseless case (dotted
|
||||||
(dotted lines).
|
lines).
|
||||||
\textbf{f}:~Noisy case: $\mu_f$ over the standard
|
\textbf{f}:~Noisy case: $\mu_f$ over standard deviation
|
||||||
deviation of input $\adapt$ corresponding to the values of
|
$\sigma_{\text{adapt}}$ of input $\adapt$ corresponding to
|
||||||
$\sca$ shown in \textbf{e}. Shaded area indicates standard
|
$\sca$ shown in \textbf{e}. Shaded area indicates values
|
||||||
deviations that would be capped in the output $\adapt(t)$
|
of $\sigma_{\text{adapt}}$ that are capped in the output
|
||||||
of the previous transformation pair (see
|
$\adapt(t)$ of the previous transformation pair
|
||||||
Fig.\,\ref{fig:log-hp}cd).
|
(Fig.\,\ref{fig:log-hp}cd).
|
||||||
}
|
}
|
||||||
\label{fig:thresh-lp_single}
|
\label{fig:thresh-lp_single}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -1148,29 +1147,29 @@ point of $f_i(t)$ less relevant.
|
|||||||
saturates at different points in feature space.}
|
saturates at different points in feature space.}
|
||||||
Same input and processing as in
|
Same input and processing as in
|
||||||
Fig.\,\ref{fig:thresh-lp_single} but with three different
|
Fig.\,\ref{fig:thresh-lp_single} but with three different
|
||||||
kernels $k_i$, each with a single kernel-specific
|
kernels $k_i$ and a single kernel-specific threshold value
|
||||||
threshold value $\thr=0.5\cdot\sigma_{\eta_i}$.
|
$\thr=0.5\cdot\sigma_{\eta_i}$ (appendix
|
||||||
|
Fig.\,\ref{fig:app_thresh-lp_kern-sd}).
|
||||||
\textbf{a}:~Examples of species-specific grasshopper
|
\textbf{a}:~Examples of species-specific grasshopper
|
||||||
songs.
|
songs.
|
||||||
\textbf{Middle}:~Average value $\mu_{f_i}$ of each feature
|
\textbf{Middle}:~Average value $\muf$ of each feature
|
||||||
$f_i(t)$ over $\sca$ per species (averaged over songs and
|
$f_i(t)$ over $\sca$ per species (averaged over songs and
|
||||||
recordings, see appendix
|
recordings, appendix Figs.\,\ref{fig:app_thresh-lp_pure}
|
||||||
Figs.\,\ref{fig:app_thresh-lp_pure} and
|
and \ref{fig:app_thresh-lp_noise}). Different color shades
|
||||||
\ref{fig:app_thresh-lp_noise}). Different color shades
|
indicate different $k_i$. Dots indicate $95\,\%$ curve
|
||||||
indicate different kernels $k_i$. Dots indicate $95\,\%$
|
span per $k_i$.
|
||||||
curve span per $k_i$.
|
|
||||||
\textbf{b}:~Noiseless case.
|
\textbf{b}:~Noiseless case.
|
||||||
\textbf{c}:~Noisy case.
|
\textbf{c}:~Noisy case.
|
||||||
\textbf{Bottom}:~2D feature spaces spanned by each pair of
|
\textbf{Bottom}:~2D feature spaces spanned by each pair of
|
||||||
$f_i(t)$. Each trajectory corresponds to a
|
$f_i(t)$. Each trajectory corresponds to a
|
||||||
species-specific combination of $\mu_{f_i}$ that develops
|
species-specific combination of $\muf$ that develops
|
||||||
with $\sca$ (colorbars). Horizontal dashes in the colorbar
|
with $\sca$ (colorbars). Horizontal dashes in the colorbar
|
||||||
indicate $5\,\%$ (dark grey) and $95\,\%$ (light grey)
|
indicate $5\,\%$ (dark grey) and $95\,\%$ (light grey)
|
||||||
curve span of the norm across all three $\mu_{f_i}$ per
|
curve span of the norm across all three $\muf$ per
|
||||||
species.
|
species.
|
||||||
\textbf{d}:~Noiseless case.
|
\textbf{d}:~Noiseless case.
|
||||||
\textbf{e}:~Noisy case. Shaded areas indicate the average
|
\textbf{e}:~Noisy case. Shaded areas indicate the average
|
||||||
minimum $\mu_{f_i}$ across all species-specific trajectories.
|
minimum $\muf$ across all species-specific trajectories.
|
||||||
}
|
}
|
||||||
\label{fig:thresh-lp_species}
|
\label{fig:thresh-lp_species}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -1255,34 +1254,34 @@ in principle, work together towards an intensity-invariant song representation.
|
|||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_full_Omocestus_rufipes.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_full_Omocestus_rufipes.pdf}
|
||||||
\caption{\textbf{Step-wise emergence of intensity-invariant song
|
\caption{\textbf{Step-wise emergence of intensity-invariant song
|
||||||
representations along the model pathway.}
|
representations along the model pathway.}
|
||||||
Input $\raw(t)$ consists of song component $\soc(t)$
|
Input $\raw(t)$ consists of $\soc(t)$ scaled by $\sca$
|
||||||
scaled by $\sca$ with added noise component $\noc(t)$ and
|
with added $\noc(t)$ and is processed up to the feature
|
||||||
is processed up to the feature set $f_i(t)$. Different
|
set $f_i(t)$ using kernel-specific threshold values
|
||||||
color shades indicate different types of Gabor kernels
|
$\thr=2\cdot\sigma_{\eta_i}$ (appendix
|
||||||
with specific lobe number $\kn$ and either $+$ or $-$
|
Fig.\,\ref{fig:app_full_kern-sd}). Different color shades
|
||||||
sign, sorted (dark to light) first by increasing $\kn$ and
|
indicate different types of Gabor kernels with specific
|
||||||
then by sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$
|
lobe number $\kn$ and either $+$ or $-$ sign, sorted (dark
|
||||||
for each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8,
|
to light) first by increasing $\kn$ and then by
|
||||||
and $16\,$ms per type; 8 types, 40 kernels in total).
|
sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
||||||
\textbf{a}:~Example representations of $\filt(t)$,
|
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
||||||
$\env(t)$, $\db(t)$, $\adapt(t)$, $c_i(t)$, and $f_i(t)$
|
$16\,$ms per type; 8 types, 40 $k_i(t)$ in total).
|
||||||
for different $\sca$.
|
\textbf{a}:~Examples of $\filt(t)$, $\env(t)$, $\db(t)$,
|
||||||
\textbf{b}:~Intensity measures over $\sca$. For $c_i(t)$
|
$\adapt(t)$, $c_i(t)$, and $f_i(t)$ for different $\sca$.
|
||||||
and $f_i(t)$, the median over kernels is shown. Dots
|
\textbf{b}:~Intensity measures over $\sca$. The median
|
||||||
|
over $k_i(t)$ is shown for $c_i(t)$ and $f_i(t)$. Dots
|
||||||
indicate $95\,\%$ curve span for $\db(t)$, $\adapt(t)$,
|
indicate $95\,\%$ curve span for $\db(t)$, $\adapt(t)$,
|
||||||
$c_i(t)$, and $f_i(t)$.
|
$c_i(t)$, and $f_i(t)$.
|
||||||
\textbf{c}:~Average value $\mu_{f_i}$ of each feature
|
\textbf{c}:~Average value $\muf$ of each $f_i(t)$
|
||||||
$f_i(t)$ over $\sca$.
|
over $\sca$.
|
||||||
\textbf{d}:~Ratios of intensity measures to the respective
|
\textbf{d}:~Ratio of intensity measures from \textbf{b} to
|
||||||
reference value for input $\raw(t)=\noc(t)$. For $c_i(t)$
|
the respective pure-noise reference for $\sca=0$.
|
||||||
and $f_i(t)$, the median over kernel-specific ratios is
|
\textbf{e}:~Ratio of standard deviation $\sigma_{c_i}$ of
|
||||||
shown.
|
|
||||||
\textbf{e}:~Ratios of standard deviation $\sigma_{c_i}$ of
|
|
||||||
each $c_i(t)$.
|
each $c_i(t)$.
|
||||||
\textbf{f}:~Ratios of $\mu_{f_i}$.
|
\textbf{f}:~Ratio of $\muf$.
|
||||||
\textbf{g}:~Distributions of kernel-specific $\sca$ that
|
\textbf{g}:~Distributions of kernel-specific $\sca$ that
|
||||||
correspond to $95\,\%$ curve span for $c_i(t)$ and
|
correspond to $95\,\%$ curve span for $c_i(t)$ and
|
||||||
$f_i(t)$. Dots indicate the values from \textbf{b}.
|
$f_i(t)$. Dots indicate values based on the median from
|
||||||
|
\textbf{b}.
|
||||||
}
|
}
|
||||||
\label{fig:pipeline_full}
|
\label{fig:pipeline_full}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -1337,32 +1336,24 @@ guaranteed simply by disabling logarithmic compression.
|
|||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_short_Omocestus_rufipes.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_short_Omocestus_rufipes.pdf}
|
||||||
\caption{\textbf{Effects of disabling logarithmic compression on intensity
|
\caption{\textbf{Effects of disabling logarithmic compression on intensity
|
||||||
invariance along the model pathway.}
|
invariance along the model pathway.}
|
||||||
Input $\raw(t)$ consists of song component $\soc(t)$
|
Same input and processing as in
|
||||||
scaled by $\sca$ with added noise component $\noc(t)$ and
|
Fig.\,\ref{fig:pipeline_full}, using kernel-specific
|
||||||
is processed up to the feature set $f_i(t)$, skipping
|
threshold values $\thr=2\cdot\sigma_{\eta_i}$ (appendix
|
||||||
$\db(t)$. Different color shades indicate different types
|
Fig.\,\ref{fig:app_short_kern-sd}), except that
|
||||||
of Gabor kernels with specific lobe number $\kn$ and
|
logarithmic compression and hence $\db(t)$ are skipped.
|
||||||
either $+$ or $-$ sign, sorted (dark to light) first by
|
\textbf{a}:~Examples of $\filt(t)$, $\env(t)$,
|
||||||
increasing $\kn$ and then by
|
$\adapt(t)$, $c_i(t)$, and $f_i(t)$ for different $\sca$.
|
||||||
sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
\textbf{b}:~Intensity measures over $\sca$. The median
|
||||||
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
over $k_i(t)$ is shown for $c_i(t)$ and $f_i(t)$. Dot
|
||||||
$16\,$ms per type; 8 types, 40 kernels in total).
|
indicates $95\,\%$ curve span for $f_i(t)$.
|
||||||
\textbf{a}:~Example representations of $\filt(t)$,
|
\textbf{c}:~Average value $\muf$ of each $f_i(t)$
|
||||||
$\env(t)$, $\adapt(t)$, $c_i(t)$, and $f_i(t)$ for
|
over $\sca$.
|
||||||
different $\sca$.
|
\textbf{d}:~Ratio of intensity measures from \textbf{b} to
|
||||||
\textbf{b}:~Intensity measures over $\sca$. For $c_i(t)$
|
the respective pure-noise reference for $\sca=0$.
|
||||||
and $f_i(t)$, the median over kernels is shown. Dots
|
\textbf{e}:~Ratio of $\muf$.
|
||||||
indicate $95\,\%$ curve span for $f_i(t)$.
|
|
||||||
\textbf{c}:~Average value $\mu_{f_i}$ of each feature
|
|
||||||
$f_i(t)$ over $\sca$.
|
|
||||||
\textbf{d}:~Ratios of intensity measures to the respective
|
|
||||||
reference value for input $\raw(t)=\noc(t)$. For $c_i(t)$
|
|
||||||
and $f_i(t)$, the median over kernel-specific ratios is
|
|
||||||
shown.
|
|
||||||
\textbf{e}:~Ratios of $\mu_{f_i}$.
|
|
||||||
\textbf{f}:~Distribution of kernel-specific $\sca$ that
|
\textbf{f}:~Distribution of kernel-specific $\sca$ that
|
||||||
correspond to $95\,\%$ curve span for $f_i(t)$. Dots
|
correspond to $95\,\%$ curve span for $f_i(t)$. Dot
|
||||||
indicate the value from \textbf{b}.
|
indicates value based on the median from \textbf{b}.
|
||||||
}
|
}
|
||||||
\label{fig:pipeline_short}
|
\label{fig:pipeline_short}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -1426,26 +1417,27 @@ distances~(Fig.\,\ref{fig:pipeline_field}a, bottom row).
|
|||||||
Input $\raw(t)$ consists of a song of \textit{P.
|
Input $\raw(t)$ consists of a song of \textit{P.
|
||||||
parallelus} recorded in the field at eight different
|
parallelus} recorded in the field at eight different
|
||||||
distances $d$ and is processed up to the feature set
|
distances $d$ and is processed up to the feature set
|
||||||
$f_i(t)$. Different color shades indicate different types
|
$f_i(t)$ using kernel-specific threshold values
|
||||||
of Gabor kernels with specific lobe number $\kn$ and
|
$\thr=2\cdot\sigma_{\eta_i}$ (appendix
|
||||||
either $+$ or $-$ sign, sorted (dark to light) first by
|
Fig.\,\ref{fig:app_field_kern-sd}). Different color shades
|
||||||
increasing $\kn$ and then by
|
indicate different types of Gabor kernels with specific
|
||||||
|
lobe number $\kn$ and either $+$ or $-$ sign, sorted (dark
|
||||||
|
to light) first by increasing $\kn$ and then by
|
||||||
sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
||||||
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
||||||
$16\,$ms per type; 8 types, 40 kernels in total).
|
$16\,$ms per type; 8 types, 40 $k_i(t)$ in total).
|
||||||
\textbf{a}:~$\filt(t)$, $\env(t)$, $\db(t)$, $\adapt(t)$,
|
\textbf{a}:~$\filt(t)$, $\env(t)$, $\db(t)$, $\adapt(t)$,
|
||||||
$c_i(t)$, and $f_i(t)$ at each $d$. A noise segment from
|
$c_i(t)$, and $f_i(t)$ at each $d$. A noise segment from
|
||||||
the same recording is shown for reference.
|
the same recording is shown for reference.
|
||||||
\textbf{b}:~Intensity measures over $d$. For $c_i(t)$
|
\textbf{b}:~Intensity measures over $d$. The median over
|
||||||
and $f_i(t)$, the median over kernels is shown.
|
$k_i(t)$ is shown for $c_i(t)$ and $f_i(t)$.
|
||||||
\textbf{c}:~Average value $\mu_{f_i}$ of each feature
|
\textbf{c}:~Average value $\muf$ of each $f_i(t)$ over
|
||||||
$f_i(t)$ over $d$.
|
$d$.
|
||||||
\textbf{d}:~Ratios of intensity measures to the respective
|
\textbf{d}:~Ratio of intensity measures from \textbf{b} to
|
||||||
value obtained from the noise reference. For $c_i(t)$ and
|
the respective value obtained from the noise reference.
|
||||||
$f_i(t)$, the median over kernel-specific ratios is shown.
|
\textbf{e}:~Ratio of standard deviation $\sigma_{c_i}$ of
|
||||||
\textbf{e}:~Ratios of standard deviation $\sigma_{c_i}$ of
|
|
||||||
each $c_i(t)$.
|
each $c_i(t)$.
|
||||||
\textbf{f}:~Ratios of $\mu_{f_i}$.
|
\textbf{f}:~Ratios of $\muf$.
|
||||||
}
|
}
|
||||||
\label{fig:pipeline_field}
|
\label{fig:pipeline_field}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -1470,8 +1462,8 @@ song, so that each dot within a subplot corresponds to a single feature
|
|||||||
$f_i(t)$. For the intraspecific
|
$f_i(t)$. For the intraspecific
|
||||||
comparisons~(Fig.\,\ref{fig:feat_cross_species}, upper triangular), the pairs
|
comparisons~(Fig.\,\ref{fig:feat_cross_species}, upper triangular), the pairs
|
||||||
of $\muf$ are distributed closely around the diagonal, with a minimum
|
of $\muf$ are distributed closely around the diagonal, with a minimum
|
||||||
correlation coefficient of $\rho=0.85$, a maximum of $\rho=0.99$, and a median
|
correlation coefficient of $\rho=0.82$, a maximum of $\rho=0.99$, and a median
|
||||||
of $\rho=0.92$. A given $f_i(t)$ thus tends to have a similar $\muf$ across
|
of $\rho=0.91$. A given $f_i(t)$ thus tends to have a similar $\muf$ across
|
||||||
different songs of the same species. In contrast, the pairs of $\muf$ for the
|
different songs of the same species. In contrast, the pairs of $\muf$ for the
|
||||||
interspecific comparisons~(Fig.\,\ref{fig:feat_cross_species}, lower
|
interspecific comparisons~(Fig.\,\ref{fig:feat_cross_species}, lower
|
||||||
triangular) are distributed in a variety of different ways, most in broader
|
triangular) are distributed in a variety of different ways, most in broader
|
||||||
@@ -1479,7 +1471,7 @@ clouds (e.g. \textit{C. biguttulus} vs. \textit{C. mollis}) but some more
|
|||||||
narrowly around the diagonal (e.g. \textit{P. parallelus} vs. \textit{C.
|
narrowly around the diagonal (e.g. \textit{P. parallelus} vs. \textit{C.
|
||||||
dispar}). The correlation coefficients $\rho$ vary widely between different
|
dispar}). The correlation coefficients $\rho$ vary widely between different
|
||||||
interspecific comparisons, with a minimum of $\rho=-0.1$, a maximum of
|
interspecific comparisons, with a minimum of $\rho=-0.1$, a maximum of
|
||||||
$\rho=0.92$, and a median of $\rho=0.53$. A given $f_i(t)$ therefore tends to
|
$\rho=0.91$, and a median of $\rho=0.40$. A given $f_i(t)$ therefore tends to
|
||||||
have a less similar $\muf$ across different species than within the same
|
have a less similar $\muf$ across different species than within the same
|
||||||
species, although certain exeptions exist~(Fig.\,\ref{fig:feat_cross_species},
|
species, although certain exeptions exist~(Fig.\,\ref{fig:feat_cross_species},
|
||||||
lower right). Accordingly, the feature representation that is generated by the
|
lower right). Accordingly, the feature representation that is generated by the
|
||||||
@@ -1498,18 +1490,17 @@ natural song variation.
|
|||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_features_cross_species.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_features_cross_species.pdf}
|
||||||
\caption{\textbf{Interspecific and intraspecific feature variability.}
|
\caption{\textbf{Interspecific and intraspecific feature variability.}
|
||||||
Average value $\mu_{f_i}$ of each feature $f_i(t)$ against
|
Average value $\muf$ of each feature $f_i(t)$ against its
|
||||||
its counterpart from a 2nd feature set based on a
|
counterpart from a 2nd feature set based on a different
|
||||||
different input $\raw(t)$. Each dot within a subplot
|
input $\raw(t)$. Data is based on the saturated $\muf$
|
||||||
represents a single feature $f_i(t)$. Different color
|
from Fig.\,\ref{fig:pipeline_full}. Each dot within a
|
||||||
|
subplot represents a single $f_i(t)$. Different color
|
||||||
shades indicate different types of Gabor kernels with
|
shades indicate different types of Gabor kernels with
|
||||||
specific lobe number $\kn$ and either $+$ or $-$ sign,
|
specific lobe number $\kn$ and either $+$ or $-$ sign,
|
||||||
sorted (dark to light) first by increasing $\kn$ and then
|
sorted (dark to light) first by increasing $\kn$ and then
|
||||||
by sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
by sign~($1\,\leq\,\kn\,\leq\,4$; first $+$, then $-$ for
|
||||||
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
each $\kn$; five kernel widths $\kw$ of 1, 2, 4, 8, and
|
||||||
$16\,$ms per type; 8 types, 40 kernels in total). Data is
|
$16\,$ms per type; 8 types, 40 kernels in total).
|
||||||
based on the analysis underlying
|
|
||||||
Fig\,\ref{fig:pipeline_full}.
|
|
||||||
\textbf{Lower triangular}:~Interspecific comparisons
|
\textbf{Lower triangular}:~Interspecific comparisons
|
||||||
between single songs of different species.
|
between single songs of different species.
|
||||||
\textbf{Upper triangular}:~Intraspecific comparisons
|
\textbf{Upper triangular}:~Intraspecific comparisons
|
||||||
@@ -1524,7 +1515,8 @@ natural song variation.
|
|||||||
\end{figure}
|
\end{figure}
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\section{Conclusions \& outlook}
|
\newpage
|
||||||
|
\section{Discussion}
|
||||||
|
|
||||||
% RIPPED FROM INTRODUCTION:
|
% RIPPED FROM INTRODUCTION:
|
||||||
|
|
||||||
@@ -1677,105 +1669,189 @@ $\rightarrow$ Graded again but highly decorrelated from the acoustic stimulus\\
|
|||||||
$\rightarrow$ Parameters of a behavioral response may be graded (e.g. approach speed),
|
$\rightarrow$ Parameters of a behavioral response may be graded (e.g. approach speed),
|
||||||
initiation of one behavior over another is categorical (e.g. approach/stay)
|
initiation of one behavior over another is categorical (e.g. approach/stay)
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
\section{Appendix}
|
||||||
|
|
||||||
|
% Not sure if we really need this one. Might raise more questions than it
|
||||||
|
% provides answers. The noise component is not stable throughout nonlinear
|
||||||
|
% transformations, that is all the reader needs to know, i believe.
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_noise_env_sd_conversion_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_noise_env_sd_conversion_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Conversion of the noise component by envelope extraction.}
|
||||||
}
|
Standard deviation $\sigma_{\eta}$ of noise component
|
||||||
|
$\noc(t)$ within the signal envelope $\env(t)$ over scale
|
||||||
|
$\sca$. Based on input $\raw(t)$ with $\sigma_{\eta}=1$
|
||||||
|
(corresponding to the analysis underlying
|
||||||
|
Fig.\,\ref{fig:rect-lp}), using 100 realizations of
|
||||||
|
$\noc(t)$.}
|
||||||
\label{fig:app_env-sd}
|
\label{fig:app_env-sd}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_rect-lp_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_rect-lp_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Species-specific data underlying Fig.\,\ref{fig:rect-lp}e.}
|
||||||
}
|
Ratio of the standard deviation $\sigma_{\text{env}}$ to
|
||||||
|
the pure-noise reference $\sigma_{\eta}$ of the signal
|
||||||
|
envelope $\env(t)$ over scale $\sca$ for different cutoff
|
||||||
|
frequencies $\fc$ of the lowpass filter extracting
|
||||||
|
$\env(t)$. Solid lines and shaded areas indicate mean
|
||||||
|
$\pm$ standard deviation across songs per recording.
|
||||||
|
Dashed lines indicate mean across recordings (shown in
|
||||||
|
Fig.\,\ref{fig:rect-lp}e).}
|
||||||
\label{fig:app_rect-lp}
|
\label{fig:app_rect-lp}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_log-hp_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_log-hp_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Species-specific data underlying Fig.\,\ref{fig:log-hp}e.}
|
||||||
}
|
Ratio of the standard deviation $\sigma_{\text{adapt}}$ to
|
||||||
|
the pure-noise reference $\sigma_{\eta}$ of the
|
||||||
|
intensity-adapted envelope $\adapt(t)$ over scale $\sca$.
|
||||||
|
Solid lines and shaded areas indicate mean $\pm$ standard
|
||||||
|
deviation across songs per recording. Dashed lines
|
||||||
|
indicate mean across recordings (shown in
|
||||||
|
Fig.\,\ref{fig:log-hp}e).}
|
||||||
\label{fig:app_log-hp_curves}
|
\label{fig:app_log-hp_curves}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_saturation_log-hp_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_saturation_log-hp_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Species-specific saturation points underlying
|
||||||
}
|
Fig.\,\ref{fig:log-hp}e.}
|
||||||
|
Distribution of saturation points ($95\,\%$ curve span) of
|
||||||
|
ratio $\sigma_{\text{adapt}} / \sigma_{\eta}$ of the
|
||||||
|
intensity-adapted envelope $\adapt(t)$ over scale $\sca$
|
||||||
|
across all available songs. Dots indicate the saturation
|
||||||
|
point of the mean curve across songs and recordings (shown
|
||||||
|
in Fig.\,\ref{fig:log-hp}e, see also appendix
|
||||||
|
Fig.\,\ref{fig:app_log-hp_curves}).}
|
||||||
\label{fig:app_log-hp_saturation}
|
\label{fig:app_log-hp_saturation}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_thresh-lp_pure_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_thresh-lp_pure_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Species-specific data underlying Fig.\,\ref{fig:thresh-lp_species}bd.}
|
||||||
}
|
Average value $\muf$ of each of the three features
|
||||||
|
$f_i(t)$ over scale $\sca$ in the noiseless case. Solid
|
||||||
|
lines and shaded areas indicate mean $\pm$ standard
|
||||||
|
deviation across songs per recording. Dashed lines
|
||||||
|
indicate mean across recordings (shown in
|
||||||
|
Fig.\,\ref{fig:thresh-lp_species}bd).}
|
||||||
\label{fig:app_thresh-lp_pure}
|
\label{fig:app_thresh-lp_pure}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_thresh-lp_noise_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_thresh-lp_noise_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Species-specific data underlying Fig.\,\ref{fig:thresh-lp_species}ce.}
|
||||||
}
|
Average value $\muf$ of each of the three features
|
||||||
|
$f_i(t)$ over scale $\sca$ in the noisy case. Solid lines
|
||||||
|
and shaded areas indicate mean $\pm$ standard deviation
|
||||||
|
across songs per recording. Dashed lines indicate mean
|
||||||
|
across recordings (shown in
|
||||||
|
Fig.\,\ref{fig:thresh-lp_species}ce).}
|
||||||
\label{fig:app_thresh-lp_noise}
|
\label{fig:app_thresh-lp_noise}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Relation between threshold value and pure-noise feature
|
||||||
|
value for Fig.\,\ref{fig:thresh-lp_single} and
|
||||||
|
Fig.\,\ref{fig:thresh-lp_species}.}
|
||||||
|
Proportion of pure-noise kernel response $c_i(t)$ that
|
||||||
|
exceeds threshold value $\thr$ --- which determines the
|
||||||
|
average value $\muf$ of feature $f_i(t)$ --- over $\thr$
|
||||||
|
in multiples of standard deviation $\sigma_{c_i}$.
|
||||||
|
Corresponds to a "reverse" cumulative distribution
|
||||||
|
function of $c_i(t)$. Black solid lines indicate rCDF per
|
||||||
|
kernel $k_i(t)$. Red dashed line indicates rCDF for a
|
||||||
|
normal distribution with $\mu=0$ and $\sigma=1$.
|
||||||
}
|
}
|
||||||
\label{fig:app_thresh-lp_kern-sd}
|
\label{fig:app_thresh-lp_kern-sd}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_full_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_full_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Relation between threshold value and pure-noise feature
|
||||||
|
value for Fig.\,\ref{fig:pipeline_full}.}
|
||||||
|
Proportion of pure-noise kernel response $c_i(t)$ that
|
||||||
|
exceeds threshold value $\thr$ --- which determines the
|
||||||
|
average value $\muf$ of feature $f_i(t)$ --- over $\thr$
|
||||||
|
in multiples of standard deviation $\sigma_{c_i}$.
|
||||||
|
Corresponds to a "reverse" cumulative distribution
|
||||||
|
function of $c_i(t)$. Black solid lines indicate rCDF per
|
||||||
|
kernel $k_i(t)$. Red dashed line indicates rCDF for a
|
||||||
|
normal distribution with $\mu=0$ and $\sigma=1$.
|
||||||
}
|
}
|
||||||
\label{fig:app_full_kern-sd}
|
\label{fig:app_full_kern-sd}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_short_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_short_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Relation between threshold value and pure-noise feature
|
||||||
|
value for Fig.\,\ref{fig:pipeline_short}.}
|
||||||
|
Proportion of pure-noise kernel response $c_i(t)$ that
|
||||||
|
exceeds threshold value $\thr$ --- which determines the
|
||||||
|
average value $\muf$ of feature $f_i(t)$ --- over $\thr$
|
||||||
|
in multiples of standard deviation $\sigma_{c_i}$.
|
||||||
|
Corresponds to a "reverse" cumulative distribution
|
||||||
|
function of $c_i(t)$. Black solid lines indicate rCDF per
|
||||||
|
kernel $k_i(t)$. Red dashed line indicates rCDF for a
|
||||||
|
normal distribution with $\mu=0$ and $\sigma=1$.
|
||||||
}
|
}
|
||||||
\label{fig:app_short_kern-sd}
|
\label{fig:app_short_kern-sd}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_field_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_kernel_sd_perc_field_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Relation between threshold value and pure-noise feature
|
||||||
|
value for Fig.\,\ref{fig:pipeline_field}.}
|
||||||
|
Proportion of pure-noise kernel response $c_i(t)$ that
|
||||||
|
exceeds threshold value $\thr$ --- which determines the
|
||||||
|
average value $\muf$ of feature $f_i(t)$ --- over $\thr$
|
||||||
|
in multiples of standard deviation $\sigma_{c_i}$.
|
||||||
|
Corresponds to a "reverse" cumulative distribution
|
||||||
|
function of $c_i(t)$. Black solid lines indicate rCDF per
|
||||||
|
kernel $k_i(t)$. Red dashed line indicates rCDF for a
|
||||||
|
normal distribution with $\mu=0$ and $\sigma=1$.
|
||||||
}
|
}
|
||||||
\label{fig:app_field_kern-sd}
|
\label{fig:app_field_kern-sd}
|
||||||
\end{figure}
|
\end{figure}% Referenced.
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[!ht]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=\textwidth]{figures/fig_invariance_cross_species_thresh_appendix.pdf}
|
\includegraphics[width=\textwidth]{figures/fig_invariance_cross_species_thresh_appendix.pdf}
|
||||||
\caption{\textbf{}
|
\caption{\textbf{Threshold-dependent intensity invariance of
|
||||||
|
species-specific feature sets.}
|
||||||
|
Same input and processing as in
|
||||||
|
Fig.\,\ref{fig:pipeline_full}, using different
|
||||||
|
kernel-specific threshold values $\thr$ (multiples of
|
||||||
|
pure-noise standard deviation $\sigma_{\eta_i}$ of
|
||||||
|
$c_i(t)$ for $\sca=0$. See also appendix
|
||||||
|
Fig.\,\ref{fig:app_full_kern-sd}). Average value $\muf$ of
|
||||||
|
each feature $f_i(t)$ over $\sca$.
|
||||||
}
|
}
|
||||||
\label{fig:app_cross_species_thresh}
|
\label{fig:app_cross_species_thresh}
|
||||||
\end{figure}
|
\end{figure}% Reference this one!
|
||||||
\FloatBarrier
|
\FloatBarrier
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import plotstyle_plt
|
import plotstyle_plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from plot_functions import xlabel, ylabel, strip_zeros, letter_subplots
|
from plot_functions import xlabel, ylabel
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
data_path = '../data/inv/noise_env/sd_conversion.npz'
|
data_path = '../data/inv/noise_env/sd_conversion.npz'
|
||||||
@@ -10,16 +10,14 @@ save_path = '../figures/fig_noise_env_sd_conversion_appendix.pdf'
|
|||||||
# PLOT SETTINGS:
|
# PLOT SETTINGS:
|
||||||
fig_kwargs = dict(
|
fig_kwargs = dict(
|
||||||
figsize=(32/2.54, 16/2.54),
|
figsize=(32/2.54, 16/2.54),
|
||||||
nrows=2,
|
nrows=1,
|
||||||
ncols=1,
|
ncols=1,
|
||||||
sharex=True,
|
|
||||||
sharey=True,
|
|
||||||
gridspec_kw=dict(
|
gridspec_kw=dict(
|
||||||
wspace=0,
|
wspace=0,
|
||||||
hspace=0.1,
|
hspace=0,
|
||||||
left=0.09,
|
left=0.08,
|
||||||
right=0.98,
|
right=0.98,
|
||||||
bottom=0.08,
|
bottom=0.1,
|
||||||
top=0.95,
|
top=0.95,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -30,81 +28,41 @@ grid_line_kwargs = dict(
|
|||||||
color='k',
|
color='k',
|
||||||
lw=0.5,
|
lw=0.5,
|
||||||
)
|
)
|
||||||
trial_kwargs = dict(
|
|
||||||
color='k',
|
|
||||||
alpha=0.5,
|
|
||||||
lw=0.5,
|
|
||||||
)
|
|
||||||
line_kwargs = dict(
|
line_kwargs = dict(
|
||||||
color='black',
|
c='k',
|
||||||
lw=1,
|
lw=0.5,
|
||||||
)
|
|
||||||
fill_kwargs = dict(
|
|
||||||
color='k',
|
|
||||||
alpha=0.5,
|
alpha=0.5,
|
||||||
)
|
)
|
||||||
xlabels = dict(
|
xlab = '$\\text{scale }\\alpha$'
|
||||||
bottom='$\\text{scale }\\alpha$',
|
|
||||||
)
|
|
||||||
ylabels = dict(
|
|
||||||
top='$\\sigma_{\\eta}\\,(PLACEHOLDER \\,\\text{realizations})$',
|
|
||||||
bottom='$\\sigma_{\\eta}\\,(\\text{mean}\\,\\pm\\,\\text{SD})$',
|
|
||||||
)
|
|
||||||
xlab_kwargs = dict(
|
xlab_kwargs = dict(
|
||||||
y=0,
|
y=0,
|
||||||
fontsize=20,
|
fontsize=20,
|
||||||
ha='center',
|
ha='center',
|
||||||
va='bottom',
|
va='bottom',
|
||||||
)
|
)
|
||||||
|
ylab = '$\\sigma_{\\eta}$'
|
||||||
ylab_kwargs = dict(
|
ylab_kwargs = dict(
|
||||||
x=0,
|
x=0,
|
||||||
fontsize=20,
|
fontsize=20,
|
||||||
ha='center',
|
ha='center',
|
||||||
va='top',
|
va='top',
|
||||||
)
|
)
|
||||||
title_kwargs = dict(
|
|
||||||
t='$\\sigma_{\\text{filt}}\\,=$',
|
|
||||||
x=0.5,
|
|
||||||
y=1,
|
|
||||||
ha='center',
|
|
||||||
va='top',
|
|
||||||
fontsize=20,
|
|
||||||
)
|
|
||||||
letter_kwargs = dict(
|
|
||||||
x=0.005,
|
|
||||||
y=0.99,
|
|
||||||
fontsize=22,
|
|
||||||
ha='left',
|
|
||||||
va='top',
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fetch data:
|
# Fetch data:
|
||||||
data = dict(np.load('../data/inv/noise_env/sd_conversion.npz'))
|
data = dict(np.load('../data/inv/noise_env/sd_conversion.npz'))
|
||||||
n = data['n_trials']
|
|
||||||
|
|
||||||
# Adjust parameters:
|
|
||||||
ylabels['top'] = f'$\\sigma_{{\\eta}}\\,({data["n_trials"]}\\text{{ realizations}})$'
|
|
||||||
title_kwargs['t'] += f'$\\,{strip_zeros(data["sd_factor"])}$'
|
|
||||||
|
|
||||||
# Prepare graph:
|
# Prepare graph:
|
||||||
fig, (ax1, ax2) = plt.subplots(**fig_kwargs)
|
fig, ax = plt.subplots(**fig_kwargs)
|
||||||
fig.suptitle(**title_kwargs)
|
ax.grid(**grid_line_kwargs)
|
||||||
ax1.grid(**grid_line_kwargs)
|
ax.set_xlim(data['scales'][0], data['scales'][-1])
|
||||||
ax1.set_xlim(data['scales'][0], data['scales'][-1])
|
ax.set_xscale('symlog', linthresh=data['scales'][1], linscale=0.5)
|
||||||
ax1.set_xscale('symlog', linthresh=data['scales'][1], linscale=0.5)
|
ax.set_ylim(0, 0.08)
|
||||||
ax1.set_ylim(0, 0.1)
|
ax.yaxis.set_major_locator(plt.MultipleLocator(0.02))
|
||||||
ylabel(ax1, ylabels['top'], transform=fig.transFigure, **ylab_kwargs)
|
xlabel(ax, xlab, transform=fig.transFigure, **xlab_kwargs)
|
||||||
ax2.grid(**grid_line_kwargs)
|
ylabel(ax, ylab, transform=fig.transFigure, **ylab_kwargs)
|
||||||
xlabel(ax2, xlabels['bottom'], transform=fig.transFigure, **xlab_kwargs)
|
|
||||||
ylabel(ax2, ylabels['bottom'], transform=fig.transFigure, **ylab_kwargs)
|
|
||||||
letter_subplots((ax1, ax2), **letter_kwargs)
|
|
||||||
|
|
||||||
# Plot individual trials:
|
# Plot individual trials:
|
||||||
ax1.plot(data['scales'], data['trials'], **trial_kwargs)
|
ax.plot(data['scales'], data['sd_noise'][..., 0], **line_kwargs)
|
||||||
|
|
||||||
# Plot mean and spread across trials:
|
|
||||||
ax2.plot(data['scales'], data['mean'], **line_kwargs)
|
|
||||||
ax2.fill_between(data['scales'], data['mean'] - data['spread'], data['mean'] + data['spread'], **fill_kwargs)
|
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(save_path)
|
fig.savefig(save_path)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ save_path = '../figures/fig_features_cross_species.pdf'
|
|||||||
|
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
thresh_rel = np.array([0, 0.5, 1, 1.5, 2, 2.5, 3])[5]
|
thresh_rel = np.array([0, 0.5, 1, 1.5, 2, 2.5, 3])[4]
|
||||||
single_spec_file = True # Only use example files for cross-species comparison
|
single_spec_file = True # Only use example files for cross-species comparison
|
||||||
equalize_spec_files = False # Prune to minimum available across species
|
equalize_spec_files = False # Prune to minimum available across species
|
||||||
n_song = n_spec#None # Limit to n first songs of in-species dataset (None for all)
|
n_song = n_spec#None # Limit to n first songs of in-species dataset (None for all)
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ from IPython import embed
|
|||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target_species = [
|
target_species = [
|
||||||
# 'Chorthippus_biguttulus',
|
'Chorthippus_biguttulus',
|
||||||
# 'Chorthippus_mollis',
|
'Chorthippus_mollis',
|
||||||
# 'Chrysochraon_dispar',
|
'Chrysochraon_dispar',
|
||||||
# 'Euchorthippus_declivus',
|
# 'Euchorthippus_declivus',
|
||||||
'Gomphocerippus_rufus',
|
'Gomphocerippus_rufus',
|
||||||
'Omocestus_rufipes',
|
'Omocestus_rufipes',
|
||||||
@@ -35,7 +35,15 @@ save_path = '../figures/fig_invariance_cross_species_thresh_appendix.pdf'
|
|||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
exclude_zero = True
|
exclude_zero = True
|
||||||
thresh_rel = np.array([0, 0.5, 1, 1.5, 2, 2.5, 3])
|
thresh_rel = np.array([
|
||||||
|
# 0,
|
||||||
|
0.5,
|
||||||
|
1,
|
||||||
|
# 1.5,
|
||||||
|
2,
|
||||||
|
# 2.5,
|
||||||
|
3,
|
||||||
|
])
|
||||||
|
|
||||||
# SUBSET SETTINGS:
|
# SUBSET SETTINGS:
|
||||||
types = np.array([1, -1, 2, -2, 3, -3, 4, -4])
|
types = np.array([1, -1, 2, -2, 3, -3, 4, -4])
|
||||||
@@ -53,15 +61,15 @@ fig_kwargs = dict(
|
|||||||
sharex=True,
|
sharex=True,
|
||||||
sharey=True,
|
sharey=True,
|
||||||
gridspec_kw=dict(
|
gridspec_kw=dict(
|
||||||
wspace=0.2,
|
wspace=0.3,
|
||||||
hspace=0.75,
|
hspace=0.5,
|
||||||
left=0.1,
|
left=0.1,
|
||||||
right=0.95,
|
right=0.97,
|
||||||
bottom=0.08,
|
bottom=0.1,
|
||||||
top=0.98,
|
top=0.98,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
inset_x_bounds = [0, -0.5, 1, 0.4]
|
inset_x_bounds = [0, -0.3, 1, 0.25]
|
||||||
inset_y_bounds = [1.01, 0, 0.1, 1]
|
inset_y_bounds = [1.01, 0, 0.1, 1]
|
||||||
|
|
||||||
# PLOT SETTINGS:
|
# PLOT SETTINGS:
|
||||||
@@ -162,6 +170,7 @@ y_dist_kwargs = dict(
|
|||||||
fig, axes = plt.subplots(**fig_kwargs)
|
fig, axes = plt.subplots(**fig_kwargs)
|
||||||
axes[0, 0].set_ylim(0, 1)
|
axes[0, 0].set_ylim(0, 1)
|
||||||
axes[0, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc))
|
axes[0, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc))
|
||||||
|
axes[0, 0].xaxis.set_major_locator(plt.LogLocator(base=10, subs=(1,)))
|
||||||
super_xlabel(xlab, fig, axes[-1, 0], axes[-1, -1], **xlab_kwargs)
|
super_xlabel(xlab, fig, axes[-1, 0], axes[-1, -1], **xlab_kwargs)
|
||||||
super_ylabel(ylab, fig, axes[0, 0], axes[-1, 0], **ylab_super_kwargs)
|
super_ylabel(ylab, fig, axes[0, 0], axes[-1, 0], **ylab_super_kwargs)
|
||||||
for ax, species in zip(axes[0, :], target_species):
|
for ax, species in zip(axes[0, :], target_species):
|
||||||
@@ -197,25 +206,27 @@ for i, species in enumerate(target_species):
|
|||||||
symlog_kwargs = dict(linthresh=scales[scales > 0][0], linscale=0.5)
|
symlog_kwargs = dict(linthresh=scales[scales > 0][0], linscale=0.5)
|
||||||
|
|
||||||
# Run through thresholds:
|
# Run through thresholds:
|
||||||
for j in range(thresh_rel.size):
|
for j, thresh in enumerate(thresh_rel):
|
||||||
ax = axes[j, i]
|
ax = axes[j, i]
|
||||||
|
ind = np.nonzero(data['thresh_rel'] == thresh)[0][0]
|
||||||
|
|
||||||
# Plot swarm of feature-specific intensity curves:
|
# Plot swarm of feature-specific intensity curves:
|
||||||
handles = ax.plot(scales, measure[:, :, j], lw=lw['swarm'])
|
handles = ax.plot(scales, measure[:, :, ind], lw=lw['swarm'])
|
||||||
assign_colors(handles, config['k_specs'][:, 0], kern_colors)
|
assign_colors(handles, config['k_specs'][:, 0], kern_colors)
|
||||||
reorder_by_sd(handles, measure[:, :, j])
|
reorder_by_sd(handles, measure[:, :, ind])
|
||||||
|
|
||||||
# Plot single compressed intensity curve:
|
# Plot single compressed intensity curve:
|
||||||
compressed = np.median(measure[:, :, j], axis=1)
|
compressed = np.median(measure[:, :, ind], axis=1)
|
||||||
ax.plot(scales, compressed, **median_kwargs)
|
ax.plot(scales, compressed, **median_kwargs)
|
||||||
|
|
||||||
# Plot distribution of saturation levels:
|
# Plot distribution of saturation levels:
|
||||||
inset = ax.inset_axes(inset_y_bounds)
|
inset = ax.inset_axes(inset_y_bounds)
|
||||||
inset.set_ylim(0, 1)
|
inset.set_ylim(0, 1)
|
||||||
inset.axis('off')
|
inset.axis('off')
|
||||||
y_dist(inset, measure[-1, :, j], **y_dist_kwargs)
|
y_dist(inset, measure[-1, :, ind], **y_dist_kwargs)
|
||||||
|
|
||||||
# Plot distribution of saturation points:
|
# Plot distribution of saturation points:
|
||||||
crit_inds = np.array(get_saturation(measure[:, :, j], **plateau_settings)[1])
|
crit_inds = np.array(get_saturation(measure[:, :, ind], **plateau_settings)[1])
|
||||||
if np.isnan(crit_inds).sum():
|
if np.isnan(crit_inds).sum():
|
||||||
print(f'WARNING: No saturation points found for {species} at threshold {thresh_rel[j]}')
|
print(f'WARNING: No saturation points found for {species} at threshold {thresh_rel[j]}')
|
||||||
crit_inds = crit_inds[~np.isnan(crit_inds)].astype(int)
|
crit_inds = crit_inds[~np.isnan(crit_inds)].astype(int)
|
||||||
@@ -223,12 +234,13 @@ for i, species in enumerate(target_species):
|
|||||||
inset = ax.inset_axes(inset_x_bounds)
|
inset = ax.inset_axes(inset_x_bounds)
|
||||||
inset.set_xlim(scales[0], scales[-1])
|
inset.set_xlim(scales[0], scales[-1])
|
||||||
inset.set_xscale('symlog', **symlog_kwargs)
|
inset.set_xscale('symlog', **symlog_kwargs)
|
||||||
|
inset.xaxis.set_major_locator(plt.LogLocator(base=10, subs=(1,)))
|
||||||
hide_axis(inset, 'left')
|
hide_axis(inset, 'left')
|
||||||
if j < thresh_rel.size - 1:
|
if j < thresh_rel.size - 1:
|
||||||
hide_ticks(inset, 'bottom')
|
hide_ticks(inset, 'bottom')
|
||||||
x_dist(inset, crit_scales, **x_dist_kwargs)
|
x_dist(inset, crit_scales, **x_dist_kwargs)
|
||||||
|
|
||||||
if j > 0:
|
if thresh > 0:
|
||||||
# Plot single saturation point:
|
# Plot single saturation point:
|
||||||
crit_ind = get_saturation(compressed, **plateau_settings)[1]
|
crit_ind = get_saturation(compressed, **plateau_settings)[1]
|
||||||
crit_scale = scales[crit_ind]
|
crit_scale = scales[crit_ind]
|
||||||
@@ -237,6 +249,7 @@ for i, species in enumerate(target_species):
|
|||||||
# Posthocs:
|
# Posthocs:
|
||||||
axes[0, 0].set_xscale('symlog', **symlog_kwargs)
|
axes[0, 0].set_xscale('symlog', **symlog_kwargs)
|
||||||
axes[0, 0].set_xlim(scales[0], scales[-1])
|
axes[0, 0].set_xlim(scales[0], scales[-1])
|
||||||
|
axes[0, 0].xaxis.set_major_locator(plt.LogLocator(base=10, subs=(1,)))
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(save_path)
|
fig.savefig(save_path)
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ from plot_functions import xlabel, ylabel
|
|||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
# Analysis settings:
|
# Analysis settings:
|
||||||
mode = ['thresh_lp', 'full', 'short', 'field'][3]
|
mode = ['thresh_lp', 'full', 'short', 'field'][0]
|
||||||
thresh_path = f'../data/inv/{mode}/thresholds.npz'
|
thresh_path = f'../data/inv/{mode}/thresholds.npz'
|
||||||
save_path = f'../figures/fig_kernel_sd_perc_{mode}_appendix.pdf'
|
save_path = f'../figures/fig_kernel_sd_perc_{mode}_appendix.pdf'
|
||||||
|
|
||||||
# Plot settings:
|
# Plot settings:
|
||||||
fig_kwargs = dict(
|
fig_kwargs = dict(
|
||||||
figsize=(32/2.54, 16/2.54),
|
figsize=(32/2.54, 15/2.54),
|
||||||
nrows=1,
|
nrows=1,
|
||||||
ncols=1,
|
ncols=1,
|
||||||
gridspec_kw=dict(
|
gridspec_kw=dict(
|
||||||
@@ -41,8 +41,8 @@ grid_line_kwargs = dict(
|
|||||||
color='k',
|
color='k',
|
||||||
lw=0.5,
|
lw=0.5,
|
||||||
)
|
)
|
||||||
xlab = '$\\text{multiple of }\\sigma_{k_i}$'
|
xlab = '$\\Theta_i\\,[\\text{multiples of }\\sigma_{c_i}]$'
|
||||||
ylab = '$P\\,(c_i > \\Theta_i)$'
|
ylab = '$\\mu_{f_i}\\,\\approx\\,P\\,(c_i > \\Theta_i)$'
|
||||||
xlab_kwargs = dict(
|
xlab_kwargs = dict(
|
||||||
y=0,
|
y=0,
|
||||||
fontsize=20,
|
fontsize=20,
|
||||||
@@ -55,6 +55,8 @@ ylab_kwargs = dict(
|
|||||||
ha='center',
|
ha='center',
|
||||||
va='top',
|
va='top',
|
||||||
)
|
)
|
||||||
|
xloc = 1
|
||||||
|
yloc = 0.25
|
||||||
|
|
||||||
# Load threshold data:
|
# Load threshold data:
|
||||||
data = dict(np.load(thresh_path))
|
data = dict(np.load(thresh_path))
|
||||||
@@ -69,6 +71,8 @@ fig, ax = plt.subplots(**fig_kwargs)
|
|||||||
ax.grid(**grid_line_kwargs)
|
ax.grid(**grid_line_kwargs)
|
||||||
ax.set_xlim(factors[0], factors[-1])
|
ax.set_xlim(factors[0], factors[-1])
|
||||||
ax.set_ylim(-0.01, 1.01)
|
ax.set_ylim(-0.01, 1.01)
|
||||||
|
ax.xaxis.set_major_locator(plt.MultipleLocator(xloc))
|
||||||
|
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc))
|
||||||
ylabel(ax, ylab, transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax, ylab, transform=fig.transFigure, **ylab_kwargs)
|
||||||
xlabel(ax, xlab, transform=fig.transFigure, **xlab_kwargs)
|
xlabel(ax, xlab, transform=fig.transFigure, **xlab_kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ stages = ['filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
|||||||
save_path = '../figures/'
|
save_path = '../figures/'
|
||||||
|
|
||||||
# GRAPH SETTINGS:
|
# GRAPH SETTINGS:
|
||||||
fig_kwargs = dict(
|
fig_pre_kwargs = dict(
|
||||||
figsize=(32/2.54, 16/2.54),
|
figsize=(32/2.54, 16/2.54),
|
||||||
sharex='col',
|
sharex='col',
|
||||||
subplot_kw=dict(
|
subplot_kw=dict(
|
||||||
@@ -28,10 +28,17 @@ fig_kwargs = dict(
|
|||||||
hspace=0.3,
|
hspace=0.3,
|
||||||
left=0.12,
|
left=0.12,
|
||||||
right=0.99,
|
right=0.99,
|
||||||
bottom=0.08,
|
bottom=0.09,
|
||||||
top=0.95
|
top=0.97
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
fig_feat_kwargs = fig_pre_kwargs.copy()
|
||||||
|
fig_feat_kwargs['gridspec_kw'] = fig_pre_kwargs['gridspec_kw'].copy()
|
||||||
|
fig_feat_kwargs['gridspec_kw'].update(dict(
|
||||||
|
left=0.09,
|
||||||
|
wspace=0.15,
|
||||||
|
hspace=0.2,
|
||||||
|
))
|
||||||
|
|
||||||
# PLOT SETTINGS:
|
# PLOT SETTINGS:
|
||||||
fs = dict(
|
fs = dict(
|
||||||
@@ -76,13 +83,15 @@ xlab_kwargs = dict(
|
|||||||
va='bottom',
|
va='bottom',
|
||||||
fontsize=fs['lab_norm'],
|
fontsize=fs['lab_norm'],
|
||||||
)
|
)
|
||||||
ylab_kwargs = dict(
|
ylab_pre_kwargs = dict(
|
||||||
x=0.03,
|
x=0.03,
|
||||||
rotation=0,
|
rotation=0,
|
||||||
ha='center',
|
ha='center',
|
||||||
va='center',
|
va='center',
|
||||||
fontsize=fs['lab_tex'],
|
fontsize=fs['lab_tex'],
|
||||||
)
|
)
|
||||||
|
ylab_feat_kwargs = ylab_pre_kwargs.copy()
|
||||||
|
ylab_feat_kwargs['x'] = 0.02
|
||||||
xloc = dict(
|
xloc = dict(
|
||||||
full=2,
|
full=2,
|
||||||
zoom=0.2
|
zoom=0.2
|
||||||
@@ -98,42 +107,28 @@ yloc_full = dict(
|
|||||||
yloc_zoom = dict(
|
yloc_zoom = dict(
|
||||||
filt=0.1,
|
filt=0.1,
|
||||||
env=0.02,
|
env=0.02,
|
||||||
log=50,
|
log=25,
|
||||||
inv=10,
|
inv=10,
|
||||||
conv=0.5,
|
conv=0.5,
|
||||||
feat=1
|
feat=1
|
||||||
)
|
)
|
||||||
letter_kwargs = dict(
|
letter_kwargs = dict(
|
||||||
x=0,
|
xref=0,
|
||||||
y=1,
|
y=1,
|
||||||
ha='left',
|
ha='left',
|
||||||
va='bottom',
|
va='center',
|
||||||
fontsize=fs['letter'],
|
fontsize=fs['letter'],
|
||||||
)
|
)
|
||||||
zoom_rel = np.array([0.3, 0.4])
|
zoom_rel = np.array([0.295, 0.4])
|
||||||
zoom_kwargs = dict(
|
zoom_kwargs = dict(
|
||||||
color=3 * (0.85,),
|
color=3 * (0.85,),
|
||||||
zorder=0,
|
zorder=0,
|
||||||
linewidth=0
|
linewidth=0
|
||||||
)
|
)
|
||||||
# kernels = np.array([
|
types = np.array([1, -1, 2, -2, 3, -3, 4, -4])
|
||||||
# [1, 0.002],
|
# types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]
|
||||||
# [1, 0.016],
|
sigmas = np.array([0.004, 0.032])
|
||||||
# [-1, 0.004],
|
# sigmas = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032]
|
||||||
# [-1, 0.032],
|
|
||||||
# [2, 0.004],
|
|
||||||
# [2, 0.016],
|
|
||||||
# [-2, 0.002],
|
|
||||||
# [-2, 0.032],
|
|
||||||
# [3, 0.008],
|
|
||||||
# [3, 0.032],
|
|
||||||
# [-3, 0.008],
|
|
||||||
# [-3, 0.032],
|
|
||||||
# [4, 0.004],
|
|
||||||
# [4, 0.032],
|
|
||||||
# [-4, 0.004],
|
|
||||||
# [-4, 0.032]
|
|
||||||
# ])
|
|
||||||
t = [1, -1, 2, -2, 3, -3, 4, -4]
|
t = [1, -1, 2, -2, 3, -3, 4, -4]
|
||||||
s = [0.004, 0.032]
|
s = [0.004, 0.032]
|
||||||
kernels = np.array([[i, j] for i in t for j in s])
|
kernels = np.array([[i, j] for i in t for j in s])
|
||||||
@@ -162,31 +157,31 @@ for data_path in data_paths:
|
|||||||
|
|
||||||
|
|
||||||
# PART I: PREPROCESSING STAGE
|
# PART I: PREPROCESSING STAGE
|
||||||
fig, axes = plt.subplots(4, 2, **fig_kwargs)
|
fig, axes = plt.subplots(4, 2, **fig_pre_kwargs)
|
||||||
super_xlabel(xlabels['super'], fig, axes[0, 0], axes[0, -1], **xlab_kwargs)
|
super_xlabel(xlabels['super'], fig, axes[0, 0], axes[0, -1], **xlab_kwargs)
|
||||||
[hide_axis(ax, 'bottom') for ax in axes[:-1, :].ravel()]
|
[hide_axis(ax, 'bottom') for ax in axes[:-1, :].ravel()]
|
||||||
|
|
||||||
# Bandpass-filtered signal:
|
# Bandpass-filtered signal:
|
||||||
ax_full, ax_zoom = axes[0, :]
|
ax_full, ax_zoom = axes[0, :]
|
||||||
ylabel(ax_full, ylabels['filt'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['filt'], transform=fig.transFigure, **ylab_pre_kwargs)
|
||||||
plot_line(ax_full, t_full, data['filt'], c=colors['filt'], lw=lw_full['filt'], yloc=yloc_full['filt'])
|
plot_line(ax_full, t_full, data['filt'], c=colors['filt'], lw=lw_full['filt'], yloc=yloc_full['filt'])
|
||||||
plot_line(ax_zoom, t_zoom, data['filt'][zoom_mask], c=colors['filt'], lw=lw_zoom['filt'], yloc=yloc_zoom['filt'])
|
plot_line(ax_zoom, t_zoom, data['filt'][zoom_mask], c=colors['filt'], lw=lw_zoom['filt'], yloc=yloc_zoom['filt'])
|
||||||
|
|
||||||
# Signal envelope:
|
# Signal envelope:
|
||||||
ax_full, ax_zoom = axes[1, :]
|
ax_full, ax_zoom = axes[1, :]
|
||||||
ylabel(ax_full, ylabels['env'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['env'], transform=fig.transFigure, **ylab_pre_kwargs)
|
||||||
plot_line(ax_full, t_full, data['env'], ymin=0, c=colors['env'], lw=lw_full['env'], yloc=yloc_full['env'])
|
plot_line(ax_full, t_full, data['env'], ymin=0, c=colors['env'], lw=lw_full['env'], yloc=yloc_full['env'])
|
||||||
plot_line(ax_zoom, t_zoom, data['env'][zoom_mask], ymin=0, c=colors['env'], lw=lw_zoom['env'], yloc=yloc_zoom['env'])
|
plot_line(ax_zoom, t_zoom, data['env'][zoom_mask], ymin=0, c=colors['env'], lw=lw_zoom['env'], yloc=yloc_zoom['env'])
|
||||||
|
|
||||||
# Logarithmic envelope:
|
# Logarithmic envelope:
|
||||||
ax_full, ax_zoom = axes[2, :]
|
ax_full, ax_zoom = axes[2, :]
|
||||||
ylabel(ax_full, ylabels['log'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['log'], transform=fig.transFigure, **ylab_pre_kwargs)
|
||||||
plot_line(ax_full, t_full, data['log'], ymax=0, c=colors['log'], lw=lw_full['log'], yloc=yloc_full['log'])
|
plot_line(ax_full, t_full, data['log'], ymax=0, c=colors['log'], lw=lw_full['log'], yloc=yloc_full['log'])
|
||||||
plot_line(ax_zoom, t_zoom, data['log'][zoom_mask], ymax=0, c=colors['log'], lw=lw_zoom['log'], yloc=yloc_zoom['log'])
|
plot_line(ax_zoom, t_zoom, data['log'][zoom_mask], c=colors['log'], lw=lw_zoom['log'], yloc=yloc_zoom['log'])
|
||||||
|
|
||||||
# Adapted envelope:
|
# Adapted envelope:
|
||||||
ax_full, ax_zoom = axes[3, :]
|
ax_full, ax_zoom = axes[3, :]
|
||||||
ylabel(ax_full, ylabels['inv'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['inv'], transform=fig.transFigure, **ylab_pre_kwargs)
|
||||||
plot_line(ax_full, t_full, data['inv'], c=colors['inv'], lw=lw_full['inv'], yloc=yloc_full['inv'])
|
plot_line(ax_full, t_full, data['inv'], c=colors['inv'], lw=lw_full['inv'], yloc=yloc_full['inv'])
|
||||||
plot_line(ax_zoom, t_zoom, data['inv'][zoom_mask], c=colors['inv'], lw=lw_zoom['inv'], yloc=yloc_zoom['inv'])
|
plot_line(ax_zoom, t_zoom, data['inv'][zoom_mask], c=colors['inv'], lw=lw_zoom['inv'], yloc=yloc_zoom['inv'])
|
||||||
|
|
||||||
@@ -197,25 +192,17 @@ for data_path in data_paths:
|
|||||||
ax_zoom.xaxis.set_major_locator(plt.MultipleLocator(xloc['zoom']))
|
ax_zoom.xaxis.set_major_locator(plt.MultipleLocator(xloc['zoom']))
|
||||||
indicate_zoom(fig, axes[0, 0], axes[-1, 0], zoom_abs, **zoom_kwargs)
|
indicate_zoom(fig, axes[0, 0], axes[-1, 0], zoom_abs, **zoom_kwargs)
|
||||||
indicate_zoom(fig, axes[0, 1], axes[-1, 1], zoom_abs, **zoom_kwargs)
|
indicate_zoom(fig, axes[0, 1], axes[-1, 1], zoom_abs, **zoom_kwargs)
|
||||||
letter_subplots(axes[:, 0], **letter_kwargs)
|
letter_subplots(axes[:, 0], ref=fig.transFigure, **letter_kwargs)
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(f'{save_path}fig_pre_stages.pdf')
|
fig.savefig(f'{save_path}fig_pre_stages.pdf')
|
||||||
|
|
||||||
# Update parameters:
|
|
||||||
fig_kwargs['gridspec_kw'].update(
|
|
||||||
left=0.09,
|
|
||||||
)
|
|
||||||
ylab_kwargs.update(
|
|
||||||
x=0.02,
|
|
||||||
)
|
|
||||||
|
|
||||||
# PART II: FEATURE EXTRACTION STAGE:
|
# PART II: FEATURE EXTRACTION STAGE:
|
||||||
fig, axes = plt.subplots(3, 2, **fig_kwargs)
|
fig, axes = plt.subplots(3, 2, **fig_feat_kwargs)
|
||||||
super_xlabel(xlabels['super'], fig, axes[0, 0], axes[0, -1], **xlab_kwargs)
|
super_xlabel(xlabels['super'], fig, axes[0, 0], axes[0, -1], **xlab_kwargs)
|
||||||
|
|
||||||
# Convolutional filter responses:
|
# Convolutional filter responses:
|
||||||
ax_full, ax_zoom = axes[0, :]
|
ax_full, ax_zoom = axes[0, :]
|
||||||
ylabel(ax_full, ylabels['conv'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['conv'], transform=fig.transFigure, **ylab_feat_kwargs)
|
||||||
signal = data['conv'][:, kern_inds]
|
signal = data['conv'][:, kern_inds]
|
||||||
handles = plot_line(ax_full, t_full, signal, lw=lw_full['conv'], yloc=yloc_full['conv'])
|
handles = plot_line(ax_full, t_full, signal, lw=lw_full['conv'], yloc=yloc_full['conv'])
|
||||||
assign_colors(handles, kern_specs[:, 0], conv_colors)
|
assign_colors(handles, kern_specs[:, 0], conv_colors)
|
||||||
@@ -228,7 +215,7 @@ for data_path in data_paths:
|
|||||||
|
|
||||||
# Binary responses:
|
# Binary responses:
|
||||||
ax_full, ax_zoom = axes[1, :]
|
ax_full, ax_zoom = axes[1, :]
|
||||||
ylabel(ax_full, ylabels['bi'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['bi'], transform=fig.transFigure, **ylab_feat_kwargs)
|
||||||
signal = data['bi'][:, kern_inds]
|
signal = data['bi'][:, kern_inds]
|
||||||
handles = plot_barcode(ax_full, t_full, signal, lw=lw_full['bi'])
|
handles = plot_barcode(ax_full, t_full, signal, lw=lw_full['bi'])
|
||||||
assign_colors(handles, kern_specs[:, 0], bi_colors)
|
assign_colors(handles, kern_specs[:, 0], bi_colors)
|
||||||
@@ -237,7 +224,7 @@ for data_path in data_paths:
|
|||||||
|
|
||||||
# Finalized features:
|
# Finalized features:
|
||||||
ax_full, ax_zoom = axes[2, :]
|
ax_full, ax_zoom = axes[2, :]
|
||||||
ylabel(ax_full, ylabels['feat'], transform=fig.transFigure, **ylab_kwargs)
|
ylabel(ax_full, ylabels['feat'], transform=fig.transFigure, **ylab_feat_kwargs)
|
||||||
signal = data['feat'][:, kern_inds]
|
signal = data['feat'][:, kern_inds]
|
||||||
handles = plot_line(ax_full, t_full, signal, ymin=0, ymax=1, c=colors['feat'], lw=lw_full['feat'], yloc=yloc_full['feat'])
|
handles = plot_line(ax_full, t_full, signal, ymin=0, ymax=1, c=colors['feat'], lw=lw_full['feat'], yloc=yloc_full['feat'])
|
||||||
assign_colors(handles, kern_specs[:, 0], feat_colors)
|
assign_colors(handles, kern_specs[:, 0], feat_colors)
|
||||||
@@ -251,7 +238,7 @@ for data_path in data_paths:
|
|||||||
ax_zoom.xaxis.set_major_locator(plt.MultipleLocator(xloc['zoom']))
|
ax_zoom.xaxis.set_major_locator(plt.MultipleLocator(xloc['zoom']))
|
||||||
indicate_zoom(fig, axes[0, 0], axes[-1, 0], zoom_abs, **zoom_kwargs)
|
indicate_zoom(fig, axes[0, 0], axes[-1, 0], zoom_abs, **zoom_kwargs)
|
||||||
indicate_zoom(fig, axes[0, 1], axes[-1, 1], zoom_abs, **zoom_kwargs)
|
indicate_zoom(fig, axes[0, 1], axes[-1, 1], zoom_abs, **zoom_kwargs)
|
||||||
letter_subplots(axes[:, 0], **letter_kwargs)
|
letter_subplots(axes[:, 0], ref=fig.transFigure, **letter_kwargs)
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
fig.savefig(f'{save_path}fig_feat_stages.pdf')
|
fig.savefig(f'{save_path}fig_feat_stages.pdf')
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ text_kwargs = dict(
|
|||||||
ha='right',
|
ha='right',
|
||||||
va='top',
|
va='top',
|
||||||
)
|
)
|
||||||
|
plateau_dot_kwargs = dict(
|
||||||
|
marker='o',
|
||||||
|
markersize=8,
|
||||||
|
markeredgewidth=1,
|
||||||
|
clip_on=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Prepare graph:
|
# Prepare graph:
|
||||||
fig, axes = plt.subplots(**fig_kwargs)
|
fig, axes = plt.subplots(**fig_kwargs)
|
||||||
@@ -111,12 +117,22 @@ for species, ax in zip(target_species, axes):
|
|||||||
# Plot distribution of saturation points:
|
# Plot distribution of saturation points:
|
||||||
handles.append(ax.bar(bins, hist, width=bins[1] - bins[0], fc=color, **bar_kwargs))
|
handles.append(ax.bar(bins, hist, width=bins[1] - bins[0], fc=color, **bar_kwargs))
|
||||||
ax.set_ylim(0, hist.max() * 1.05)
|
ax.set_ylim(0, hist.max() * 1.05)
|
||||||
|
if species == 'Gomphocerippus_rufus':
|
||||||
|
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
|
||||||
|
else:
|
||||||
|
ax.yaxis.set_major_locator(plt.MultipleLocator(0.03))
|
||||||
|
|
||||||
# Indicate mean of distribution:
|
# Indicate mean of distribution:
|
||||||
ax.axvline(data['crit_scales'].mean(), **mean_kwargs)
|
# ax.axvline(data['crit_scales'].mean(), **mean_kwargs)
|
||||||
|
|
||||||
# Indicate number of songs:
|
# Indicate number of songs:
|
||||||
ax.text(**text_kwargs, s=f'n = {n_songs}', transform=ax.transAxes)
|
ax.text(**text_kwargs, s=f'n={n_songs}', transform=ax.transAxes)
|
||||||
|
|
||||||
|
# Indicate saturation point of condensed curve:
|
||||||
|
ax.plot(data['crit_scale'], 0, c='w', alpha=1, zorder=5.5,
|
||||||
|
transform=ax.get_xaxis_transform(), **plateau_dot_kwargs)
|
||||||
|
ax.plot(data['crit_scale'], 0, mfc=color, mec='k', alpha=0.75, zorder=6,
|
||||||
|
transform=ax.get_xaxis_transform(), **plateau_dot_kwargs)
|
||||||
|
|
||||||
# Posthocs:
|
# Posthocs:
|
||||||
labels = [shorten_species(species) for species in target_species]
|
labels = [shorten_species(species) for species in target_species]
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
import glob
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
from thunderhopper.filetools import search_files
|
||||||
from thunderhopper.modeltools import load_data
|
from thunderhopper.modeltools import load_data
|
||||||
from thunderhopper.filters import sosfilter
|
from thunderhopper.filters import sosfilter
|
||||||
from IPython import embed
|
from IPython import embed
|
||||||
|
|
||||||
# GENERAL SETTINGS:
|
# GENERAL SETTINGS:
|
||||||
target = 'Omocestus_rufipes'
|
target = 'Omocestus_rufipes'
|
||||||
data_path = glob.glob(f'../data/processed/{target}*.npz')[0]
|
data_path = search_files(target, dir='../data/processed/')[0]
|
||||||
save_path = '../data/inv/noise_env/'
|
save_path = '../data/inv/noise_env/'
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
scales = np.geomspace(0.1, 10000, 200)
|
scales = np.geomspace(0.01, 1000, 100)
|
||||||
sd_inputs = np.array([1.0])
|
sd_inputs = np.array([1.0])
|
||||||
n_trials = 10
|
n_trials = 100
|
||||||
tol_to_one = 0.1
|
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
|
|
||||||
# Load signal data:
|
# Load signal data:
|
||||||
data, config = load_data(data_path, files='filt')
|
data, config = load_data(data_path, files='raw')
|
||||||
signal, rate = data['filt'], config['rate']
|
signal, rate = data['raw'], config['rate']
|
||||||
|
|
||||||
# Reduce to song segment and normalize:
|
# Reduce to song segment and normalize:
|
||||||
time = np.arange(signal.shape[0]) / rate
|
time = np.arange(signal.shape[0]) / rate
|
||||||
@@ -28,67 +26,60 @@ start, end = data['songs_0'].ravel()
|
|||||||
segment = (time >= start) & (time <= end)
|
segment = (time >= start) & (time <= end)
|
||||||
signal /= signal[segment].std()
|
signal /= signal[segment].std()
|
||||||
|
|
||||||
# Get rescaled signals (time, scale):
|
# Rescale signal (time, scale):
|
||||||
signal = signal[:, None] * scales[None, :]
|
signal = signal[:, None] * scales[None, :]
|
||||||
|
|
||||||
# Prepare storage:
|
# Prepare storage:
|
||||||
if sd_inputs.size > 1:
|
sd_noise = np.zeros((scales.size, n_trials, sd_inputs.size), dtype=float)
|
||||||
current_match = 0
|
|
||||||
storage = dict(
|
|
||||||
scales=scales,
|
|
||||||
n_trials=n_trials,
|
|
||||||
sd_factor=np.array([0.]),
|
|
||||||
trials=np.zeros((scales.size, n_trials), dtype=float),
|
|
||||||
mean=np.zeros(scales.size, dtype=float),
|
|
||||||
spread=np.zeros(scales.size, dtype=float),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Analyze piece-wise:
|
# Analyze piece-wise:
|
||||||
rng = np.random.default_rng()
|
rng = np.random.default_rng()
|
||||||
for i, sigma in enumerate(sd_inputs):
|
for i, sigma in enumerate(sd_inputs):
|
||||||
print(f'Testing SD: {sigma:.3f} ...')
|
print(f'Testing SD: {sigma:.3f} ...')
|
||||||
|
|
||||||
# Add Gaussian noise of given SD to rescaled signals (time, scale, trial):
|
# Prepare trial storage:
|
||||||
mix = signal[..., None] + rng.normal(0, sigma, (*signal.shape, n_trials))
|
sd_trials = np.zeros((segment.sum(), scales.size, n_trials), dtype=float)
|
||||||
|
|
||||||
# Get mixture envelopes (time, scale, trial):
|
# Run trials:
|
||||||
mix = sosfilter(np.abs(mix), rate, config['env_fcut'], 'lp',
|
for j in range(n_trials):
|
||||||
padtype='even', padlen=config['padlen'])[segment, ...]
|
# Mix signals with white noise of target SD:
|
||||||
|
mix = signal + rng.normal(0, sigma, signal.shape)
|
||||||
|
|
||||||
|
# Process mixture:
|
||||||
|
mix = sosfilter(mix, rate, config['bp_fcut'], 'bp',
|
||||||
|
padtype='fixed', padlen=config['padlen'])
|
||||||
|
mix = sosfilter(np.abs(mix), rate, config['env_fcut'], 'lp',
|
||||||
|
padtype='even', padlen=config['padlen'])
|
||||||
|
|
||||||
|
# Log current trial:
|
||||||
|
sd_trials[..., j] = mix[segment, :]
|
||||||
|
|
||||||
# Get noise remainders of mean over trials:
|
# Get noise remainders of mean over trials:
|
||||||
mix -= mix.mean(axis=-1, keepdims=True)
|
sd_trials -= sd_trials.mean(axis=-1, keepdims=True)
|
||||||
|
|
||||||
# Estimate noise SD:
|
# Estimate noise SD:
|
||||||
sd = mix.std(axis=0)
|
sd_noise[:, :, i] = sd_trials.std(axis=0)
|
||||||
# Average SD over trials:
|
|
||||||
mean_sd = sd.mean(axis=-1)
|
|
||||||
|
|
||||||
# Log single-run results:
|
# # Add Gaussian noise of given SD to rescaled signals (time, scale, trial):
|
||||||
if sd_inputs.size == 1:
|
# mix = signal[..., None] + rng.normal(0, sigma, (*signal.shape, n_trials))
|
||||||
storage = dict(
|
|
||||||
scales=scales,
|
|
||||||
n_trials=n_trials,
|
|
||||||
sd_factor=sigma,
|
|
||||||
trials=sd,
|
|
||||||
mean=mean_sd,
|
|
||||||
spread=sd.std(axis=-1),
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Update multi-run results if better than previous:
|
# # Get mixture envelopes (time, scale, trial):
|
||||||
n_match = (np.abs(1 - mean_sd) <= tol_to_one).sum()
|
# mix = sosfilter(np.abs(mix), rate, config['env_fcut'], 'lp',
|
||||||
if n_match > current_match:
|
# padtype='even', padlen=config['padlen'])[segment, ...]
|
||||||
print(f'Found better SD: {sigma:.3f} with {n_match} matches (previous: {current_match})')
|
|
||||||
storage['sd_factor'][0] = sigma
|
# # Get noise remainders of mean over trials:
|
||||||
storage['trials'][:, :] = sd
|
# mix -= mix.mean(axis=-1, keepdims=True)
|
||||||
storage['mean'][:] = mean_sd
|
|
||||||
storage['spread'][:] = sd.std(axis=-1)
|
# # Estimate noise SD:
|
||||||
current_match = n_match
|
# sd_noise[:, :, i] = mix.std(axis=0)
|
||||||
del mix
|
|
||||||
del signal
|
|
||||||
|
|
||||||
if save_path is not None:
|
if save_path is not None:
|
||||||
np.savez(save_path + 'sd_conversion.npz', **storage)
|
archive = dict(
|
||||||
|
scales=scales,
|
||||||
|
sd_input=sd_inputs,
|
||||||
|
sd_noise=sd_noise,
|
||||||
|
)
|
||||||
|
np.savez(save_path + 'sd_conversion.npz', **archive)
|
||||||
|
|
||||||
print('Done.')
|
print('Done.')
|
||||||
embed()
|
embed()
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ target_species = [
|
|||||||
'Omocestus_rufipes',
|
'Omocestus_rufipes',
|
||||||
'Pseudochorthippus_parallelus',
|
'Pseudochorthippus_parallelus',
|
||||||
]
|
]
|
||||||
search_path = '../data/inv/log_hp/collected/'
|
collect_path = '../data/inv/log_hp/collected/'
|
||||||
|
condense_path = '../data/inv/log_hp/condensed/'
|
||||||
save_path = '../data/inv/log_hp/saturation/'
|
save_path = '../data/inv/log_hp/saturation/'
|
||||||
|
|
||||||
# ANALYSIS SETTINGS:
|
# ANALYSIS SETTINGS:
|
||||||
@@ -32,7 +33,7 @@ pad = 0.05
|
|||||||
# PREPARATION:
|
# PREPARATION:
|
||||||
if compute_hist:
|
if compute_hist:
|
||||||
species_scales = []
|
species_scales = []
|
||||||
min_scale, max_scale = [], []
|
min_scale, max_scale = np.inf, -np.inf
|
||||||
archives = [{} for _ in target_species]
|
archives = [{} for _ in target_species]
|
||||||
|
|
||||||
# EXECUTION:
|
# EXECUTION:
|
||||||
@@ -40,31 +41,48 @@ for i, species in enumerate(target_species):
|
|||||||
print(f'Processing {species}')
|
print(f'Processing {species}')
|
||||||
|
|
||||||
# Load accumulated invariance data:
|
# Load accumulated invariance data:
|
||||||
path = search_files(species, dir=search_path)[0]
|
path = search_files(species, dir=collect_path)[0]
|
||||||
data, config = load_data(path, ['scales', 'measure_inv'])
|
data, config = load_data(path, ['scales', 'measure_inv'])
|
||||||
|
|
||||||
# Find upper saturation point per song file:
|
# Find upper saturation point per song file:
|
||||||
crit_inds = np.array(get_saturation(data['measure_inv'], **plateau_settings)[1])
|
crit_inds = np.array(get_saturation(data['measure_inv'], **plateau_settings)[1])
|
||||||
crit_scales = data['scales'][crit_inds]
|
crit_scales = data['scales'][crit_inds]
|
||||||
|
|
||||||
|
# Load condensed invariance data:
|
||||||
|
path = search_files(species, incl=['noise', 'norm-base'], dir=condense_path)[0]
|
||||||
|
data, _ = load_data(path, ['scales', 'mean_inv'])
|
||||||
|
|
||||||
|
# Find single upper saturation point of condensed curve:
|
||||||
|
crit_ind = get_saturation(data['mean_inv'].mean(axis=-1), **plateau_settings)[1]
|
||||||
|
crit_scale = data['scales'][crit_ind]
|
||||||
|
|
||||||
# Output options:
|
# Output options:
|
||||||
if not compute_hist:
|
if not compute_hist:
|
||||||
# Save species data immediately:
|
# Save species data immediately:
|
||||||
archive = dict(crit_inds=crit_inds, crit_scales=crit_scales, scales=data['scales'])
|
archive = dict(
|
||||||
|
scales=data['scales'],
|
||||||
|
crit_inds=crit_inds,
|
||||||
|
crit_scales=crit_scales,
|
||||||
|
crit_ind=crit_ind,
|
||||||
|
crit_scale=crit_scale,
|
||||||
|
)
|
||||||
save_data(save_path + species, archive, config, overwrite=True)
|
save_data(save_path + species, archive, config, overwrite=True)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Log but don't save data yet:
|
# Log but don't save data yet:
|
||||||
archives[i]['crit_inds'] = crit_inds
|
min_scale = min(crit_scales.min(), min_scale)
|
||||||
archives[i]['crit_scales'] = crit_scales
|
max_scale = max(crit_scales.max(), max_scale)
|
||||||
archives[i]['scales'] = data['scales']
|
archives[i].update(
|
||||||
min_scale.append(crit_scales.min())
|
scales=data['scales'],
|
||||||
max_scale.append(crit_scales.max())
|
crit_inds=crit_inds,
|
||||||
|
crit_scales=crit_scales,
|
||||||
|
crit_ind=crit_ind,
|
||||||
|
crit_scale=crit_scale,
|
||||||
|
)
|
||||||
|
|
||||||
# Optional histogram:
|
# Optional histogram:
|
||||||
if compute_hist:
|
if compute_hist:
|
||||||
# Generated shared histogram edges:
|
# Generated shared bin edges:
|
||||||
min_scale, max_scale = min(min_scale), max(max_scale)
|
|
||||||
pad *= (max_scale - min_scale)
|
pad *= (max_scale - min_scale)
|
||||||
edges = np.linspace(max(0, min_scale - pad), max_scale + pad, bins + 1)
|
edges = np.linspace(max(0, min_scale - pad), max_scale + pad, bins + 1)
|
||||||
centers = edges[:-1] + np.diff(edges) / 2
|
centers = edges[:-1] + np.diff(edges) / 2
|
||||||
|
|||||||
Reference in New Issue
Block a user