diff --git a/figures/fig_invariance_thresh_lp.pdf b/figures/fig_invariance_thresh_lp.pdf deleted file mode 100644 index d8a4cda..0000000 Binary files a/figures/fig_invariance_thresh_lp.pdf and /dev/null differ diff --git a/figures/fig_invariance_thresh_lp_single.pdf b/figures/fig_invariance_thresh_lp_single.pdf index c0e55cb..3e9858b 100644 Binary files a/figures/fig_invariance_thresh_lp_single.pdf and b/figures/fig_invariance_thresh_lp_single.pdf differ diff --git a/figures/fig_invariance_thresh_lp_single_noise.pdf b/figures/fig_invariance_thresh_lp_single_noise.pdf deleted file mode 100644 index 4a7e868..0000000 Binary files a/figures/fig_invariance_thresh_lp_single_noise.pdf and /dev/null differ diff --git a/main.aux b/main.aux index b0ae31f..f12e891 100644 --- a/main.aux +++ b/main.aux @@ -248,27 +248,25 @@ \newlabel{eq:toy_log}{{12}{11}{}{}{}} \newlabel{eq:toy_highpass}{{13}{11}{}{}{}} \newlabel{eq:toy_snr}{{14}{12}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces \textbf {Intensity invariance by logarithmic compression and adaptation is restricted by the noise floor.} Synthetic input $x_{\text {filt}}(t)$ consists of song component $s(t)$ scaled by $\alpha $ with (\textbf {c}{} and \textbf {d}) or without (\textbf {a}{} and \textbf {b}) additive noise component $\eta (t)$. Input $x_{\text {filt}}(t)$ is transformed into envelope $x_{\text {env}}(t)$, logarithmically compressed envelope $x_{\text {dB}}(t)$, and intensity-adapted envelope $x_{\text {adapt}}(t)$. \textbf {Left}:~$x_{\text {env}}(t)$, $x_{\text {dB}}(t)$, and $x_{\text {adapt}}(t)$ for different scales $\alpha $. \textbf {Right}:~Ratios of the standard deviation of $x_{\text {env}}(t)$, $x_{\text {dB}}(t)$, and $x_{\text {adapt}}(t)$ relative to the respective reference standard deviation for input $x_{\text {filt}}(t)=\eta (t)$. \textbf {a}{} and \textbf {b}:~Ideally, if $x_{\text {filt}}(t)=\alpha \cdot s(t)$, then $x_{\text {adapt}}(t)$ is intensity-invariant across all $\alpha $. \textbf {c}{} and \textbf {d}:~In practice, if $x_{\text {filt}}(t)=\alpha \cdot s(t)+\eta (t)$, the intensity invariance of $x_{\text {adapt}}(t)$ is limited to sufficiently large $\alpha $. Shaded area indicates saturation of $x_{\text {adapt}}(t)$ at $95\,\%$ curve span. }}{12}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces \textbf {Intensity invariance by logarithmic compression and adaptation is restricted by the noise floor.} Synthetic input $x_{\text {filt}}(t)$ consists of song component $s(t)$ scaled by $\alpha $ with (\textbf {c}{} and \textbf {d}) or without (\textbf {a}{} and \textbf {b}) additive noise component $\eta (t)$. Input $x_{\text {filt}}(t)$ is transformed into envelope $x_{\text {env}}(t)$, logarithmically compressed envelope $x_{\text {dB}}(t)$, and intensity-adapted envelope $x_{\text {adapt}}(t)$. \textbf {Left}:~$x_{\text {env}}(t)$, $x_{\text {dB}}(t)$, and $x_{\text {adapt}}(t)$ for different scales $\alpha $. \textbf {Right}:~Ratios of the standard deviation of $x_{\text {env}}(t)$, $x_{\text {dB}}(t)$, and $x_{\text {adapt}}(t)$ relative to the respective reference standard deviation $\sigma _{\eta }$ for input $x_{\text {filt}}(t)=\eta (t)$. \textbf {a}{} and \textbf {b}:~Ideally, if $x_{\text {filt}}(t)=\alpha \cdot s(t)$, then $x_{\text {adapt}}(t)$ is intensity-invariant across all $\alpha $. \textbf {c}{} and \textbf {d}:~In practice, if $x_{\text {filt}}(t)=\alpha \cdot s(t)+\eta (t)$, the intensity invariance of $x_{\text {adapt}}(t)$ is limited to sufficiently large $\alpha $. Shaded area indicates saturation of $x_{\text {adapt}}(t)$ at $95\,\%$ curve span. }}{12}{}\protected@file@percent } \newlabel{fig:inv_log-hp}{{4}{12}{}{}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Thresholding nonlinearity \& temporal averaging}{12}{}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces \textbf {Intensity invariance by thresholding and temporal averaging depends on the threshold value with regard to variable range but not saturation level.} Kernel response $c_i(t)$ is rescaled by $\alpha $ and transformed into binary response $b_i(t)$ and further into feature $f_i(t)$. Threshold value $\Theta _i$ is set to different percentiles of the the distribution of $c_i(t)$ at $\alpha =1$. Darker colors indicate higher values of $\Theta _i$. Indicated time scale of $100\,$ms is the same for \textbf {a}-\textbf {c} (black bar). \textbf {a}:~50th percentile. \textbf {b}:~75th percentile. \textbf {c}:~100th percentile. \textbf {d}:~Average value of $f_i(t)$ during the song for the different $\Theta _i$ in \textbf {a}-\textbf {c}. }}{13}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces \textbf {Intensity invariance by thresholding and temporal averaging depends on both the threshold value and the noise floor.} Synthetic input $x_{\text {adapt}}(t)$ consists of song component $s(t)$ scaled by $\alpha $ with additive noise component $\eta (t)$. Input $x_{\text {adapt}}(t)$ is transformed into kernel response $c_i(t)$, binary response $b_i(t)$, and feature $f_i(t)$. Threshold value $\Theta _i$ is set to multiples of the reference standard deviation $\sigma _{\eta }$ of $c_i(t)$ for input $x_{\text {adapt}}(t)=\eta (t)$. Darker colors correspond to higher $\Theta _i$. \textbf {Left}:~$x_{\text {adapt}}(t)$, $c_i(t)$, $b_i(t)$, and $f_i(t)$ for different scales $\alpha $ and threshold values $\Theta _i$. Left-most column is is the pure-noise reference. \textbf {Right}:~Average value of $f_i(t)$ during the song for the different $\Theta _i$. \textbf {a}:~Input $x_{\text {adapt}}(t)$. \textbf {b}-\textbf {d}:~$c_i(t)$, $b_i(t)$, and $f_i(t)$ for the different $\Theta _i$ based on the same $x_{\text {adapt}}(t)$ from \textbf {a}{}. \textbf {e}:~Average value of $f_i(t)$ during the song for the different $\Theta _i$ in \textbf {b}{}-\textbf {d}. }}{13}{}\protected@file@percent } \newlabel{fig:inv_thresh-lp_single}{{5}{13}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces \textbf {Intensity invariance by thresholding and temporal averaging depends on noise with regard to variable range but not saturation level.} Kernel response $c_i(t)$ is rescaled by $\alpha $, mixed with fixed-scale noise component $\eta (t)$, and transformed into binary response $b_i(t)$ and further into feature $f_i(t)$. Threshold value $\Theta _i$ is set to different percentiles of the the distribution of $c_i(t)$ at $\alpha =1$. Darker colors indicate higher values of $\Theta _i$. Indicated time scale of $100\,$ms is the same for \textbf {a}-\textbf {c} (black bar). \textbf {a}:~50th percentile. \textbf {b}:~75th percentile. \textbf {c}:~100th percentile. \textbf {d}:~Average value of $f_i(t)$ during the song for the different $\Theta _i$ in \textbf {a}-\textbf {c}. }}{14}{}\protected@file@percent } -\newlabel{fig:inv_thresh-lp_single_noise}{{6}{14}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces \textbf {Feature representation of different species-specific songs saturates at different points in feature space.} }}{15}{}\protected@file@percent } -\newlabel{fig:inv_thresh-lp_species}{{7}{15}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces \textbf {Step-wise emergence of intensity invariant song representation along the model pathway.} }}{15}{}\protected@file@percent } -\newlabel{fig:inv_thresh-lp_full}{{8}{15}{}{}{}} -\newlabel{eq:pdf_split}{{15}{16}{}{}{}} -\newlabel{eq:feat_avg}{{16}{16}{}{}{}} -\newlabel{eq:feat_prop}{{17}{16}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces \textbf {Feature representation of different species-specific songs saturates at different points in feature space.} }}{13}{}\protected@file@percent } +\newlabel{fig:inv_thresh-lp_species}{{6}{13}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces \textbf {Step-wise emergence of intensity invariant song representation along the model pathway.} }}{14}{}\protected@file@percent } +\newlabel{fig:inv_thresh-lp_full}{{7}{14}{}{}{}} +\newlabel{eq:pdf_split}{{15}{14}{}{}{}} \abx@aux@cite{0}{stumpner1991auditory} \abx@aux@segm{0}{0}{stumpner1991auditory} -\@writefile{toc}{\contentsline {section}{\numberline {4}Discriminating species-specific song\\patterns in feature space}{17}{}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{17}{}\protected@file@percent } -\abx@aux@page{73}{17} -\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces \textbf {} }}{19}{}\protected@file@percent } -\newlabel{}{{9}{19}{}{}{}} +\newlabel{eq:feat_avg}{{16}{15}{}{}{}} +\newlabel{eq:feat_prop}{{17}{15}{}{}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4}Discriminating species-specific song\\patterns in feature space}{16}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{16}{}\protected@file@percent } +\abx@aux@page{73}{16} +\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces \textbf {} }}{17}{}\protected@file@percent } +\newlabel{}{{8}{17}{}{}{}} \gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }} \abx@aux@read@bbl@mdfivesum{1380DC8C93D2855FDB132CC5A40AD52F} -\gdef \@abspage@last{19} +\gdef \@abspage@last{17} diff --git a/main.blg b/main.blg index ccddb83..6d8c72b 100644 --- a/main.blg +++ b/main.blg @@ -1,71 +1,71 @@ [0] Config.pm:307> INFO - This is Biber 2.19 [0] Config.pm:310> INFO - Logfile is 'main.blg' -[36] biber:340> INFO - === Mo Mär 23, 2026, 15:34:22 +[36] biber:340> INFO - === Mi Mär 25, 2026, 15:53:59 [43] Biber.pm:419> INFO - Reading 'main.bcf' [71] Biber.pm:979> INFO - Found 55 citekeys in bib section 0 [77] Biber.pm:4419> INFO - Processing section 0 [81] Biber.pm:4610> INFO - Looking for bibtex file 'cite.bib' for section 0 [83] bibtex.pm:1713> INFO - LaTeX decoding ... [112] bibtex.pm:1519> INFO - Found BibTeX data source 'cite.bib' -[284] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'variable = shifted' with 'variable = non-ignorable' -[284] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'normalization = NFD' with 'normalization = prenormalized' -[284] Biber.pm:4239> INFO - Sorting list 'nyt/global//global/global' of type 'entry' with template 'nyt' and locale 'en-US' -[284] Biber.pm:4245> INFO - No sort tailoring available for locale 'en-US' -[307] bbl.pm:660> INFO - Writing 'main.bbl' with encoding 'UTF-8' -[317] bbl.pm:763> INFO - Output to main.bbl -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 10, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 21, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 38, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 49, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 58, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 73, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 82, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 91, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 100, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 109, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 118, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 127, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 136, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 157, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 178, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 187, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 196, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 207, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 218, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 229, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 240, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 249, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 258, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 269, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 278, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 289, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 300, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 309, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 328, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 337, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 400, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 419, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 428, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 437, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 456, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 491, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 526, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 535, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 556, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 565, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 576, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 587, warning: 6 characters of junk seen at toplevel -[317] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 619, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 648, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 658, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 667, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 688, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 709, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 720, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 729, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 749, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 766, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 775, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 800, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_WUPV/347c261ec4135a5723bef5c751f5078f_55550.utf8, line 817, warning: 6 characters of junk seen at toplevel -[318] Biber.pm:133> INFO - WARNINGS: 55 +[287] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'normalization = NFD' with 'normalization = prenormalized' +[287] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'variable = shifted' with 'variable = non-ignorable' +[287] Biber.pm:4239> INFO - Sorting list 'nyt/global//global/global' of type 'entry' with template 'nyt' and locale 'en-US' +[287] Biber.pm:4245> INFO - No sort tailoring available for locale 'en-US' +[310] bbl.pm:660> INFO - Writing 'main.bbl' with encoding 'UTF-8' +[320] bbl.pm:763> INFO - Output to main.bbl +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 10, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 21, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 38, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 49, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 58, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 73, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 82, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 91, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 100, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 109, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 118, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 127, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 136, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 157, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 178, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 187, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 196, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 207, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 218, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 229, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 240, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 249, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 258, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 269, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 278, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 289, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 300, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 309, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 328, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 337, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 400, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 419, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 428, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 437, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 456, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 491, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 526, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 535, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 556, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 565, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 576, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 587, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 619, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 648, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 658, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 667, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 688, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 709, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 720, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 729, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 749, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 766, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 775, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 800, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_gWc3/347c261ec4135a5723bef5c751f5078f_62855.utf8, line 817, warning: 6 characters of junk seen at toplevel +[321] Biber.pm:133> INFO - WARNINGS: 55 diff --git a/main.fdb_latexmk b/main.fdb_latexmk index f4e5fbf..75dc139 100644 --- a/main.fdb_latexmk +++ b/main.fdb_latexmk @@ -1,14 +1,14 @@ # Fdb version 4 -["biber main"] 1774276462.09046 "main.bcf" "main.bbl" "main" 1774276586.37924 0 +["biber main"] 1774450439.36422 "main.bcf" "main.bbl" "main" 1774450447.31629 0 "cite.bib" 1770904753.08918 27483 4290db0c91f7b5055e25472ef913f6b4 "" - "main.bcf" 1774276586.2705 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" + "main.bcf" 1774450447.19902 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" (generated) "main.bbl" "main.blg" (rewritten before read) -["pdflatex"] 1774276584.89956 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1774276586.37948 0 +["pdflatex"] 1774450445.69982 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1774450447.31653 0 "/etc/texmf/web2c/texmf.cnf" 1761560044.43676 475 c0e671620eb5563b2130f56340a5fde8 "" - "/home/hartling/phd/paper/paper_2025/main.tex" 1774276584.74351 48814 dd2ac1d2321e0ebfabfa83fbfcca1664 "" + "/home/hartling/phd/paper/paper_2025/main.tex" 1774450445.38503 48022 de46789e7f0ca716a47759b334bfa10b "" "/usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1246382020 1004 54797486969f23fa377b128694d548df "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1246382020 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 "" @@ -155,15 +155,14 @@ "figures/fig_feat_stages.pdf" 1774002994.98767 11091006 565fe951f1255c121429a060082398f5 "" "figures/fig_invariance_full.pdf" 1774271483.89842 149796490 a2dd04969d8a98c63c3653d20848c0b6 "" "figures/fig_invariance_log_hp.pdf" 1774270814.43169 544402 7a2def404adc93a3e18fa8b309d452be "" - "figures/fig_invariance_thresh_lp_single.pdf" 1773738083.70309 580357 3681b066ae31e650d9261f435fcd92af "" - "figures/fig_invariance_thresh_lp_single_noise.pdf" 1774271693.79875 944238 eae31012249660340999b8b5ad139ae2 "" + "figures/fig_invariance_thresh_lp_single.pdf" 1774448531.93474 921028 cae18b62e262b42f630e219fcaa0ca09 "" "figures/fig_invariance_thresh_lp_species.pdf" 1773741140.93995 47573 9dd8a2281ce467803dd2a7b74ff3373e "" "figures/fig_noise_env_sd_conversion.pdf" 1774256952.42051 45466 671a2b8fbf72b4eba6b970b4421f2521 "" "figures/fig_pre_stages.pdf" 1774002992.74268 449426 5762be15627fe5d8b6d108b7ea18db44 "" - "main.aux" 1774276586.2645 15775 9d5556b7cec6642ec926c3da8ab827e7 "pdflatex" - "main.bbl" 1774276462.69945 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" - "main.run.xml" 1774276586.2705 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" - "main.tex" 1774276584.74351 48814 dd2ac1d2321e0ebfabfa83fbfcca1664 "" + "main.aux" 1774450447.19302 15278 2c66d13a9cb30f6854e7c7e85ce0fb43 "pdflatex" + "main.bbl" 1774450439.97007 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" + "main.run.xml" 1774450447.20002 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" + "main.tex" 1774450445.38503 48022 de46789e7f0ca716a47759b334bfa10b "" (generated) "main.aux" "main.bcf" diff --git a/main.fls b/main.fls index 7832fbe..ad9de2b 100644 --- a/main.fls +++ b/main.fls @@ -298,11 +298,6 @@ INPUT ./figures/fig_invariance_thresh_lp_single.pdf INPUT ./figures/fig_invariance_thresh_lp_single.pdf INPUT ./figures/fig_invariance_thresh_lp_single.pdf INPUT ./figures/fig_invariance_thresh_lp_single.pdf -INPUT ./figures/fig_invariance_thresh_lp_single_noise.pdf -INPUT ./figures/fig_invariance_thresh_lp_single_noise.pdf -INPUT ./figures/fig_invariance_thresh_lp_single_noise.pdf -INPUT ./figures/fig_invariance_thresh_lp_single_noise.pdf -INPUT ./figures/fig_invariance_thresh_lp_single_noise.pdf INPUT ./figures/fig_invariance_thresh_lp_species.pdf INPUT ./figures/fig_invariance_thresh_lp_species.pdf INPUT ./figures/fig_invariance_thresh_lp_species.pdf diff --git a/main.log b/main.log index 3cb1be7..9653d1d 100644 --- a/main.log +++ b/main.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2025.10.28) 23 MAR 2026 15:36 +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2025.10.28) 25 MAR 2026 15:54 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -702,29 +702,29 @@ LaTeX Font Info: Trying to load font information for U+msb on input line 41. (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd File: umsb.fd 2013/01/14 v3.01 AMS symbols B ) -Overfull \hbox (54.40451pt too wide) in paragraph at lines 127--158 +Overfull \hbox (54.40451pt too wide) in paragraph at lines 128--159 \OT1/cmr/m/n/12 and eval-u-a-tion ([]), sender lo-cal-iza-tion ([]), [] -Overfull \hbox (9.21051pt too wide) in paragraph at lines 127--158 +Overfull \hbox (9.21051pt too wide) in paragraph at lines 128--159 \OT1/cmr/m/n/12 tion sig-nals for dif-fer-ent con-texts and ranges us-ing their wings, hindlegs, or mandibles ([]). [] [1 {/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] -Overfull \hbox (42.86342pt too wide) in paragraph at lines 223--284 +Overfull \hbox (42.86342pt too wide) in paragraph at lines 224--285 \OT1/cmr/m/n/12 and grasshop-pers ([]; re-view on both: []). [] -Overfull \hbox (3.29253pt too wide) in paragraph at lines 223--284 +Overfull \hbox (3.29253pt too wide) in paragraph at lines 224--285 []\OT1/cmr/m/n/12 ; []). The fit-ted sig-moidal [] [3] -Overfull \hbox (41.1838pt too wide) in paragraph at lines 317--352 +Overfull \hbox (41.1838pt too wide) in paragraph at lines 318--353 \OT1/cmr/m/n/12 for con-spe-cific song recog-ni-tion and re-sponse ini-ti-a-tion ([]; [] @@ -732,10 +732,10 @@ Overfull \hbox (41.1838pt too wide) in paragraph at lines 317--352 File: figures/fig_auditory_pathway.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_auditory_pathway.pdf used on input line 355. +Package pdftex.def Info: figures/fig_auditory_pathway.pdf used on input line 356. (pdftex.def) Requested size: 483.69687pt x 518.2677pt. -Overfull \hbox (65.93214pt too wide) in paragraph at lines 378--384 +Overfull \hbox (65.93214pt too wide) in paragraph at lines 379--385 \OT1/cmr/m/n/12 tym-pa-nal mem-brane acts as a me-chan-i-cal res-o-nance fil-ter for sound-induced vi-bra-tions ([]; [] @@ -750,10 +750,10 @@ Overfull \vbox (0.8319pt too high) has occurred while \output is active [] File: figures/fig_pre_stages.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_pre_stages.pdf used on input line 427. +Package pdftex.def Info: figures/fig_pre_stages.pdf used on input line 428. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. [7] [8 <./figures/fig_pre_stages.pdf>] -Overfull \hbox (42.89445pt too wide) in paragraph at lines 520--529 +Overfull \hbox (42.89445pt too wide) in paragraph at lines 521--530 \OT1/cmr/m/n/12 glion ([]; []; []). [] @@ -761,45 +761,40 @@ Overfull \hbox (42.89445pt too wide) in paragraph at lines 520--529 File: figures/fig_feat_stages.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_feat_stages.pdf used on input line 541. +Package pdftex.def Info: figures/fig_feat_stages.pdf used on input line 542. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. [10 <./figures/fig_feat_stages.pdf>] [11] File: figures/fig_invariance_log_hp.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_log_hp.pdf used on input line 631. +Package pdftex.def Info: figures/fig_invariance_log_hp.pdf used on input line 632. (pdftex.def) Requested size: 483.69687pt x 253.52437pt. File: figures/fig_invariance_thresh_lp_single.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_thresh_lp_single.pdf used on input line 662. +Package pdftex.def Info: figures/fig_invariance_thresh_lp_single.pdf used on input line 663. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. [12 <./figures/fig_invariance_log_hp.pdf>] - -File: figures/fig_invariance_thresh_lp_single_noise.pdf Graphic file (type pdf) - -Package pdftex.def Info: figures/fig_invariance_thresh_lp_single_noise.pdf used on input line 685. -(pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [13 <./figures/fig_invariance_thresh_lp_single.pdf>] [14 <./figures/fig_invariance_thresh_lp_single_noise.pdf>] - + File: figures/fig_invariance_thresh_lp_species.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_thresh_lp_species.pdf used on input line 709. +Package pdftex.def Info: figures/fig_invariance_thresh_lp_species.pdf used on input line 693. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - + [13 <./figures/fig_invariance_thresh_lp_single.pdf> <./figures/fig_invariance_thresh_lp_species.pdf>] + File: figures/fig_invariance_full.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_full.pdf used on input line 719. +Package pdftex.def Info: figures/fig_invariance_full.pdf used on input line 703. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [15 + [14 - <./figures/fig_invariance_thresh_lp_species.pdf> <./figures/fig_invariance_full.pdf>] [16] [17] - + <./figures/fig_invariance_full.pdf>] [15] [16] + File: figures/fig_noise_env_sd_conversion.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_noise_env_sd_conversion.pdf used on input line 878. +Package pdftex.def Info: figures/fig_noise_env_sd_conversion.pdf used on input line 862. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [18] [19 <./figures/fig_noise_env_sd_conversion.pdf>] (./main.aux) + [17 <./figures/fig_noise_env_sd_conversion.pdf>] (./main.aux) *********** LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-01-22> @@ -809,18 +804,18 @@ Package logreq Info: Writing requests to 'main.run.xml'. ) Here is how much of TeX's memory you used: - 20769 strings out of 474222 - 448460 string characters out of 5748732 + 20762 strings out of 474222 + 448017 string characters out of 5748732 1937975 words of memory out of 5000000 - 42759 multiletter control sequences out of 15000+600000 + 42752 multiletter control sequences out of 15000+600000 569394 words of font info for 79 fonts, out of 8000000 for 9000 1143 hyphenation exceptions out of 8191 - 94i,19n,93p,1478b,1732s stack positions out of 10000i,1000n,20000p,200000b,200000s + 94i,19n,93p,1496b,1732s stack positions out of 10000i,1000n,20000p,200000b,200000s -Output written on main.pdf (19 pages, 164788506 bytes). +Output written on main.pdf (17 pages, 164189765 bytes). PDF statistics: - 1566 PDF objects out of 1728 (max. 8388607) - 861 compressed objects within 9 object streams + 1521 PDF objects out of 1728 (max. 8388607) + 843 compressed objects within 9 object streams 0 named destinations out of 1000 (max. 500000) - 58 words of extra memory for PDF output out of 10000 (max. 10000000) + 53 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/main.pdf b/main.pdf index 0cd03e3..4ac98fc 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.synctex.gz b/main.synctex.gz index 7a82177..f026919 100644 Binary files a/main.synctex.gz and b/main.synctex.gz differ diff --git a/main.tex b/main.tex index e8bf99b..0cf5390 100644 --- a/main.tex +++ b/main.tex @@ -52,6 +52,7 @@ \newcommand{\figb}{\textbf{b}} \newcommand{\figc}{\textbf{c}} \newcommand{\figd}{\textbf{d}} +\newcommand{\fige}{\textbf{e}} % Math shorthands - Standard symbols: \newcommand{\dec}{\log_{10}} % Logarithm base 10 @@ -641,8 +642,8 @@ the signal for reliable song recognition. different scales $\sca$. \textbf{Right}:~Ratios of the standard deviation of $\env(t)$, $\db(t)$, and $\adapt(t)$ relative to the - respective reference standard deviation for input - $\filt(t)=\noc(t)$. + respective reference standard deviation $\sigma_{\eta}$ + for input $\filt(t)=\noc(t)$. \figa{} and \figb:~Ideally, if $\filt(t)=\sca\cdot\soc(t)$, then $\adapt(t)$ is intensity-invariant across all $\sca$. \figc{} and \figd:~In practice, if @@ -661,49 +662,32 @@ the signal for reliable song recognition. \centering \includegraphics[width=\textwidth]{figures/fig_invariance_thresh_lp_single.pdf} \caption{\textbf{Intensity invariance by thresholding and temporal - averaging depends on the threshold value with regard to - variable range but not saturation level.} - Kernel response $c_i(t)$ is rescaled by $\sca$ and - transformed into binary response $b_i(t)$ and further into - feature $f_i(t)$. Threshold value $\thr$ is set to - different percentiles of the the distribution of $c_i(t)$ - at $\sca=1$. Darker colors indicate higher values of - $\thr$. Indicated time scale of $100\,$ms is the same for - \textbf{a}-\textbf{c} (black bar). - \textbf{a}:~50th percentile. - \textbf{b}:~75th percentile. - \textbf{c}:~100th percentile. - \textbf{d}:~Average value of $f_i(t)$ during the song for - the different $\thr$ in \textbf{a}-\textbf{c}. + averaging depends on both the threshold value and the + noise floor.} + Synthetic input $\adapt(t)$ consists of song component + $\soc(t)$ scaled by $\sca$ with additive noise component + $\noc(t)$. Input $\adapt(t)$ is transformed into kernel + response $c_i(t)$, binary response $b_i(t)$, and feature + $f_i(t)$. Threshold value $\thr$ is set to multiples of + the reference standard deviation $\sigma_{\eta}$ of $c_i(t)$ for input + $\adapt(t)=\noc(t)$. Darker colors correspond to higher + $\thr$. + \textbf{Left}:~$\adapt(t)$, $c_i(t)$, $b_i(t)$, and + $f_i(t)$ for different scales $\sca$ and threshold values + $\thr$. Left-most column is is the pure-noise reference. + \textbf{Right}:~Average value of $f_i(t)$ during the song + for the different $\thr$. + \figa:~Input $\adapt(t)$. + \figb-\figd:~$c_i(t)$, $b_i(t)$, and $f_i(t)$ for the + different $\thr$ based on the same $\adapt(t)$ from + \figa{}. + \fige:~Average value of $f_i(t)$ during the song for + the different $\thr$ in \figb{}-\figd. } \label{fig:inv_thresh-lp_single} \end{figure} \FloatBarrier -\begin{figure}[!ht] - \centering - \includegraphics[width=\textwidth]{figures/fig_invariance_thresh_lp_single_noise.pdf} - \caption{\textbf{Intensity invariance by thresholding and temporal - averaging depends on noise with regard to variable range - but not saturation level.} - Kernel response $c_i(t)$ is rescaled by $\sca$, mixed with - fixed-scale noise component $\noc(t)$, and transformed - into binary response $b_i(t)$ and further into feature - $f_i(t)$. Threshold value $\thr$ is set to different - percentiles of the the distribution of $c_i(t)$ at - $\sca=1$. Darker colors indicate higher values of $\thr$. - Indicated time scale of $100\,$ms is the same for - \textbf{a}-\textbf{c} (black bar). - \textbf{a}:~50th percentile. - \textbf{b}:~75th percentile. - \textbf{c}:~100th percentile. - \textbf{d}:~Average value of $f_i(t)$ during the song for - the different $\thr$ in \textbf{a}-\textbf{c}. - } - \label{fig:inv_thresh-lp_single_noise} -\end{figure} -\FloatBarrier - \begin{figure}[!ht] \centering \includegraphics[width=\textwidth]{figures/fig_invariance_thresh_lp_species.pdf} diff --git a/python/fig_invariance_thresh-lp.py b/python/fig_invariance_thresh-lp.py deleted file mode 100644 index b1857e2..0000000 --- a/python/fig_invariance_thresh-lp.py +++ /dev/null @@ -1,271 +0,0 @@ -import plotstyle_plt -import numpy as np -import matplotlib.pyplot as plt -from itertools import product -from thunderhopper.filetools import search_files -from thunderhopper.modeltools import load_data -from color_functions import load_colors -from plot_functions import hide_axis, ylimits, xlabel, ylabel,\ - plot_line, plot_barcode, strip_zeros, time_bar -from IPython import embed - -def add_snip_axes(fig, grid_kwargs): - grid = fig.add_gridspec(**grid_kwargs) - axes = np.zeros((grid.nrows, grid.ncols), dtype=object) - for i, j in product(range(grid.nrows), range(grid.ncols)): - axes[i, j] = fig.add_subplot(grid[i, j]) - [hide_axis(ax, 'left') for ax in axes.flatten()] - [hide_axis(ax, 'bottom') for ax in axes.flatten()] - return axes - -def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs): - ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05) - for ax, snippet in zip(axes, snippets.T): - plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs) - return None - -def plot_bi_snippets(axes, time, binary, **kwargs): - for ax, binary in zip(axes, binary.T): - plot_barcode(ax, time, binary[:, None], **kwargs) - return None - - -# GENERAL SETTINGS: -target = 'Omocestus_rufipes' -data_paths = search_files(target, excl='noise', dir='../data/inv/thresh_lp/') -stages = ['conv', 'bi', 'feat'] -load_kwargs = dict( - files=stages, - keywords=['scales', 'measure', 'spread'] -) -save_path = '../figures/fig_invariance_thresh_lp.pdf' - -# GRAPH SETTINGS: -fig_kwargs = dict( - figsize=(32/2.54, 16/2.54), -) -super_grid_kwargs = dict( - nrows=2, - ncols=2, - wspace=0, - hspace=0, - left=0, - right=1, - bottom=0, - top=1 -) -subfig_specs = dict( - pure=(0, 0), - noise=(1, 0), - analysis=(slice(None), 1) -) -pure_grid_kwargs = dict( - nrows=len(stages), - ncols=None, - wspace=0.05, - hspace=0.1, - left=0.07, - right=0.95, - bottom=0.15, - top=0.9 -) -noise_grid_kwargs = dict( - nrows=len(stages), - ncols=None, - wspace=0.05, - hspace=0.1, - left=0.07, - right=0.95, - bottom=0.15, - top=0.9 -) -analysis_grid_kwargs = dict( - nrows=1, - ncols=1, - wspace=0, - hspace=0, - left=0.15, - right=0.96, - bottom=0.1, - top=0.95 -) -snip_specs = dict( - conv=(0, slice(None)), - bi=(1, slice(None)), - feat=(2, slice(None)) -) - -# PLOT SETTINGS: -colors = load_colors('../data/stage_colors.npz') -lw_snippets = dict( - conv=0.5, - feat=2 -) -lw_analysis = 3 -xlabels = dict( - analysis='scale $\\alpha$', -) -xlab_analysis_kwargs = dict( - y=0.01, - fontsize=16, - ha='center', - va='bottom', -) -ylabels = dict( - conv='$c_i$', - bi='$b_i$', - feat='$f_i$', - analysis='ratio $\\text{SD}_{\\alpha}\\,/\\,\\text{SD}_{\\min[\\alpha]}$', - # analysis='ratio $\\sigma_{\\alpha}\\,/\\,\\sigma_{\\min[\\alpha]}$', -) -ylab_snip_kwargs = dict( - x=0.01, - fontsize=20, - rotation=0, - ha='left', - va='center', -) -ylab_analysis_kwargs = dict( - x=0.02, - fontsize=16, - ha='center', - va='top', -) -xloc = dict( - analysis=10, -) -letter_snip_kwargs = dict( - x=0.02, - y=1, - ha='left', - va='top', - fontsize=22, - fontweight='bold' -) -letter_analysis_kwargs = dict( - x=0, - y=1, - ha='left', - va='top', - fontsize=22, - fontweight='bold' -) -bar_time = 5 -bar_kwargs = dict( - y0=0.7, - y1=0.8, - color='k', - lw=0, -) -spread_kwargs = dict( - alpha=0.3, - lw=0, - zorder=0 -) -kernel_ind = 0 - -# EXECUTION: -for data_path in data_paths: - print(f'Processing {data_path}') - - # Load invariance data: - pure_data, config = load_data(data_path, **load_kwargs) - noise_data, _ = load_data(data_path.replace('.npz', '_noise.npz'), **load_kwargs) - t_full = np.arange(pure_data['conv'].shape[0]) / config['env_rate'] - - # Reduce snippet data to kernel subset: - pure_data['conv'] = pure_data['conv'][:, kernel_ind] - pure_data['bi'] = pure_data['bi'][:, kernel_ind] - pure_data['feat'] = pure_data['feat'][:, kernel_ind] - noise_data['conv'] = noise_data['conv'][:, kernel_ind] - noise_data['bi'] = noise_data['bi'][:, kernel_ind] - noise_data['feat'] = noise_data['feat'][:, kernel_ind] - - # Prepare overall graph: - fig = plt.figure(**fig_kwargs) - super_grid = fig.add_gridspec(**super_grid_kwargs) - - # Prepare pure-song snippet axes: - pure_subfig = fig.add_subfigure(super_grid[subfig_specs['pure']]) - pure_grid_kwargs['nrows' if pure_grid_kwargs['nrows'] is None else 'ncols'] = pure_data['example_scales'].size - pure_axes = add_snip_axes(pure_subfig, pure_grid_kwargs) - for ax, stage in zip(pure_axes[:, 0], stages): - ylabel(ax, ylabels[stage], **ylab_snip_kwargs, - transform=pure_subfig.transSubfigure) - for ax, scale in zip(pure_axes[snip_specs['conv']], pure_data['example_scales']): - ax.set_title(f'$\\alpha={strip_zeros(scale)}$') - pure_subfig.text(s='a', **letter_snip_kwargs) - - # Prepare noise-song snippet axes: - noise_subfig = fig.add_subfigure(super_grid[subfig_specs['noise']]) - noise_grid_kwargs['nrows' if noise_grid_kwargs['nrows'] is None else 'ncols'] = noise_data['example_scales'].size - noise_grid = noise_subfig.add_gridspec(**noise_grid_kwargs) - noise_axes = add_snip_axes(noise_subfig, noise_grid_kwargs) - for ax, stage in zip(noise_axes[:, 0], stages): - ylabel(ax, ylabels[stage], **ylab_snip_kwargs, - transform=noise_subfig.transSubfigure) - for ax, scale in zip(noise_axes[snip_specs['conv']], noise_data['example_scales']): - ax.set_title(f'$\\alpha={strip_zeros(scale)}$') - noise_subfig.text(s='b', **letter_snip_kwargs) - - # Prepare analysis axis: - analysis_subfig = fig.add_subfigure(super_grid[subfig_specs['analysis']]) - analysis_grid = analysis_subfig.add_gridspec(**analysis_grid_kwargs) - analysis_ax = analysis_subfig.add_subplot(analysis_grid[0, 0]) - analysis_ax.set_xlim(noise_data['scales'].min(), noise_data['scales'].max()) - analysis_ax.xaxis.set_major_locator(plt.MultipleLocator(xloc['analysis'])) - xlabel(analysis_ax, xlabels['analysis'], **xlab_analysis_kwargs, - transform=analysis_subfig.transSubfigure) - # analysis_ax.set_yscale('log') - ylabel(analysis_ax, ylabels['analysis'], **ylab_analysis_kwargs, - transform=analysis_subfig.transSubfigure) - analysis_subfig.text(s='c', **letter_analysis_kwargs) - - # Plot pure-song kernel response snippets: - plot_snippets(pure_axes[snip_specs['conv']], t_full, pure_data['conv'], - c=colors['conv'], lw=lw_snippets['conv']) - - # Plot pure-song binary snippets: - plot_bi_snippets(pure_axes[snip_specs['bi']], t_full, pure_data['bi'], - color=colors['bi'], lw=0) - - # Plot pure-song feature snippets: - plot_snippets(pure_axes[snip_specs['feat']], t_full, pure_data['feat'], - ymin=0, ymax=1, c=colors['feat'], lw=lw_snippets['feat']) - - # Indicate time scale: - time_bar(pure_axes[snip_specs['conv']][0], bar_time, **bar_kwargs) - - # Plot noise-song kernel response snippets: - plot_snippets(noise_axes[snip_specs['conv']], t_full, noise_data['conv'], - c=colors['conv'], lw=lw_snippets['conv']) - - # Plot noise-song binary snippets: - plot_bi_snippets(noise_axes[snip_specs['bi']], t_full, noise_data['bi'], - color=colors['bi'], lw=0) - - # Plot noise-song feature snippets: - plot_snippets(noise_axes[snip_specs['feat']], t_full, noise_data['feat'], - ymin=0, ymax=1, c=colors['feat'], lw=lw_snippets['feat']) - - # Indicate time scale: - time_bar(noise_axes[snip_specs['conv']][0], bar_time, **bar_kwargs) - - # Plot noise-song SD ratios (limited): - analysis_ax.plot(noise_data['scales'], noise_data['measure_conv'], - c=colors['conv'], lw=lw_analysis) - lower, upper = noise_data['spread_conv'] - analysis_ax.fill_between(noise_data['scales'], lower, upper, - color=colors['conv'], **spread_kwargs) - analysis_ax.plot(noise_data['scales'], noise_data['measure_feat'], - c=colors['feat'], lw=lw_analysis) - lower, upper = noise_data['spread_feat'] - analysis_ax.fill_between(noise_data['scales'], lower, upper, - color=colors['feat'], **spread_kwargs) - - if save_path is not None: - fig.savefig(save_path) - plt.show() - -print('Done.') -embed() diff --git a/python/fig_invariance_thresh-lp_single.py b/python/fig_invariance_thresh-lp_single.py index 19efb3c..274acf8 100644 --- a/python/fig_invariance_thresh-lp_single.py +++ b/python/fig_invariance_thresh-lp_single.py @@ -1,73 +1,71 @@ import plotstyle_plt import numpy as np import matplotlib.pyplot as plt +from itertools import product from thunderhopper.filetools import search_files from thunderhopper.modeltools import load_data from thunderhopper.filtertools import find_kern_specs from color_functions import load_colors, shade_colors -from plot_functions import hide_axis, ylimits, xlabel, ylabel, super_ylabel, super_xlabel,\ - plot_line, plot_barcode, strip_zeros, time_bar,\ - letter_subplot, letter_subplots, title_subplot +from plot_functions import shift_subplot, hide_axis, ylimits, xlabel, ylabel,\ + super_ylabel, plot_line, plot_barcode, strip_zeros,\ + time_bar, letter_subplot, letter_subplots, title_subplot,\ + set_clip_box from IPython import embed -def add_snip_axes(fig, grid_kwargs, snip_specs): +def add_snip_axes(fig, grid_kwargs): grid = fig.add_gridspec(**grid_kwargs) - axes = np.zeros((len(snip_specs), grid.ncols), dtype=object) - for i, specs in enumerate(snip_specs.values()): - for j in range(grid.ncols): - axes[i, j] = fig.add_subplot(grid[specs, j]) - [hide_axis(ax, 'left') for ax in axes[:, 1:].flatten()] + axes = np.zeros((grid.nrows, grid.ncols), dtype=object) + for i, j in product(range(grid.nrows), range(grid.ncols)): + axes[i, j] = fig.add_subplot(grid[i, j]) + if j == 0: + shift_subplot(axes[i, j], dx=snip_col_shift) + [hide_axis(ax, 'left') for ax in axes[:, 2:].flatten()] [hide_axis(ax, 'bottom') for ax in axes.flatten()] return axes -def plot_snippets(axes, time, snippets, ymin=None, ymax=None, +def plot_snippets(axes, time, snippets, ymin=None, ymax=None, ypad=0.05, thresh=None, fill_kwargs={}, **kwargs): - ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05) + ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=ypad) + handles = [] for ax, snippet in zip(axes, snippets.T): - plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs) + handles.append(plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs)) if thresh is not None: ax.fill_between(time, thresh, snippet, where=(snippet > thresh), **fill_kwargs) - return None + return handles def plot_bi_snippets(axes, time, binary, **kwargs): for ax, binary in zip(axes, binary.T): plot_barcode(ax, time, binary[:, None], **kwargs) return None -def side_distributions(axes, snippets, inset_bounds, thresh, nbins=50, - ymin=None, ymax=None, fill_kwargs={}, **kwargs): - limits = np.array([snippets.min(), snippets.max()]) * 1.05 +def side_distributions(axes, snippets, inset_bounds, thresh, nbins=1000, + fill_kwargs={}, **kwargs): + limits = np.array([snippets.min(), snippets.max()]) * 1.1 edges = np.linspace(*limits, nbins + 1) centers = edges[:-1] + (edges[1] - edges[0]) / 2 + insets = [] for ax, snippet in zip(axes, snippets.T): pdf, _ = np.histogram(snippet, edges, density=True) inset = ax.inset_axes(inset_bounds) inset.plot(pdf, centers, **kwargs) - inset.fill_betweenx(centers, pdf.min(), pdf, where=(centers > thresh), - **fill_kwargs) - ylimits(centers, inset, minval=ymin, maxval=ymax, pad=0) + inset.fill_betweenx(centers, pdf.min(), pdf, where=(centers > thresh), **fill_kwargs) inset.set_xlim(0, pdf.max()) + inset.set_ylim(ax.get_ylim()) inset.axis('off') - return None + insets.append(inset) + return insets # GENERAL SETTINGS: -with_noise = True target = 'Omocestus_rufipes' -search_kwargs = dict( - incl=['subset', 'noise'] if with_noise else 'subset', - excl=None if with_noise else 'noise', - dir='../data/inv/thresh_lp/' -) -data_paths = search_files(target, **search_kwargs) +data_paths = search_files(target, incl='noise', dir='../data/inv/thresh_lp/') stages = ['conv', 'bi', 'feat'] load_kwargs = dict( files=stages, keywords=['scales', 'snip', 'measure', 'thresh'] ) save_path = '../figures/fig_invariance_thresh_lp_single.pdf' -if with_noise and save_path is not None: - save_path = save_path.replace('.pdf', '_noise.pdf') +exclude_zero = True # GRAPH SETTINGS: fig_kwargs = dict( @@ -83,19 +81,34 @@ super_grid_kwargs = dict( bottom=0, top=1 ) +input_rows = 1 +snip_rows = 2 subfig_specs = dict( - snip=(slice(None), slice(super_grid_kwargs['ncols'] - 1)), + input=(slice(input_rows), slice(-1)), + snip=[np.array([input_rows, input_rows + snip_rows]), slice(-1)], big=(slice(None), -1), ) +snip_col_shift = -0.07 snip_grid_kwargs = dict( - nrows=len(stages) + 1, + nrows=len(stages), ncols=None, wspace=0.3, hspace=0, - left=0.17, + left=0.25, right=0.93, bottom=0.15, - top=0.9 + top=0.95, + height_ratios=[2, 1, 1] +) +input_grid_kwargs = dict( + nrows=1, + ncols=None, + wspace=snip_grid_kwargs['wspace'], + hspace=0, + left=snip_grid_kwargs['left'], + right=snip_grid_kwargs['right'], + bottom=0.15, + top=0.75, ) big_grid_kwargs = dict( nrows=1, @@ -107,12 +120,7 @@ big_grid_kwargs = dict( bottom=0.1, top=0.99 ) -snip_specs = dict( - conv=slice(0, -2), - bi=-2, - feat=-1 -) -inset_bounds = [1.02, 0, 0.2, 1] +dist_inset_bounds = [1.02, 0, 0.2, 1] # PLOT SETTINGS: fs = dict( @@ -124,29 +132,24 @@ fs = dict( bar=16, ) colors = load_colors('../data/stage_colors.npz') -color_factors = [0.2, -0.2] +shade_factors = [0.2, -0.2] lw = dict( - conv=1, + inv=1.5, + conv=1.5, bi=0.1, feat=3, big=4, ) xlabels = dict( - snip='time [s]', big='scale $\\alpha$', ) ylabels = dict( + inv='$x_{\\text{adapt}}$', conv='$c_i$', bi='$b_i$', feat='$f_i$', big='$\\mu_f$', ) -xlab_snip_kwargs = dict( - y=0, - fontsize=fs['lab_norm'], - ha='center', - va='bottom', -) xlab_big_kwargs = dict( y=0, fontsize=fs['lab_norm'], @@ -157,7 +160,7 @@ ylab_snip_kwargs = dict( x=0.08, fontsize=fs['lab_tex'], rotation=0, - ha='right', + ha='center', va='center', ) ylab_super_kwargs = dict( @@ -168,14 +171,20 @@ ylab_super_kwargs = dict( ) ylab_big_kwargs = dict( x=0, - fontsize=fs['lab_norm'], + fontsize=fs['lab_tex'], ha='center', va='top', ) +ypad = dict( + inv=0.05, + conv=0.05, + big=0.075 +) yloc = dict( - conv=100, - bi=1, - feat=1, + inv=(2, 200), + conv=(0.02, 2), + bi=(1, 1), + feat=(1, 1), big=0.2, ) title_kwargs = dict( @@ -200,7 +209,6 @@ letter_big_kwargs = dict( fontsize=fs['letter'], ) dist_kwargs = dict( - nbins=50, c='k', lw=1, ) @@ -211,8 +219,8 @@ dist_fill_kwargs = dict( bar_time = 0.1 bar_kwargs = dict( dur=bar_time, - y0=-0.25, - y1=-0.1, + y0=-0.5, + y1=-0.35, xshift=1, color='k', lw=0, @@ -225,7 +233,16 @@ bar_kwargs = dict( va='center', ) ) -kernel = np.array([ +leg_kwargs = dict( + ncols=2, + loc='center', + bbox_to_anchor=(0, 0.95, 1, 0.05), + frameon=False, + fontsize=fs['tit_norm'], + handlelength=1.5, + columnspacing=1, +) +kern_specs = np.array([ [1, 0.008], [2, 0.004], [3, 0.002], @@ -238,96 +255,138 @@ for data_path in data_paths: print(f'Processing {data_path}') # Load invariance data: - data, config = load_data(data_path, **load_kwargs) - t_full = np.arange(data['snip_conv'].shape[0]) / config['env_rate'] + noise_data, config = load_data(data_path, **load_kwargs) + pure_data, _ = load_data(data_path.replace('noise', 'pure'), **load_kwargs) + + # Unpack shared variables: + scales = noise_data['scales'] + plot_scales = noise_data['example_scales'] + thresh_rel = noise_data['thresh_rel'] + thresh_abs = noise_data['thresh_abs'] + + # Reduce to kernel subset and crop to zoom frame: + t_full = np.arange(noise_data['snip_conv'].shape[0]) / config['env_rate'] zoom_abs = zoom_rel * t_full[-1] zoom_inds = (t_full >= zoom_abs[0]) & (t_full <= zoom_abs[1]) - kern_ind = find_kern_specs(config['k_specs'], kerns=kernel)[0] - - # Reduce to kernel subset and crop time to zoom frame: - data['snip_conv'] = data['snip_conv'][zoom_inds, kern_ind, ...] - data['snip_bi'] = data['snip_bi'][zoom_inds, kern_ind, ...] - data['snip_feat'] = data['snip_feat'][zoom_inds, kern_ind, ...] - data['measure_feat'] = data['measure_feat'][:, kern_ind, :] - t_full = np.arange(data['snip_conv'].shape[0]) / config['env_rate'] + kern_ind = find_kern_specs(config['k_specs'], kerns=kern_specs)[0] + noise_data['snip_inv'] = noise_data['snip_inv'][zoom_inds, :] + noise_data['snip_conv'] = noise_data['snip_conv'][zoom_inds, kern_ind, :] + noise_data['snip_bi'] = noise_data['snip_bi'][zoom_inds, kern_ind, :, :] + noise_data['snip_feat'] = noise_data['snip_feat'][zoom_inds, kern_ind, :, :] + noise_data['measure_feat'] = noise_data['measure_feat'][:, kern_ind, :] + pure_data['measure_feat'] = pure_data['measure_feat'][:, kern_ind, :] + thresh_abs = thresh_abs[:, kern_ind] + t_full = np.arange(noise_data['snip_conv'].shape[0]) / config['env_rate'] + if exclude_zero: + # Reduce to nonzero scales: + nonzero_inds = scales > 0 + scales = scales[nonzero_inds] + noise_data['measure_feat'] = noise_data['measure_feat'][nonzero_inds, :] + pure_data['measure_feat'] = pure_data['measure_feat'][nonzero_inds, :] # Get threshold-specific colors: - factors = np.linspace(*color_factors, data['threshs'].size) - colors = dict( + factors = np.linspace(*shade_factors, thresh_rel.size) + shaded = dict( conv=shade_colors(colors['conv'], factors), bi=shade_colors(colors['bi'], factors), feat=shade_colors(colors['feat'], factors), ) - # Adjust grid parameters: - super_grid_kwargs['nrows'] = data['threshs'].size - snip_grid_kwargs['ncols'] = data['example_scales'].size + # Adjust grid parameters to loaded data: + super_grid_kwargs['nrows'] = snip_rows * thresh_rel.size + 1 + input_grid_kwargs['ncols'] = plot_scales.size + snip_grid_kwargs['ncols'] = plot_scales.size # Prepare overall graph: fig = plt.figure(**fig_kwargs) super_grid = fig.add_gridspec(**super_grid_kwargs) + # Prepare input snippet axes: + input_subfig = fig.add_subfigure(super_grid[subfig_specs['input']]) + input_axes = add_snip_axes(input_subfig, input_grid_kwargs).ravel() + input_axes[0].yaxis.set_major_locator(plt.MultipleLocator(yloc['inv'][0])) + input_axes[1].yaxis.set_major_locator(plt.MultipleLocator(yloc['inv'][1])) + ylabel(input_axes[0], ylabels['inv'], transform=input_subfig.transSubfigure, **ylab_snip_kwargs) + for ax, scale in zip(input_axes, plot_scales): + title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', ref=input_subfig, **title_kwargs) + letter_subplot(input_subfig, 'a', **letter_snip_kwargs) + # Prepare snippet axes: - snip_axes = {} - for i in range(data['threshs'].size): - subfig_specs['snip'] = (i, subfig_specs['snip'][1]) - snip_subfig = fig.add_subfigure(super_grid[subfig_specs['snip']]) - axes = add_snip_axes(snip_subfig, snip_grid_kwargs, snip_specs) - snip_axes[snip_subfig] = axes - super_ylabel(f'{strip_zeros(100 * data["thresh_perc"][i])}%', + snip_subfigs, snip_axes = [], [] + for i in range(thresh_rel.size): + subfig_spec = subfig_specs['snip'].copy() + subfig_spec[0] = slice(*(subfig_spec[0] + i * snip_rows)) + snip_subfig = fig.add_subfigure(super_grid[*subfig_spec]) + axes = add_snip_axes(snip_subfig, snip_grid_kwargs) + [hide_axis(ax, 'left') for ax in axes[1:, 1]] + super_ylabel(f'$\\Theta={strip_zeros(thresh_rel[i])}\\cdot\\sigma_{{\\eta}}$', snip_subfig, axes[-1, 0], axes[0, 0], **ylab_super_kwargs) - for ax, stage in zip(axes[:, 0], stages): - ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage])) - ylabel(ax, ylabels[stage], **ylab_snip_kwargs, - transform=snip_subfig.transSubfigure) - if i == 0: - for ax, scale in zip(axes[0, :], data['example_scales']): - title = f'$\\alpha={strip_zeros(scale)}$' - title_subplot(ax, title, **title_kwargs, ref=fig) - elif i == data['threshs'].size - 1: + for (ax1, ax2), stage in zip(axes[:, :2], stages): + ax1.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][0])) + ax2.yaxis.set_major_locator(plt.MultipleLocator(yloc[stage][1])) + ylabel(ax1, ylabels[stage], transform=snip_subfig.transSubfigure, **ylab_snip_kwargs) + # for ax, scale in zip(axes[0, :], plot_scales): + # title_subplot(ax, f'$\\alpha={strip_zeros(scale)}$', ref=snip_subfig, **title_kwargs) + if i == thresh_rel.size - 1: axes[-1, -1].set_xlim(t_full[0], t_full[-1]) time_bar(axes[-1, -1], **bar_kwargs) - letter_subplots(snip_axes.keys(), **letter_snip_kwargs) + snip_subfigs.append(snip_subfig) + snip_axes.append(axes) + letter_subplots(snip_subfigs, 'bcd', **letter_snip_kwargs) # Prepare analysis axis: big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']]) big_grid = big_subfig.add_gridspec(**big_grid_kwargs) big_ax = big_subfig.add_subplot(big_grid[0, 0]) - xlabel(big_ax, xlabels['big'], **xlab_big_kwargs, - transform=big_subfig.transSubfigure) - ylabel(big_ax, ylabels['big'], **ylab_big_kwargs, - transform=big_subfig.transSubfigure) - big_ax.set_xlim(data['scales'].min(), data['scales'].max()) - big_ax.set_xscale('symlog', linthresh=data['scales'][1], linscale=0.5) - ylimits(data['measure_feat'], big_ax, minval=0, pad=0.01) + big_ax.set_xlim(scales[0], scales[-1]) + big_ax.set_xscale('symlog', linthresh=scales[scales > 0][0], linscale=0.5) + ylimits(noise_data['measure_feat'], big_ax, minval=0, pad=ypad['big']) big_ax.yaxis.set_major_locator(plt.MultipleLocator(yloc['big'])) - letter_subplot(big_subfig, 'd', **letter_big_kwargs, ref=list(snip_axes.keys())[0]) + xlabel(big_ax, xlabels['big'], transform=big_subfig.transSubfigure, **xlab_big_kwargs) + ylabel(big_ax, ylabels['big'], transform=big_subfig.transSubfigure, **ylab_big_kwargs) + letter_subplot(big_subfig, 'e', **letter_big_kwargs, ref=input_subfig) + + # Plot intensity-adapted snippets: + plot_snippets(input_axes, t_full, noise_data['snip_inv'], + ypad=ypad['inv'], c=colors['inv'], lw=lw['inv']) + ylimits(noise_data['snip_inv'][:, 0], input_axes[0], pad=ypad['inv']) # Plot representation snippets per threshold: - conv_min, conv_max = ylimits(data['snip_conv'], pad=0.02) - for i, (subfig, axes) in enumerate(snip_axes.items()): - dist_fill_kwargs['color'] = colors['bi'][i] + for i, (subfig, axes) in enumerate(zip(snip_subfigs, snip_axes)): + dist_fill_kwargs['color'] = shaded['bi'][i] # Plot kernel response snippets: - plot_snippets(axes[0, :], t_full, data['snip_conv'][:, :, i], - thresh=data['threshs'][i], ymin=conv_min, ymax=conv_max, - fill_kwargs=dist_fill_kwargs, c=colors['conv'][i], lw=lw['conv']) + plot_snippets(axes[0, :], t_full, noise_data['snip_conv'], thresh=thresh_abs[i], + ypad=ypad['conv'], fill_kwargs=dist_fill_kwargs, c=shaded['conv'][i], lw=lw['conv']) + ylimits(noise_data['snip_conv'][:, 0], axes[0, 0], pad=ypad['conv']) + + # Plot kernel response distributions: + side_distributions(axes[0, :1], noise_data['snip_conv'][:, :1], dist_inset_bounds, + thresh_abs[i], nbins=50, fill_kwargs=dist_fill_kwargs, **dist_kwargs) + side_distributions(axes[0, 1:], noise_data['snip_conv'][:, 1:], dist_inset_bounds, + thresh_abs[i], nbins=50, fill_kwargs=dist_fill_kwargs, **dist_kwargs) # Plot binary snippets: - plot_bi_snippets(axes[1, :], t_full, data['snip_bi'][:, :, i], - color=colors['bi'][i], lw=lw['bi']) + plot_bi_snippets(axes[1, :], t_full, noise_data['snip_bi'][:, :, i], + color=shaded['bi'][i], lw=lw['bi']) + # Plot feature snippets: - plot_snippets(axes[2, :], t_full, data['snip_feat'][:, :, i], - ymin=0, ymax=1, c=colors['feat'][i], lw=lw['feat']) + handles = plot_snippets(axes[2, :], t_full, noise_data['snip_feat'][:, :, i], + ymin=0, ymax=1, c=shaded['feat'][i], lw=lw['feat']) + [set_clip_box(h[0], ax, bounds=[[0, -0.05], [1, 1.05]]) for h, ax in zip(handles, axes[2, :])] - # Plot kernel response distribution: - side_distributions(axes[0, :], data['snip_conv'][:, :, i], inset_bounds, - data['threshs'][i], ymin=conv_min, ymax=conv_max, - fill_kwargs=dist_fill_kwargs, **dist_kwargs) + # Plot pure-song analysis results: + handles = big_ax.plot(scales, pure_data['measure_feat'], lw=lw['big'], ls='dotted') + [h.set_color(c) for h, c in zip(handles, shaded['feat'])] - # Plot analysis results: - handles = big_ax.plot(data['scales'], data['measure_feat'], lw=lw['big']) - [h.set_color(c) for h, c in zip(handles, colors['feat'])] + # Plot noise-song analysis results: + handles = big_ax.plot(scales, noise_data['measure_feat'], lw=lw['big']) + [h.set_color(c) for h, c in zip(handles, shaded['feat'])] + + # Add proxy legend: + h1 = big_ax.plot([], [], c='k', lw=lw['big'], label='$\\alpha\\cdot s(t) + \\eta(t)$')[0] + h2 = big_ax.plot([], [], c='k', lw=lw['big'], ls='dotted', label='$\\alpha\\cdot s(t)$')[0] + big_ax.legend(handles=[h1, h2], **leg_kwargs) if save_path is not None: fig.savefig(save_path) diff --git a/python/fig_invariance_thresh-lp_subset.py b/python/fig_invariance_thresh-lp_subset.py deleted file mode 100644 index 887aacd..0000000 --- a/python/fig_invariance_thresh-lp_subset.py +++ /dev/null @@ -1,160 +0,0 @@ -import plotstyle_plt -import numpy as np -import matplotlib.pyplot as plt -from thunderhopper.filetools import search_files -from thunderhopper.modeltools import load_data -from thunderhopper.filtertools import find_kern_specs -from color_functions import load_colors, shade_colors -from plot_functions import hide_axis, ylimits, xlabel, ylabel, super_ylabel,\ - plot_line, plot_barcode, strip_zeros, time_bar,\ - letter_subplot, letter_subplots, hide_ticks,\ - super_xlabel, super_ylabel, assign_colors -from IPython import embed - -# GENERAL SETTINGS: -target = 'Omocestus_rufipes' -search_kwargs = dict( - incl='subset', - excl='noise', - dir='../data/inv/thresh_lp/' -) -pure_paths = search_files(target, **search_kwargs) -load_kwargs = dict( - keywords=['scales', 'measure', 'thresh'] -) -save_path = None#'../figures/fig_invariance_thresh_lp_subset.pdf' - -# GRAPH SETTINGS: -fig_kwargs = dict( - figsize=(32/2.54, 16/2.54), -) -super_grid_kwargs = dict( - nrows=1, - ncols=1, - wspace=0, - hspace=0, - left=0, - right=1, - bottom=0, - top=1 -) -grid_kwargs = dict( - nrows=2, - ncols=1, - wspace=0, - hspace=0.1, - left=0.15, - right=0.95, - bottom=0.1, - top=0.85 -) -inset_bounds = [0.2, 1.01, 0.6, 0.4] - -# PLOT SETTINGS: -colors = load_colors('../data/stage_colors.npz') -color_factors = [-0.5, 0.5] -lw = dict( - one=3, - kern=3, - all=1, -) -ax_labels = dict( - x='scale $\\alpha$', - y='$\\mu_f$', -) -xlab_kwargs = dict( - y=0.005, - fontsize=16, - ha='center', - va='bottom', -) -ylab_kwargs = dict( - x=0, - fontsize=20, - ha='left', - va='center', -) -yloc = 0.2 - -# EXECUTION: -for pure_path in pure_paths: - print(f'Processing {pure_path}') - noise_path = pure_path.replace('.npz', '_noise.npz') - - # Load kernel invariance data: - pure_data, config = load_data(pure_path, **load_kwargs) - noise_data, _ = load_data(noise_path, **load_kwargs) - scales = pure_data['scales'] - - # Adjust grid parameters: - n_columns = config['k_specs'].shape[0] + 1 - super_grid_kwargs['ncols'] = n_columns - - # Prepare overall graph: - fig = plt.figure(**fig_kwargs) - super_grid = fig.add_gridspec(**super_grid_kwargs) - - # Prepare axes: - all_axes = np.zeros((grid_kwargs['nrows'], n_columns), dtype=object) - subfigs = [] - for i in range(n_columns): - subfig = fig.add_subfigure(super_grid[0, i]) - grid = subfig.add_gridspec(**grid_kwargs) - subfigs.append(subfig) - for j in range(grid_kwargs['nrows']): - ax = subfig.add_subplot(grid[j, 0]) - ax.set_xlim(scales[0], scales[-1]) - ax.set_ylim(0, 1) - ax.set_xscale('symlog', linthresh=scales[1], linscale=0.5) - ax.yaxis.set_major_locator(plt.MultipleLocator(yloc)) - if i > 0: - hide_ticks(ax, side='left') - all_axes[j, i] = ax - hide_ticks(all_axes[0, i], side='bottom') - super_xlabel(ax_labels['x'], fig, all_axes[-1, 0], all_axes[-1, -1], **xlab_kwargs) - super_ylabel(ax_labels['y'], fig, all_axes[0, 0], all_axes[1, 0], **ylab_kwargs) - - # Plot kernel-specific results: - in_min, in_high = ylimits(config['kernels'], pad=0.05) - for i in range(config['k_specs'].shape[0]): - pure_ax, noise_ax = all_axes[:, i] - # Plot results of pure-song analysis: - pure_ax.plot(scales, pure_data['measure_feat'][:, i, :], - c=colors['feat'], lw=lw['one']) - # Plot results of noise-song analysis: - noise_ax.plot(scales, noise_data['measure_feat'][:, i, :], - c=colors['feat'], lw=lw['one']) - # Indicate kernel waveform: - inset = pure_ax.inset_axes(inset_bounds) - inset.plot(config['k_times'], config['kernels'][:, i], c='k', lw=lw['kern']) - inset.set_xlim(config['k_times'][0], config['k_times'][-1]) - inset.set_ylim(in_min, in_high) - inset.axis('off') - - # Load population invariance data: - pure_data, config = load_data(pure_path.replace('_subset', ''), **load_kwargs) - noise_data, _ = load_data(noise_path.replace('_subset', ''), **load_kwargs) - scales = pure_data['scales'] - - # Get kernel type-specific colors: - types, ind = np.unique(config['k_specs'][:, 0], return_index=True) - types = types[np.argsort(ind)].astype(int) - factors = np.linspace(*color_factors, types.size) - kern_colors = shade_colors(colors['feat'], factors) - kern_colors = dict(zip(types.astype(str), kern_colors)) - - # Plot population-wide results: - pure_ax, noise_ax = all_axes[:, -1] - handles = pure_ax.plot(scales, pure_data['measure_feat'], c='k', lw=lw['all']) - assign_colors(handles, config['k_specs'][:, 0], kern_colors) - - handles = noise_ax.plot(scales, noise_data['measure_feat'], c='k', lw=lw['all']) - assign_colors(handles, config['k_specs'][:, 0], kern_colors) - - - if save_path is not None: - fig.savefig(save_path) - plt.show() - -print('Done.') -embed() diff --git a/python/plot_functions.py b/python/plot_functions.py index e6cf6da..53b3671 100644 --- a/python/plot_functions.py +++ b/python/plot_functions.py @@ -1,7 +1,7 @@ import string import numpy as np import matplotlib.pyplot as plt -from matplotlib.transforms import BboxTransformTo +from matplotlib.transforms import Bbox, BboxTransformTo, TransformedBbox def hide_ticks(ax, side='bottom', ticks=True): axis = 'x' if side in ['top', 'bottom'] else 'y' @@ -33,6 +33,14 @@ def get_trans_artist(artist): return BboxTransformTo(artist.get_tightbbox(renderer)) raise ValueError('Artist does not have a bounding box to use as transform.') +def shift_subplot(ax, dx=0, dy=0, ref=None): + if ref is not None: + transform = get_trans_artist(ref) + get_trans_artist(ax.figure).inverted() + dx, dy = transform.transform((dx, dy)) - transform.transform((0, 0)) + pos = ax.get_position() + ax.set_position([pos.x0 + dx, pos.y0 + dy, pos.width, pos.height]) + return None + def title_subplot(artist, title, x=0.5, y=1.0, xref=None, yref=None, ref=None, ha='center', va='bottom', fontsize=16, fontweight='normal', **kwargs): trans_artist = get_trans_artist(artist) @@ -68,6 +76,10 @@ def letter_subplots(artists, labels=None, x=None, y=None, xref=None, yref=None, return handles def xlimits(time, ax=None, minval=None, maxval=None, pad=0.05): + if minval is not None and maxval is not None: + if ax is not None: + return ax.set_xlim([minval, maxval]) + return [minval, maxval] limits = [minval, maxval] if minval is None: limits[0] = time[0] @@ -83,6 +95,10 @@ def xlimits(time, ax=None, minval=None, maxval=None, pad=0.05): return limits def ylimits(signal, ax=None, minval=None, maxval=None, pad=0.05): + if minval is not None and maxval is not None: + if ax is not None: + return ax.set_ylim([minval, maxval]) + return [minval, maxval] limits = [minval, maxval] if minval is None: limits[0] = signal.min() @@ -267,3 +283,7 @@ def zoom_inset(ax, inset, handle, x0=None, x1=None, y0=None, y1=None, ref='x', visibility = low_left, up_left, low_right, up_right [l.set_visible(v) for l, v in zip(elements.connectors, visibility)] return inset_handle, elements.rectangle, elements.connectors + +def set_clip_box(artist, ax, bounds=[[0, -0.05], [1, 1.05]]): + artist.set_clip_box(TransformedBbox(Bbox(bounds), ax.transAxes)) + return None diff --git a/python/save_inv_data_thresh-lp.py b/python/save_inv_data_thresh-lp.py index db1b764..0e5dc7e 100644 --- a/python/save_inv_data_thresh-lp.py +++ b/python/save_inv_data_thresh-lp.py @@ -1,86 +1,151 @@ -import glob import numpy as np +import matplotlib.pyplot as plt from thunderhopper.modeltools import load_data, save_data -from thunderhopper.filetools import crop_paths +from thunderhopper.filetools import search_files, crop_paths from thunderhopper.filters import sosfilter +from thunderhopper.filtertools import find_kern_specs +from thunderhopper.model import convolve_kernels from IPython import embed # GENERAL SETTINGS: -target = 'Omocestus_rufipes' -data_paths = glob.glob(f'../data/processed/{target}*.npz') +target = ['Omocestus_rufipes', '*'][0] +data_paths = search_files(target, dir='../data/processed/') +noise_path = '../data/processed/white_noise_sd-1.npz' save_path = '../data/inv/thresh_lp/' # ANALYSIS SETTINGS: -add_noise = False -thresh_percent = 90 -example_scales = np.array([0, 1, 10, 50]) -scales = np.geomspace(0.01, 100, 100) +add_noise = True +save_snippets = add_noise and True +plot_results = False +example_scales = np.array([0, 1, 10, 30, 100]) +scales = np.geomspace(0.01, 10000, 100) scales = np.unique(np.concatenate((scales, example_scales))) +thresh_rel = np.array([0.5, 1, 3]) +kern_specs = np.array([ + [1, 0.008], + [2, 0.004], + [3, 0.002], +]) + +# PREPARATION: +pure_noise = np.load(noise_path)['inv'] # EXECUTION: for data_path, name in zip(data_paths, crop_paths(data_paths)): print(f'Processing {name}') save_name = save_path + name - # Get pure-song kernel responses: - data, config = load_data(data_path, files='conv') - song, rate = data['conv'], data['conv_rate'] + # Get adapted envelope (prior to convolution): + data, config = load_data(data_path, files='inv') + song, rate = data['inv'], data['inv_rate'] # Get song segment to be analyzed: time = np.arange(song.shape[0]) / rate start, end = data['songs_0'].ravel() segment = (time >= start) & (time <= end) - + + # Reduce to kernel subset: + kern_inds = find_kern_specs(config['k_specs'], kerns=kern_specs) + config['kernels'] = config['kernels'][:, kern_inds] + config['k_specs'] = config['k_specs'][kern_inds, :] + config['k_props'] = [config['k_props'][i] for i in kern_inds] + # Normalize song component: - song /= song[segment, :].std(axis=0) + song /= song[segment].std() - if add_noise: - # Get normalized noise: - rng = np.random.default_rng() - noise = rng.normal(size=(song.shape[0], 1)) - noise /= noise[segment].std() + # Get normalized noise component: + noise = pure_noise[:song.shape[0]] + noise /= noise[segment].std() - # Prepare noise-bound threshold: - threshold = np.percentile(noise, thresh_percent, axis=0) - else: - # Reuse threshold from previous noise run: - threshold = np.load(save_name + '_noise.npz')['thresh'] + # Define kernel-specific threshold values based on pure-noise response SD: + ref_conv = convolve_kernels(noise, config['kernels'], config['k_specs']) + thresh_abs = ref_conv[segment, :].std(axis=0, keepdims=True) * thresh_rel[:, None] # Prepare measure storage: - shape = (scales.size, song.shape[1]) - # measure_conv = np.zeros(shape, dtype=float) + shape = (scales.size, kern_specs.shape[0], thresh_rel.size) measure_feat = np.zeros(shape, dtype=float) + if save_snippets: + # Prepare snippet storage: + snip_inv = np.zeros((song.size, example_scales.size), dtype=float) + shape = (song.size, kern_specs.shape[0], example_scales.size, thresh_rel.size) + snip_conv = np.zeros(shape[:-1], dtype=float) + snip_bi = np.zeros(shape, dtype=float) + snip_feat = np.zeros(shape, dtype=float) # Execute piecewise: for i, scale in enumerate(scales): print('Simulating scale', scale) # Rescale song component: - scaled_conv = song * scale + scaled_song = song * scale if add_noise: # Add noise: - scaled_conv += noise + scaled_song += noise # Process mixture: - scaled_bi = (scaled_conv > threshold).astype(float) - scaled_feat = sosfilter(scaled_bi, rate, config['feat_fcut'], 'lp', - padtype='fixed', padlen=config['padlen']) + scaled_conv = convolve_kernels(scaled_song, config['kernels'], config['k_specs']) + + # Log threshold-independent snippet data: + if save_snippets and scale in example_scales: + save_ind = np.nonzero(example_scales == scale)[0][0] + snip_inv[:, save_ind] = scaled_song + snip_conv[:, :, save_ind] = scaled_conv - # Get intensity measure per stage: - # measure_conv[i] = scaled_conv[segment, :].std(axis=0) - measure_feat[i] = scaled_feat[segment, :].mean(axis=0) + # Execute piecewise again: + for j, thresholds in enumerate(thresh_abs): + + # Process mixture further: + scaled_bi = (scaled_conv > thresholds).astype(float) + scaled_feat = sosfilter(scaled_bi, rate, config['feat_fcut'], 'lp', + padtype='fixed', padlen=config['padlen']) + + # Log threshold-dependent snippet data: + if save_snippets and scale in example_scales: + snip_bi[:, :, save_ind, j] = scaled_bi + snip_feat[:, :, save_ind, j] = scaled_feat + + # Log intensity measure: + measure_feat[i, :, j] = scaled_feat[segment, :].mean(axis=0) + + # Overview plot: + if plot_results: + fig, axes = plt.subplots(thresh_rel.size, kern_specs.shape[0], + figsize=(16, 9), layout='constrained', + sharex=True, sharey=True, squeeze=True) + axes[0, 0].set_xscale('symlog', linthresh=scales[scales>0].min(), + linscale=0.25) + axes[0, 0].set_ylim(0, 1) + for i, thresh in enumerate(thresh_rel): + for j, kernel in enumerate(kern_specs): + ax = axes[i, j] + ax.plot(scales, measure_feat[:, j, i], 'k') + if i == 0: + ax.set_title(f'Kernel {kernel}') + if j == 0: + ax.set_ylabel(f'{thresh} * SD') + plt.show() # Save analysis results: if save_path is not None: data = dict( scales=scales, - # measure_conv=measure_conv, + example_scales=example_scales, measure_feat=measure_feat, - thresh=threshold, - thresh_perc=thresh_percent, + thresh_rel=thresh_rel, + thresh_abs=thresh_abs, ) + if save_snippets: + data.update(dict( + snip_inv=snip_inv, + snip_conv=snip_conv, + snip_bi=snip_bi, + snip_feat=snip_feat, + )) if add_noise: save_name += '_noise' + else: + save_name += '_pure' save_data(save_name, data, config, overwrite=True) + print('Done.') embed() diff --git a/python/save_inv_data_thresh-lp_subset.py b/python/save_inv_data_thresh-lp_subset.py deleted file mode 100644 index f03c91c..0000000 --- a/python/save_inv_data_thresh-lp_subset.py +++ /dev/null @@ -1,138 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt -from thunderhopper.modeltools import load_data, save_data -from thunderhopper.filetools import search_files, crop_paths -from thunderhopper.filters import sosfilter -from thunderhopper.filtertools import find_kern_specs, pdf_proportion -from IPython import embed - -# GENERAL SETTINGS: -target = ['Omocestus_rufipes', '*'][0] -data_paths = search_files(target, dir='../data/processed/') -save_path = '../data/inv/thresh_lp/' - -# ANALYSIS SETTINGS: -add_noise = False -save_snippets = True -example_scales = np.array([0, 1, 10, 50]) -scales = np.geomspace(0.01, 1000, 100) -scales = np.unique(np.concatenate((scales, example_scales))) -thresh_percent = np.array([0.6, 0.75, 0.999]) -thresholds = pdf_proportion(thresh_percent, sd=1, mu=0) -plot_results = False -kernels = np.array([ - [1, 0.008], - [2, 0.004], - [3, 0.002], -]) - -# EXECUTION: -for data_path, name in zip(data_paths, crop_paths(data_paths)): - print(f'Processing {name}') - save_name = save_path + name + '_subset' - - # Get pure-song kernel responses: - data, config = load_data(data_path, files='conv') - conv, rate = data['conv'], data['conv_rate'] - - # Get song segment to be analyzed: - time = np.arange(conv.shape[0]) / rate - start, end = data['songs_0'].ravel() - segment = (time >= start) & (time <= end) - - # Reduce to kernel subset: - kern_inds = find_kern_specs(config['k_specs'], kerns=kernels) - config['kernels'] = config['kernels'][:, kern_inds] - config['k_specs'] = config['k_specs'][kern_inds] - config['k_props'] = [config['k_props'][i] for i in kern_inds] - conv = conv[:, kern_inds] - - # Normalize kernel responses: - conv /= conv[segment, :].std(axis=0) - - if add_noise: - # Get normalized noise: - rng = np.random.default_rng() - noise = rng.normal(size=(conv.shape[0], 1)) - noise /= noise[segment].std() - - if save_snippets: - # Prepare snippet storage: - shape = conv.shape + (example_scales.size, thresh_percent.size) - snip_conv = np.zeros(shape, dtype=float) - snip_bi = np.zeros(shape, dtype=float) - snip_feat = np.zeros(shape, dtype=float) - - # Prepare measure storage: - shape = (scales.size, conv.shape[1], thresh_percent.size) - # measure_conv = np.zeros(shape, dtype=float) - measure_feat = np.zeros(shape, dtype=float) - - # Execute piecewise analysis: - for i, thresh in enumerate(thresholds): - print('\nSimulating threshold ', thresh_percent[i]) - - for j, scale in enumerate(scales): - print('Simulating scale ', scale) - - # Rescale conv component: - scaled_conv = conv * scale - if add_noise: - # Add noise: - scaled_conv += noise - - # Process mixture: - scaled_bi = (scaled_conv > thresh).astype(float) - scaled_feat = sosfilter(scaled_bi, rate, config['feat_fcut'], 'lp', - padtype='fixed', padlen=config['padlen']) - - # Log snippet data: - if save_snippets and scale in example_scales: - scale_ind = np.nonzero(example_scales == scale)[0][0] - snip_conv[:, :, scale_ind, i] = scaled_conv - snip_bi[:, :, scale_ind, i] = scaled_bi - snip_feat[:, :, scale_ind, i] = scaled_feat - - # Get intensity measure per stage: - measure_feat[j, :, i] = scaled_feat[segment, :].mean(axis=0) - # measure_conv[j, :, i] = scaled_conv[segment, :].std(axis=0) - - if plot_results: - fig, axes = plt.subplots(thresh_percent.size, kernels.shape[0], - figsize=(16, 9), layout='constrained', - sharex=True, sharey=True, squeeze=True) - axes[0, 0].set_xscale('symlog', linthresh=scales[scales>0].min(), - linscale=0.25) - axes[0, 0].set_ylim(0, 1) - - for i, thresh in enumerate(thresh_percent): - for j, kernel in enumerate(kernels): - ax = axes[i, j] - ax.plot(scales, measure_feat[:, j, i], 'k') - if i == 0: - ax.set_title(f'Kernel {kernel}') - if j == 0: - ax.set_ylabel(f'{100 * thresh}%') - plt.show() - - # Save analysis results: - if save_path is not None: - data = dict( - scales=scales, - example_scales=example_scales, - # measure_conv=measure_conv, - measure_feat=measure_feat, - thresh_perc=thresh_percent, - threshs=thresholds, - ) - if save_snippets: - data.update(dict( - snip_conv=snip_conv, - snip_bi=snip_bi, - snip_feat=snip_feat, - )) - if add_noise: - save_name += '_noise' - save_data(save_name, data, config, overwrite=True) -print('Done.') -embed()