diff --git a/figures/fig_invariance_log_hp.pdf b/figures/fig_invariance_log_hp.pdf new file mode 100644 index 0000000..5bf2ab9 Binary files /dev/null and b/figures/fig_invariance_log_hp.pdf differ diff --git a/main.aux b/main.aux index 34fb672..68937a1 100644 --- a/main.aux +++ b/main.aux @@ -248,15 +248,17 @@ \newlabel{eq:toy_log}{{12}{11}{}{}{}} \newlabel{eq:toy_highpass}{{13}{11}{}{}{}} \newlabel{eq:toy_snr}{{14}{11}{}{}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Thresholding nonlinearity \& temporal averaging}{11}{}\protected@file@percent } -\newlabel{eq:pdf_split}{{15}{12}{}{}{}} -\newlabel{eq:feat_avg}{{16}{12}{}{}{}} -\newlabel{eq:feat_prop}{{17}{12}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces \textbf {Intensity invariance by logarithmic compression and adaptation.} \textbf {a}:~Synthetic envelopes resulting from the mixture of song component $s(t)$ with scale $\alpha $ and noise component $\eta (t)$ with fixed scale. \textbf {b}:~Corresponding logarithmically scaled envelopes. \textbf {c}:~Corresponding intensity-adapted envelopes. \textbf {d}:~Absolute SNRs of each representation relative to the representation without song component ($\alpha =0$). \textbf {e}:~Same SNRs as in \textbf {d} but normalized to the maximum SNR for each representation. \textbf {f}:~Relative amplification of normalized SNRs relative to the normalized SNRs of the initial envelope. }}{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 } +\newlabel{eq:pdf_split}{{15}{13}{}{}{}} +\newlabel{eq:feat_avg}{{16}{13}{}{}{}} +\newlabel{eq:feat_prop}{{17}{13}{}{}{}} \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}{13}{}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{13}{}\protected@file@percent } -\abx@aux@page{73}{13} +\@writefile{toc}{\contentsline {section}{\numberline {4}Discriminating species-specific song\\patterns in feature space}{14}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{14}{}\protected@file@percent } +\abx@aux@page{73}{14} \gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }} \abx@aux@read@bbl@mdfivesum{1380DC8C93D2855FDB132CC5A40AD52F} -\gdef \@abspage@last{14} +\gdef \@abspage@last{15} diff --git a/main.blg b/main.blg index b32bb78..c795d8b 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 - === Fr Feb 27, 2026, 16:08:08 -[42] Biber.pm:419> INFO - Reading 'main.bcf' -[70] Biber.pm:979> INFO - Found 55 citekeys in bib section 0 -[75] Biber.pm:4419> INFO - Processing section 0 -[80] Biber.pm:4610> INFO - Looking for bibtex file 'cite.bib' for section 0 -[81] bibtex.pm:1713> INFO - LaTeX decoding ... -[110] bibtex.pm:1519> INFO - Found BibTeX data source 'cite.bib' -[276] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'normalization = NFD' with 'normalization = prenormalized' -[276] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'variable = shifted' with 'variable = non-ignorable' -[276] Biber.pm:4239> INFO - Sorting list 'nyt/global//global/global' of type 'entry' with template 'nyt' and locale 'en-US' -[276] Biber.pm:4245> INFO - No sort tailoring available for locale 'en-US' -[297] bbl.pm:660> INFO - Writing 'main.bbl' with encoding 'UTF-8' -[307] bbl.pm:763> INFO - Output to main.bbl -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 10, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 21, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 38, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 49, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 58, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 73, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 82, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 91, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 100, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 109, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 118, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 127, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 136, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 157, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 178, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 187, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 196, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 207, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 218, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 229, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 240, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 249, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 258, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 269, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 278, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 289, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 300, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 309, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 328, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 337, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 400, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 419, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 428, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 437, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 456, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 491, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 526, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 535, warning: 6 characters of junk seen at toplevel -[307] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 556, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 565, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 576, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 587, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 619, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 648, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 658, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 667, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 688, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 709, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 720, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 729, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 749, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 766, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 775, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 800, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_Q3WE/347c261ec4135a5723bef5c751f5078f_25304.utf8, line 817, warning: 6 characters of junk seen at toplevel -[308] Biber.pm:133> INFO - WARNINGS: 55 +[38] biber:340> INFO - === Di Mär 3, 2026, 16:21:37 +[45] Biber.pm:419> INFO - Reading 'main.bcf' +[75] Biber.pm:979> INFO - Found 55 citekeys in bib section 0 +[82] Biber.pm:4419> INFO - Processing section 0 +[87] Biber.pm:4610> INFO - Looking for bibtex file 'cite.bib' for section 0 +[88] bibtex.pm:1713> INFO - LaTeX decoding ... +[120] bibtex.pm:1519> INFO - Found BibTeX data source 'cite.bib' +[303] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'normalization = NFD' with 'normalization = prenormalized' +[303] UCollate.pm:68> INFO - Overriding locale 'en-US' defaults 'variable = shifted' with 'variable = non-ignorable' +[303] Biber.pm:4239> INFO - Sorting list 'nyt/global//global/global' of type 'entry' with template 'nyt' and locale 'en-US' +[303] Biber.pm:4245> INFO - No sort tailoring available for locale 'en-US' +[327] bbl.pm:660> INFO - Writing 'main.bbl' with encoding 'UTF-8' +[337] bbl.pm:763> INFO - Output to main.bbl +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 10, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 21, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 38, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 49, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 58, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 73, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 82, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 91, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 100, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 109, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 118, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 127, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 136, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 157, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 178, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 187, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 196, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 207, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 218, warning: 6 characters of junk seen at toplevel +[337] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 229, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 240, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 249, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 258, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 269, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 278, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 289, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 300, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 309, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 328, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 337, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 400, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 419, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 428, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 437, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 456, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 491, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 526, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 535, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 556, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 565, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 576, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 587, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 619, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 648, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 658, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 667, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 688, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 709, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 720, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 729, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 749, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 766, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 775, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 800, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:131> WARN - BibTeX subsystem: /tmp/biber_tmp_rB4F/347c261ec4135a5723bef5c751f5078f_81147.utf8, line 817, warning: 6 characters of junk seen at toplevel +[338] Biber.pm:133> INFO - WARNINGS: 55 diff --git a/main.fdb_latexmk b/main.fdb_latexmk index 6414929..b88dca6 100644 --- a/main.fdb_latexmk +++ b/main.fdb_latexmk @@ -1,14 +1,14 @@ # Fdb version 4 -["biber main"] 1772204888.14684 "main.bcf" "main.bbl" "main" 1772204926.70326 0 +["biber main"] 1772551296.80409 "main.bcf" "main.bbl" "main" 1772551360.62635 0 "cite.bib" 1770904753.08918 27483 4290db0c91f7b5055e25472ef913f6b4 "" - "main.bcf" 1772204926.65235 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" + "main.bcf" 1772551360.57805 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" (generated) "main.bbl" "main.blg" (rewritten before read) -["pdflatex"] 1772204925.84696 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1772204926.70347 0 +["pdflatex"] 1772551359.77359 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1772551360.62655 0 "/etc/texmf/web2c/texmf.cnf" 1761560044.43676 475 c0e671620eb5563b2130f56340a5fde8 "" - "/home/hartling/phd/paper/paper_2025/main.tex" 1772204925.75836 43610 64fc0d2095542fc0b26831f03534a80f "" + "/home/hartling/phd/paper/paper_2025/main.tex" 1772551358.81608 44727 89099053313a739a124eef0ebf096cbe "" "/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 "" @@ -153,11 +153,12 @@ "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1761648508 8213325 7fd20752ab46ff9aa583e4973d7433df "" "figures/fig_auditory_pathway.pdf" 1771593904.14638 1153923 3df8539421fd21dc866cc8d320bd9b1d "" "figures/fig_feat_stages.pdf" 1771841347.81651 8600157 89f9276167cc096f9adce052152edd70 "" + "figures/fig_invariance_log_hp.pdf" 1772550242.81975 596132 199b6299bddb7a18add3f3c606c26c68 "" "figures/fig_pre_stages.pdf" 1771841345.77353 440442 263f9bd4a3bca8e0653ac0a4c4a8da2c "" - "main.aux" 1772204926.64635 11791 7489be3296a12717c20b24d84cde4ae1 "pdflatex" - "main.bbl" 1772204888.74085 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" - "main.run.xml" 1772204926.65235 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" - "main.tex" 1772204925.75836 43610 64fc0d2095542fc0b26831f03534a80f "" + "main.aux" 1772551360.57305 12621 fd60ae2568ab59c6c47a0013f596c4ce "pdflatex" + "main.bbl" 1772551297.4309 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" + "main.run.xml" 1772551360.57905 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" + "main.tex" 1772551358.81608 44727 89099053313a739a124eef0ebf096cbe "" (generated) "main.aux" "main.bcf" diff --git a/main.fls b/main.fls index 215ee14..eb08eb9 100644 --- a/main.fls +++ b/main.fls @@ -288,6 +288,11 @@ INPUT ./figures/fig_feat_stages.pdf INPUT ./figures/fig_feat_stages.pdf INPUT ./figures/fig_feat_stages.pdf INPUT ./figures/fig_feat_stages.pdf +INPUT ./figures/fig_invariance_log_hp.pdf +INPUT ./figures/fig_invariance_log_hp.pdf +INPUT ./figures/fig_invariance_log_hp.pdf +INPUT ./figures/fig_invariance_log_hp.pdf +INPUT ./figures/fig_invariance_log_hp.pdf INPUT main.aux INPUT main.run.xml OUTPUT main.run.xml diff --git a/main.log b/main.log index c8291a4..e23bb36 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) 27 FEB 2026 16:08 +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2025.10.28) 3 MAR 2026 16:22 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -762,7 +762,13 @@ File: figures/fig_feat_stages.pdf Graphic file (type pdf) Package pdftex.def Info: figures/fig_feat_stages.pdf used on input line 535. (pdftex.def) Requested size: 483.69687pt x 181.38585pt. -[9] [10 <./figures/fig_feat_stages.pdf>] [11] [12] [13] [14] (./main.aux) +[9] [10 <./figures/fig_feat_stages.pdf>] + +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 625. +(pdftex.def) Requested size: 483.69687pt x 241.84782pt. + [11] [12 <./figures/fig_invariance_log_hp.pdf>] [13] [14] [15] (./main.aux) *********** LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-01-22> @@ -772,18 +778,18 @@ Package logreq Info: Writing requests to 'main.run.xml'. ) Here is how much of TeX's memory you used: - 20717 strings out of 474222 - 446212 string characters out of 5748732 + 20725 strings out of 474222 + 446531 string characters out of 5748732 1937975 words of memory out of 5000000 - 42707 multiletter control sequences out of 15000+600000 + 42715 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,955b,1732s stack positions out of 10000i,1000n,20000p,200000b,200000s -Output written on main.pdf (14 pages, 10363062 bytes). +Output written on main.pdf (15 pages, 10953973 bytes). PDF statistics: - 1226 PDF objects out of 1440 (max. 8388607) - 745 compressed objects within 8 object streams + 1299 PDF objects out of 1440 (max. 8388607) + 764 compressed objects within 8 object streams 0 named destinations out of 1000 (max. 500000) - 28 words of extra memory for PDF output out of 10000 (max. 10000000) + 33 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/main.pdf b/main.pdf index 3f449ea..e61acfc 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.synctex.gz b/main.synctex.gz index df28b2d..89e5e59 100644 Binary files a/main.synctex.gz and b/main.synctex.gz differ diff --git a/main.tex b/main.tex index 076bbbd..3647a2c 100644 --- a/main.tex +++ b/main.tex @@ -620,6 +620,27 @@ to recover songs that have already sunken below the noise floor, which emphasizes the importance of a sufficiently high SNR at the intial reception of the signal for reliable song recognition. +\begin{figure}[!ht] + \centering + \includegraphics[width=\textwidth]{figures/fig_invariance_log_hp.pdf} + \caption{\textbf{Intensity invariance by logarithmic compression and + adaptation.} + \textbf{a}:~Synthetic envelopes resulting from the + mixture of song component $\soc(t)$ with scale $\sca$ and + noise component $\noc(t)$ with fixed scale. + \textbf{b}:~Corresponding logarithmically scaled envelopes. + \textbf{c}:~Corresponding intensity-adapted envelopes. + \textbf{d}:~Absolute SNRs of each representation relative + to the representation without song component ($\sca=0$). + \textbf{e}:~Same SNRs as in \textbf{d} but normalized to + the maximum SNR for each representation. + \textbf{f}:~Relative amplification of normalized SNRs + relative to the normalized SNRs of the initial envelope. + } + \label{fig:inv_log-hp} +\end{figure} +\FloatBarrier + \subsection{Thresholding nonlinearity \& temporal averaging} The second key mechanism for the emergence of intensity invariance along the diff --git a/python/fig_invariance_log-hp.py b/python/fig_invariance_log-hp.py index ed42101..a972f66 100644 --- a/python/fig_invariance_log-hp.py +++ b/python/fig_invariance_log-hp.py @@ -1,133 +1,227 @@ +import plotstyle_plt +import glob import numpy as np import matplotlib.pyplot as plt from itertools import product +from thunderhopper.modeltools import load_data +from color_functions import load_colors +from plot_functions import hide_axis, letter_subplots, ylimits, ylabel, super_xlabel, plot_line +from IPython import embed -def prepare_fig(nrows, ncols, width=8, height=None, rheight=2, - left=0.01, right=0.95, bottom=0.01, top=0.95, - wspace=0.4, hspace=0.4): - if height is None: - height = rheight * nrows - fig = plt.figure(figsize=(width, height)) - grid = fig.add_gridspec(nrows=nrows, ncols=ncols, wspace=wspace, hspace=hspace, - left=left, right=right, top=top, bottom=bottom) - axes = np.zeros((nrows, ncols), dtype=object) - for i, j in product(range(nrows), range(ncols)): - axes[i, j] = fig.add_subplot(grid[i, j]) - axes[i, j].set_facecolor('none') - return fig, axes +def strip_zeros(num, right_digits=5): + if isinstance(num, int): + return num + num = f'{num:.{right_digits}f}' + left, right = num.split('.') + right = right.rstrip('0') + if right: + return f'{left}.{right}' + return left -def xlimits(ax, time, minval=None, maxval=None, pad=0.05): - limits = [minval, maxval] - if minval is None: - limits[0] = time[0] - if maxval is None: - limits[1] = time[-1] - if pad is not None and minval is None: - limits[0] -= (limits[1] - limits[0]) * pad - if pad is not None and maxval is None: - limits[1] += (limits[1] - limits[0]) * pad - return ax.set_xlim(limits) - -def ylimits(ax, signal, minval=None, maxval=None, pad=0.05): - limits = [minval, maxval] - if minval is None: - limits[0] = signal.min() - if maxval is None: - limits[1] = signal.max() - if pad is not None and minval is None: - limits[0] -= (limits[1] - limits[0]) * pad - if pad is not None and maxval is None: - limits[1] += (limits[1] - limits[0]) * pad - return ax.set_ylim(limits) - -def ylabel(ax, label, x=-0.23, fontsize=20): - ax.set_ylabel(label, fontsize=fontsize, rotation=0, ha='left', va='center') - ax.yaxis.set_label_coords(x, 0.5) +def plot_snippets(axes, time, snippets, label, scales=None, + ymin=None, ymax=None, **kwargs): + ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05) + ylabel(axes[0], label, x=-0.7, rotation=0, ha='left', va='center') + for i, (ax, snippet) in enumerate(zip(axes, snippets.T)): + plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs) + if scales is not None: + ax.set_title(f'$\\alpha={strip_zeros(scales[i])}$') return None -def super_xlabel(label, fig, high_ax, low_ax, y=0.005, **kwargs): - x = (low_ax.get_position().x0 + high_ax.get_position().x1) / 2 - fig.supxlabel(label, x=x, y=y, **kwargs) - return None +# GENERAL SETTINGS: +target = 'Omocestus_rufipes' +data_paths = glob.glob(f'../data/inv/log_hp/{target}*.npz') +stages = ['env', 'log', 'inv'] +files = stages + ['scales', 'plot_scales', 'snr_env', 'snr_log', 'snr_inv'] +save_path = '../figures/fig_invariance_log_hp.pdf' -def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs): - y = (low_ax.get_position().y0 + high_ax.get_position().y1) / 2 - fig.supylabel(label, x=x, y=y, **kwargs) - return None +# PLOT SETTINGS: +fig_kwargs = dict( + figsize=(32/2.54, 16/2.54), +) +grid1_kwargs = dict( + nrows=len(stages), + ncols=None, + wspace=0.05, + hspace=0.3, + left=0.1, + right=0.985, + bottom=0.17, + top=0.9 +) +grid2_kwargs = dict( + nrows=1, + ncols=3, + wspace=0.35, + hspace=0, + left=0.1, + right=0.985, + bottom=0.18, + top=0.95 +) +colors = load_colors('../data/stage_colors.npz') +lw_snippets = 0.25 +lw_analysis = 3 +ylabels = dict( + env=r'$x_{\text{env}}$', + log=r'$x_{\text{dB}}$', + inv=r'$x_{\text{adapt}}$', + abs='abs. SNR',#'abs. ' + r'$\text{SNR}$', + norm='norm. SNR',#'norm. ' + r'$\text{SNR}$', + gain='rel. SNR gain' +) +xloc = dict( + abs=5, +) +yloc = dict( + env=100, + log=10, + inv=5, + abs=50, +) +letter_kwargs = dict( + x=0.03, + y=0.99, + ha='left', + va='top' +) +fit_kwargs = dict( + c='darkred', + ls='--', + zorder=1.9 +) +fit_lw = dict( + abs=6, + norm=3, + gain=3 +) +text_kwargs = dict( + abs=dict(s='$\\alpha^2+1$', fontsize=16, c=fit_kwargs['c'], + x=0.85, y=0.9, ha='right', va='center'), + norm=dict(s='$\\alpha^2+1$', fontsize=16, c=fit_kwargs['c'], + x=0.85, y=0.9, ha='right', va='center'), + gain=dict(s='$\\frac{1}{\\alpha}$', fontsize=24, c=fit_kwargs['c'], + x=0.75, y=0.8, ha='left', va='center') +) +calculated_floor = False +floor_kwargs = dict( + xmin=0, + color=3 * (0.85,), + zorder=0, + lw=0 +) -def hide_axis(ax, side='bottom'): - ax.spines[side].set_visible(False) - params = {side: False, 'label' + side: False} - ax.tick_params(axis='x' if side in ['top', 'bottom'] else 'y', - which='both', **params) - return None +# EXECUTION: +for data_path in data_paths: + print(f'Processing {data_path}') -def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None, - xpad=None, ypad=0.05, yloc=None, **kwargs): - handles = ax.plot(time, signal, **kwargs) - xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad) - ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad) - ax.yaxis.set_major_locator(plt.MultipleLocator(yloc)) - return handles + # Load invariance data: + data, config = load_data(data_path, files) + t_full = np.arange(data['env'].shape[0]) / config['env_rate'] + nonzero_scales = data['scales'][data['scales'] > 0] + floor_kwargs['xmax'] = data['floor_scale'] if calculated_floor else 1 -def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs): - if xmin is None: - xmin = time[0] - if xmax is None: - xmax = time[-1] - lower, upper, handles = 0, 1, [] - for i in range(binary.shape[1]): - h = ax.fill_between(time, lower, upper, where=binary[:, i], **kwargs) - handles.append(h) - if i < binary.shape[1] - 1: - lower += offset + 1 - upper += offset + 1 - xlimits(ax, time, minval=xmin, maxval=xmax) - ax.set_ylim(0, upper) - hide_axis(ax, 'bottom') - hide_axis(ax, 'left') - return handles + # Prepare overall graph: + fig = plt.figure(**fig_kwargs) + super_grid = fig.add_gridspec(2, 1, wspace=0, hspace=1, + left=0, right=1, bottom=0, top=1) -def indicate_zoom(fig, high_ax, low_ax, zoom_abs, **kwargs): - y0 = low_ax.get_position().y0 - y1 = high_ax.get_position().y1 - transform = low_ax.transData + fig.transFigure.inverted() - x0 = transform.transform((zoom_abs[0], 0))[0] - x1 = transform.transform((zoom_abs[1], 0))[0] - rect = plt.Rectangle((x0, y0), x1 - x0, y1 - y0, - transform=fig.transFigure, **kwargs) - fig.add_artist(rect) - return None + # Prepare snippet axes: + subfig1 = fig.add_subfigure(super_grid[0, :]) + grid1_kwargs['ncols'] = data['plot_scales'].size + grid1 = subfig1.add_gridspec(**grid1_kwargs) + axes = np.zeros((grid1.nrows, grid1.ncols), dtype=object) + for i, j in product(range(grid1.nrows), range(grid1.ncols)): + axes[i, j] = subfig1.add_subplot(grid1[i, j]) + [hide_axis(ax, 'bottom') for ax in axes[:-1, :].flatten()] + [hide_axis(ax, 'left') for ax in axes[:, 1:].flatten()] + super_xlabel('time [s]', subfig1, axes[-1, 0], axes[-1, -1], y=0) + letter_subplots(axes[:, 0], labels='abc', **letter_kwargs) -def assign_colors(handles, types, colors): - for handle, type_id in zip(handles, types): - handle.set_color(colors[str(int(type_id))]) - return None + # Prepare analysis axes: + subfig2 = fig.add_subfigure(super_grid[1, :]) + grid2 = subfig2.add_gridspec(**grid2_kwargs) + symlog_kwargs = dict(linthresh=nonzero_scales.min(), linscale=0.2) -def reorder_traces(handles, signal, zlow=2, zhigh=2.5): - inds = np.argsort(signal.std(axis=0)) - zorders = np.linspace(zlow, zhigh, len(inds))[::-1] - for ind, z in zip(inds, zorders): - handles[ind].set_zorder(z) - return None + ax_abs_snr = subfig2.add_subplot(grid2[:, 0]) + ax_abs_snr.set_ylabel(ylabels['abs']) -def choose_kernels(kern_specs, features, kern_types, per_type=2, thresh=0.01): - mean_feat = features.mean(axis=0) - feat_diff = np.abs(mean_feat[:, None] - mean_feat[None, :]) - feat_diff[features.max(axis=0) < thresh, :] = np.nan - feat_diff = np.nanmean(feat_diff, axis=0) + ax_norm_snr = subfig2.add_subplot(grid2[:, 1]) + ax_norm_snr.set_ylabel(ylabels['norm']) + ax_norm_snr.set_xscale('symlog', **symlog_kwargs) + ax_norm_snr.set_yscale('log') - ranking = np.argsort(feat_diff) - kern_inds = [] - for type_id in kern_types: - type_inds = np.nonzero(kern_specs[:, 0] == type_id)[0] - rank_inds = np.nonzero(np.isin(ranking, type_inds))[0][-per_type:] - kern_inds.extend(ranking[rank_inds]) - return np.array(kern_inds) + ax_gain = subfig2.add_subplot(grid2[:, 2]) + ax_gain.set_ylabel(ylabels['gain']) + ax_gain.set_xscale('symlog', **symlog_kwargs) + ax_gain.set_yscale('log') + super_xlabel('song scale $\\alpha$', subfig2, ax_abs_snr, ax_gain) + letter_subplots([ax_abs_snr, ax_norm_snr, ax_gain], labels='def', **letter_kwargs) -def letter_subplots(axes, labels='abcd', x=0.02, y=1, ha='left', va='bottom', - fontsize=16, fontweight='bold', **kwargs): - for ax, label in zip(axes, labels): - ax.text(x, y, label, transform=ax.transAxes, ha=ha, va=va, - fontsize=fontsize, fontweight=fontweight, **kwargs) - return None \ No newline at end of file + # Plot envelope snippets: + plot_snippets(axes[0, :], t_full, data['env'], ylabels['env'], ymin=0, + scales=data['plot_scales'], c=colors['env'], lw=lw_snippets) + axes[0, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['env'])) + + # Plot logarithmic snippets: + plot_snippets(axes[1, :], t_full, data['log'], ylabels['log'], ymax=0, + c=colors['log'], lw=lw_snippets) + axes[1, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['log'])) + + # Plot invariant snippets: + plot_snippets(axes[2, :], t_full, data['inv'], ylabels['inv'], + c=colors['inv'], lw=lw_snippets) + axes[2, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['inv'])) + + # Plot in-representation SNRs (absolute): + ax_abs_snr.plot(data['scales'], data['snr_env'], c=colors['env'], lw=lw_analysis) + ax_abs_snr.plot(data['scales'], data['snr_log'], c=colors['log'], lw=lw_analysis) + ax_abs_snr.plot(data['scales'], data['snr_inv'], c=colors['inv'], lw=lw_analysis) + ax_abs_snr.axvspan(**floor_kwargs) + ax_abs_snr.xaxis.set_major_locator(plt.MultipleLocator(xloc['abs'])) + ax_abs_snr.yaxis.set_major_locator(plt.MultipleLocator(yloc['abs'])) + ax_abs_snr.set_ylim(0, data['snr_env'].max()) + + # Plot envelope SNR fit: + ax_abs_snr.plot(data['scales'], data['scales'] ** 2 + 1, + lw=fit_lw['abs'], **fit_kwargs) + ax_abs_snr.text(transform=ax_abs_snr.transAxes, **text_kwargs['abs']) + + # Get normalized SNRs: + norm_snr_env = data['snr_env'] / data['snr_env'].max() + norm_snr_log = data['snr_log'] / data['snr_log'].max() + norm_snr_inv = data['snr_inv'] / data['snr_inv'].max() + + # Plot in-representation SNRs (normalized): + ax_norm_snr.plot(data['scales'], norm_snr_env, c=colors['env'], lw=lw_analysis) + ax_norm_snr.plot(data['scales'], norm_snr_log, c=colors['log'], lw=lw_analysis) + ax_norm_snr.plot(data['scales'], norm_snr_inv, c=colors['inv'], lw=lw_analysis) + ax_norm_snr.axvspan(**floor_kwargs) + ax_norm_snr.set_ylim(norm_snr_env.min(), 1) + + # # Plot envelope SNR fit: + # ax_norm_snr.plot(nonzero_scales, nonzero_scales / nonzero_scales.max(), + # lw=fit_lw['norm'], **fit_kwargs) + # ax_norm_snr.text(transform=ax_norm_snr.transAxes, **text_kwargs['norm']) + + # Get relative SNR gain: + gain_log = norm_snr_log / norm_snr_env + gain_inv = norm_snr_inv / norm_snr_env + + # Plot across-representation gain: + ax_gain.plot(data['scales'], gain_log, c=colors['log'], lw=lw_analysis) + ax_gain.plot(data['scales'], gain_inv, c=colors['inv'], lw=lw_analysis) + ax_gain.axvspan(**floor_kwargs) + ax_gain.set_ylim(1, 10) + + # Plot amplification fit: + ax_gain.plot(nonzero_scales, nonzero_scales.max() / nonzero_scales, + lw=fit_lw['gain'], **fit_kwargs) + ax_gain.text(transform=ax_gain.transAxes, **text_kwargs['gain']) + + if save_path is not None: + fig.savefig(save_path) + plt.show() + +print('Done.') +embed() diff --git a/python/fig_pathway_stages.py b/python/fig_pathway_stages.py index 4eb877c..fc6a5ba 100644 --- a/python/fig_pathway_stages.py +++ b/python/fig_pathway_stages.py @@ -9,142 +9,11 @@ from plot_functions import prepare_fig, hide_axis, letter_subplots,\ indicate_zoom, assign_colors, reorder_traces from IPython import embed -# def prepare_fig(nrows, ncols, width=8, height=None, rheight=2, -# left=0.01, right=0.95, bottom=0.01, top=0.95, -# wspace=0.4, hspace=0.4): -# if height is None: -# height = rheight * nrows -# fig = plt.figure(figsize=(width, height)) -# grid = fig.add_gridspec(nrows=nrows, ncols=ncols, wspace=wspace, hspace=hspace, -# left=left, right=right, top=top, bottom=bottom) -# axes = np.zeros((nrows, ncols), dtype=object) -# for i, j in product(range(nrows), range(ncols)): -# axes[i, j] = fig.add_subplot(grid[i, j]) -# axes[i, j].set_facecolor('none') -# return fig, axes - -# def xlimits(ax, time, minval=None, maxval=None, pad=0.05): -# limits = [minval, maxval] -# if minval is None: -# limits[0] = time[0] -# if maxval is None: -# limits[1] = time[-1] -# if pad is not None and minval is None: -# limits[0] -= (limits[1] - limits[0]) * pad -# if pad is not None and maxval is None: -# limits[1] += (limits[1] - limits[0]) * pad -# return ax.set_xlim(limits) - -# def ylimits(ax, signal, minval=None, maxval=None, pad=0.05): -# limits = [minval, maxval] -# if minval is None: -# limits[0] = signal.min() -# if maxval is None: -# limits[1] = signal.max() -# if pad is not None and minval is None: -# limits[0] -= (limits[1] - limits[0]) * pad -# if pad is not None and maxval is None: -# limits[1] += (limits[1] - limits[0]) * pad -# return ax.set_ylim(limits) - -# def ylabel(ax, label, x=-0.23, fontsize=20): -# ax.set_ylabel(label, fontsize=fontsize, rotation=0, ha='left', va='center') -# ax.yaxis.set_label_coords(x, 0.5) -# return None - -# def super_xlabel(label, fig, high_ax, low_ax, y=0.005, **kwargs): -# x = (low_ax.get_position().x0 + high_ax.get_position().x1) / 2 -# fig.supxlabel(label, x=x, y=y, **kwargs) -# return None - -# def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs): -# y = (low_ax.get_position().y0 + high_ax.get_position().y1) / 2 -# fig.supylabel(label, x=x, y=y, **kwargs) -# return None - -# def hide_axis(ax, side='bottom'): -# ax.spines[side].set_visible(False) -# params = {side: False, 'label' + side: False} -# ax.tick_params(axis='x' if side in ['top', 'bottom'] else 'y', -# which='both', **params) -# return None - -# def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None, -# xpad=None, ypad=0.05, yloc=None, **kwargs): -# handles = ax.plot(time, signal, **kwargs) -# xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad) -# ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad) -# ax.yaxis.set_major_locator(plt.MultipleLocator(yloc)) -# return handles - -# def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs): -# if xmin is None: -# xmin = time[0] -# if xmax is None: -# xmax = time[-1] -# lower, upper, handles = 0, 1, [] -# for i in range(binary.shape[1]): -# h = ax.fill_between(time, lower, upper, where=binary[:, i], **kwargs) -# handles.append(h) -# if i < binary.shape[1] - 1: -# lower += offset + 1 -# upper += offset + 1 -# xlimits(ax, time, minval=xmin, maxval=xmax) -# ax.set_ylim(0, upper) -# hide_axis(ax, 'bottom') -# hide_axis(ax, 'left') -# return handles - -# def indicate_zoom(fig, high_ax, low_ax, zoom_abs, **kwargs): -# y0 = low_ax.get_position().y0 -# y1 = high_ax.get_position().y1 -# transform = low_ax.transData + fig.transFigure.inverted() -# x0 = transform.transform((zoom_abs[0], 0))[0] -# x1 = transform.transform((zoom_abs[1], 0))[0] -# rect = plt.Rectangle((x0, y0), x1 - x0, y1 - y0, -# transform=fig.transFigure, **kwargs) -# fig.add_artist(rect) -# return None - -# def assign_colors(handles, types, colors): -# for handle, type_id in zip(handles, types): -# handle.set_color(colors[str(int(type_id))]) -# return None - -# def reorder_traces(handles, signal, zlow=2, zhigh=2.5): -# inds = np.argsort(signal.std(axis=0)) -# zorders = np.linspace(zlow, zhigh, len(inds))[::-1] -# for ind, z in zip(inds, zorders): -# handles[ind].set_zorder(z) -# return None - -# def choose_kernels(kern_specs, features, kern_types, per_type=2, thresh=0.01): -# mean_feat = features.mean(axis=0) -# feat_diff = np.abs(mean_feat[:, None] - mean_feat[None, :]) -# feat_diff[features.max(axis=0) < thresh, :] = np.nan -# feat_diff = np.nanmean(feat_diff, axis=0) - -# ranking = np.argsort(feat_diff) -# kern_inds = [] -# for type_id in kern_types: -# type_inds = np.nonzero(kern_specs[:, 0] == type_id)[0] -# rank_inds = np.nonzero(np.isin(ranking, type_inds))[0][-per_type:] -# kern_inds.extend(ranking[rank_inds]) -# return np.array(kern_inds) - -# def letter_subplots(axes, labels='abcd', x=0.02, y=1, ha='left', va='bottom', -# fontsize=16, fontweight='bold', **kwargs): -# for ax, label in zip(axes, labels): -# ax.text(x, y, label, transform=ax.transAxes, ha=ha, va=va, -# fontsize=fontsize, fontweight=fontweight, **kwargs) -# return None - - # GENERAL SETTINGS: target = 'Omocestus_rufipes' data_paths = glob.glob(f'../data/processed/{target}*.npz') stages = ['filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat'] -save_path = None#'../figures/' +save_path = '../figures/' # PLOT SETTINGS: fig_kwargs = dict( @@ -348,3 +217,6 @@ for data_path in data_paths: if save_path is not None: fig.savefig(f'{save_path}fig_feat_stages.pdf') plt.show() + +print('Done.') +embed() \ No newline at end of file diff --git a/python/plot_functions.py b/python/plot_functions.py index c2a24f4..6d15213 100644 --- a/python/plot_functions.py +++ b/python/plot_functions.py @@ -17,6 +17,12 @@ def prepare_fig(nrows, ncols, width=8, height=None, rheight=2, unit=1/2.54, axes[i, j].set_facecolor('none') return fig, axes +def hide_ticks(ax, side='bottom', ticks=True): + axis = 'x' if side in ['top', 'bottom'] else 'y' + params = {side: ticks, 'label' + side: False} + ax.tick_params(axis=axis, which='both', **params) + return None + def hide_axis(ax, side='bottom'): ax.spines[side].set_visible(False) params = {side: False, 'label' + side: False} @@ -33,7 +39,7 @@ def letter_subplots(axes, labels=None, x=0.02, y=1, ha='left', va='bottom', fontsize=fontsize, fontweight=fontweight, **kwargs) return None -def xlimits(ax, time, minval=None, maxval=None, pad=0.05): +def xlimits(time, ax=None, minval=None, maxval=None, pad=0.05): limits = [minval, maxval] if minval is None: limits[0] = time[0] @@ -44,9 +50,11 @@ def xlimits(ax, time, minval=None, maxval=None, pad=0.05): limits[0] -= span * pad if pad and maxval is None: limits[1] += span * pad - return ax.set_xlim(limits) + if ax is not None: + return ax.set_xlim(limits) + return limits -def ylimits(ax, signal, minval=None, maxval=None, pad=0.05): +def ylimits(signal, ax=None, minval=None, maxval=None, pad=0.05): limits = [minval, maxval] if minval is None: limits[0] = signal.min() @@ -57,7 +65,9 @@ def ylimits(ax, signal, minval=None, maxval=None, pad=0.05): limits[0] -= span * pad if pad and maxval is None: limits[1] += span * pad - return ax.set_ylim(limits) + if ax is not None: + return ax.set_ylim(limits) + return limits def xlabel(ax, label, y=-0.1, fontsize=20, **kwargs): ax.set_xlabel(label, fontsize=fontsize, **kwargs) @@ -82,8 +92,8 @@ def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs): def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None, xpad=None, ypad=0.05, yloc=None, xloc=None, **kwargs): handles = ax.plot(time, signal, **kwargs) - xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad) - ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad) + xlimits(time, ax=ax, minval=xmin, maxval=xmax, pad=xpad) + ylimits(signal, ax=ax, minval=ymin, maxval=ymax, pad=ypad) if xloc is not None: ax.xaxis.set_major_locator(plt.MultipleLocator(xloc)) if yloc is not None: @@ -98,7 +108,7 @@ def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs): if i < binary.shape[1] - 1: lower += offset + 1 upper += offset + 1 - xlimits(ax, time, minval=xmin, maxval=xmax, pad=0) + xlimits(time, ax=ax, minval=xmin, maxval=xmax, pad=0) ax.set_ylim(0, upper) hide_axis(ax, 'bottom') hide_axis(ax, 'left') diff --git a/python/save_inv_data_log-hp.py b/python/save_inv_data_log-hp.py new file mode 100644 index 0000000..e4244ff --- /dev/null +++ b/python/save_inv_data_log-hp.py @@ -0,0 +1,124 @@ +import plotstyle_plt +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.filters import decibel, sosfilter +from thunderhopper.model import extract_env +from IPython import embed + +# GENERAL SETTINGS: +target = 'Omocestus_rufipes' +data_paths = glob.glob(f'../data/processed/{target}*.npz') +save_path = '../data/inv/log_hp/' + +# ANALYSIS SETTINGS: +scales = np.arange(0, 10.1, 0.1) +save_scales = np.array([0, 0.5, 1, 2, 5, 10]) +floor_percents = dict(song=100, noise=99) +single_db_ref = True +plot_redundant = False + +# EXECUTION: +for data_path, name in zip(data_paths, crop_paths(data_paths)): + print(f'Processing {name}') + + # Load song envelope: + data, config = load_data(data_path, files='env') + song, rate = data['env'], config['env_rate'] + t_full = np.arange(song.shape[0]) / rate + + # Generate noise envelope: + rng = np.random.default_rng() + noise = rng.normal(size=song.shape) + noise = extract_env(noise, rate, config=config) + + # Normalize each: + song /= song.std() + noise /= noise.std() + + # Mix song component and noise component: + scaled = song[:, None] * scales[None, :] + mix = scaled + noise[:, None] + + # Find noise floor (experimental): + song_percent = np.percentile(scaled, floor_percents['song'], axis=0) + noise_percent = np.percentile(noise, floor_percents['noise']) + floor_scale = scales[np.nonzero(song_percent <= noise_percent)[0][-1]] + + # Process mixture: + mix_log = decibel(mix, axis=None if single_db_ref else 0) + mix_inv = sosfilter(mix_log, rate, config['inv_fcut'], 'hp', + padtype='constant', padlen=config['padlen']) + + # Get variances per stage: + var_env = mix.var(axis=0) + var_log = mix_log.var(axis=0) + var_inv = mix_inv.var(axis=0) + + # Get SNRs against pure noise per stage: + base_ind = np.nonzero(scales == 0)[0][0] + snr_env = var_env / var_env[base_ind] + snr_log = var_log / var_log[base_ind] + snr_inv = var_inv / var_inv[base_ind] + + if plot_redundant: + # Normalize SNRs: + norm_snr_env = snr_env / snr_env.max() + norm_snr_log = snr_log / snr_log.max() + norm_snr_inv = snr_inv / snr_inv.max() + + # Get SNR gain against env: + gain_log = snr_log / snr_env + gain_inv = snr_inv / snr_env + + # Plot results: + fig, axes = plt.subplots(6, 1, sharex=True, layout='constrained') + + axes[0].set_title('variance') + axes[0].plot(scales, var_env) + axes[0].plot(scales, var_log) + axes[0].plot(scales, var_inv) + + axes[1].set_title('normalized variance') + axes[1].plot(scales, var_env / var_env.max()) + axes[1].plot(scales, var_log / var_log.max()) + axes[1].plot(scales, var_inv / var_inv.max()) + + axes[2].set_title('SNR') + axes[2].plot(scales, snr_env) + axes[2].plot(scales, snr_log) + axes[2].plot(scales, snr_inv) + + axes[3].set_title('normalized SNR') + axes[3].plot(scales, norm_snr_env) + axes[3].plot(scales, norm_snr_log) + axes[3].plot(scales, norm_snr_inv) + + axes[4].set_title('gain (absolute SNR)') + axes[4].plot(scales, gain_log) + axes[4].plot(scales, gain_inv) + + axes[5].set_title('gain (normalized SNR)') + axes[5].plot(scales, norm_snr_log / norm_snr_env) + axes[5].plot(scales, norm_snr_inv / norm_snr_env) + plt.show() + + # Save analysis results: + save_inds = np.isin(scales, save_scales) + if save_path is not None: + data = dict( + scales=scales, + plot_scales=scales[save_inds], + floor_scale=floor_scale, + env=mix[:, save_inds], + log=mix_log[:, save_inds], + inv=mix_inv[:, save_inds], + snr_env=snr_env, + snr_log=snr_log, + snr_inv=snr_inv, + ) + save_data(save_path + name, data, config, overwrite=True) +print('Done.') +embed()