From 433e00d1b3e03a17083e21f40d5eb859c6b009ec Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 16 Apr 2024 17:27:10 -0700 Subject: [PATCH 01/25] Move reference to API; add proper intro page and glossary/concepts explanation --- docs/Manifest.toml | 983 +++++++++++++++++++++++++++++++++++++++++- docs/Project.toml | 2 + docs/make.jl | 12 +- docs/src/glossary.md | 280 ++++++++++++ docs/src/index.md | 93 +++- docs/src/reference.md | 34 ++ src/peakwidth.jl | 6 +- 7 files changed, 1386 insertions(+), 24 deletions(-) create mode 100644 docs/src/glossary.md create mode 100644 docs/src/reference.md diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 5317a7b..3ea9a7e 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "46b5b82f24e4b5d97afc2843032730b022086b31" +project_hash = "bd88975b48268047d3c3a80bea50368febdfc240" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -21,19 +21,130 @@ version = "1.1.1" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +[[deps.AssetRegistry]] +deps = ["Distributed", "JSON", "Pidfile", "SHA", "Test"] +git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" +uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" +version = "0.1.0" + [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blink]] +deps = ["Base64", "Distributed", "HTTP", "JSExpr", "JSON", "Lazy", "Logging", "MacroTools", "Mustache", "Mux", "Pkg", "Reexport", "Sockets", "WebIO"] +git-tree-sha1 = "bc93511973d1f949d45b0ea17878e6cb0ad484a1" +uuid = "ad839575-38b3-5650-b840-f874b8c74a25" +version = "0.12.9" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.4" +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.ColorVectorSpace.weakdeps] + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" @@ -51,15 +162,98 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+0" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" version = "2.5.0+0" +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.1" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.FunctionalCollections]] +deps = ["Test"] +git-tree-sha1 = "04cb9cfaa6ba5311973994fe3496ddec19b6292a" +uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" +version = "0.5.0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] +git-tree-sha1 = "3437ade7073682993e092ca570ad68a2aba26983" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.3" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a96d5c713e6aa28c242b0d25c1347e258d6541ab" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.3+0" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + [[deps.Git]] deps = ["Git_jll"] git-tree-sha1 = "04eff47b1354d702c3a85e8ab23d539bb7d5957e" @@ -72,6 +266,41 @@ git-tree-sha1 = "12945451c5d0e2d0dca0724c3a8d6448b46bbdf9" uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" version = "2.44.0+1" +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hiccup]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" +uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" +version = "0.2.2" + [[deps.IOCapture]] deps = ["Logging", "Random"] git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" @@ -82,23 +311,106 @@ version = "0.2.4" deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLFzf]] +deps = ["Pipe", "REPL", "Random", "fzf_jll"] +git-tree-sha1 = "a53ebe394b71470c7f97c2e7e170d51df21b17af" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.7" + [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" version = "1.5.0" +[[deps.JSExpr]] +deps = ["JSON", "MacroTools", "Observables", "WebIO"] +git-tree-sha1 = "b413a73785b98474d8af24fd4c8a975e31df3658" +uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +version = "0.5.4" + [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.4" +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.Kaleido_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "43032da5832754f58d14a91ffbe86d5f176acda9" +uuid = "f7e6163d-2fa5-5f23-b69c-1db539e41963" +version = "0.2.1+0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "bf36f528eec6634efc60d7ec062008f171071434" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "3.0.0+1" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.Latexify]] +deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "cad560042a7cc108f5a4c24ea1431a9221f22c1b" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.2" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SymEngineExt = "SymEngine" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + [[deps.LazilyInitializedFields]] git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" version = "1.2.2" +[[deps.Lazy]] +deps = ["MacroTools"] +git-tree-sha1 = "1370f8202dac30758f3c345f9909b97f53d87d3f" +uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" +version = "0.15.1" + [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" @@ -126,15 +438,89 @@ version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" version = "1.17.0+0" +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "2da088d113af58221c52828a80378e16be7d037a" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.5.1+1" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -145,11 +531,28 @@ git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.2" +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.2+1" +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" @@ -157,32 +560,173 @@ uuid = "a63ad114-7e13-5084-954f-fe012c677804" uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.1.10" +[[deps.Mustache]] +deps = ["Printf", "Tables"] +git-tree-sha1 = "a7cefa21a2ff993bff0456bf7521f46fc077ddf1" +uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" +version = "1.0.19" + +[[deps.Mux]] +deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "MbedTLS", "Pkg", "Sockets"] +git-tree-sha1 = "7295d849103ac4fcbe3b2e439f229c5cc77b9b69" +uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" +version = "1.0.2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.13+0" +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+1" +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.8.1" +[[deps.Pidfile]] +deps = ["FileWatching", "Test"] +git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.3.0" + +[[deps.Pipe]] +git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" +uuid = "b98c9c47-44ae-5843-9183-064241ee97a0" +version = "1.3.0" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.10.0" +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "1f03a2d339f42dca4a4da149c7e15e9b896ad899" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.1.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PlotlyBase]] +deps = ["ColorSchemes", "Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Parameters", "Pkg", "REPL", "Requires", "Statistics", "UUIDs"] +git-tree-sha1 = "56baf69781fc5e61607c3e46227ab17f7040ffa2" +uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5" +version = "0.8.19" + +[[deps.PlotlyJS]] +deps = ["Base64", "Blink", "DelimitedFiles", "JSExpr", "JSON", "Kaleido_jll", "Markdown", "Pkg", "PlotlyBase", "PlotlyKaleido", "REPL", "Reexport", "Requires", "WebIO"] +git-tree-sha1 = "e62d886d33b81c371c9d4e2f70663c0637f19459" +uuid = "f0f68f2c-4968-5e81-91da-67840de0976a" +version = "0.18.13" + + [deps.PlotlyJS.extensions] + CSVExt = "CSV" + DataFramesExt = ["DataFrames", "CSV"] + IJuliaExt = "IJulia" + JSON3Ext = "JSON3" + + [deps.PlotlyJS.weakdeps] + CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" + +[[deps.PlotlyKaleido]] +deps = ["Base64", "JSON", "Kaleido_jll"] +git-tree-sha1 = "2650cd8fb83f73394996d507b3411a7316f6f184" +uuid = "f2990250-8cf9-495f-b13a-cce12b45703c" +version = "2.2.4" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "3bdfa4fa528ef21287ef659a89d686e8a1bcb1a9" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.3" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" @@ -199,6 +743,12 @@ version = "1.4.3" deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "37b7bb7aabf9a085e0044307e1717436117f2b3b" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.5.3+1" + [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -207,32 +757,129 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + [[deps.RegistryInstances]] deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" version = "0.1.0" +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" version = "1.0.3" +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + [[deps.Tar]] deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" version = "1.10.0" +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -246,18 +893,334 @@ weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] TestExt = ["Test", "Random"] +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "3c793be6df9dd77a0cf49d80984ef9ff996948fa" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.19.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "e2d817cc500e960fdbafcf988ac8436ba3208bfd" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.6.3" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.21.0+1" + +[[deps.Wayland_protocols_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "93f43ab61b16ddfb2fd3bb13b3ce241cafb0e6c9" +uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" +version = "1.31.0+0" + +[[deps.WebIO]] +deps = ["AssetRegistry", "Base64", "Distributed", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "UUIDs", "WebSockets", "Widgets"] +git-tree-sha1 = "0eef0765186f7452e52236fa42ca8c9b3c11c6e3" +uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +version = "0.8.21" + +[[deps.WebSockets]] +deps = ["Base64", "Dates", "HTTP", "Logging", "Sockets"] +git-tree-sha1 = "4162e95e05e79922e44b9952ccbc262832e4ad07" +uuid = "104b5d7c-a370-577a-8038-80a2059c5097" +version = "1.6.0" + +[[deps.Widgets]] +deps = ["Colors", "Dates", "Observables", "OrderedCollections"] +git-tree-sha1 = "fcdae142c1cfc7d89de2d11e08721d0f2f86c98a" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.6.6" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Libdl", "Pkg"] +git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.0.10+1" + +[[deps.Xorg_libSM_jll]] +deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] +git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.3+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "730eeca102434283c50ccf7d1ecdadf521a765a4" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.2+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.4+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"] +git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.9+1" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.1+1" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "330f955bc41bb8f5270a369c473fc4a5a4e4d3cb" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.6+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "691634e5453ad362044e2ad653e79f3ee3bb98c3" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.39.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" version = "1.2.13+1" +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] +git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.9+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a68c9655fbe6dfcab3d972808f1aafec151ce3f8" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.43.0+0" + +[[deps.gperf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3516a5630f741c9eecb3720b1ec9d8edc3ecc033" +uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" +version = "3.1.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.11.0+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.18.0+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.6+0" + [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" @@ -267,3 +1230,21 @@ version = "1.52.0+1" deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.4.1+1" diff --git a/docs/Project.toml b/docs/Project.toml index 88df92a..6bb9aec 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,7 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" [compat] Documenter = "1.3" diff --git a/docs/make.jl b/docs/make.jl index d15c535..e42ca19 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,11 +7,19 @@ makedocs( modules = [Peaks], checkdocs = :exports, format = Documenter.HTML(; - prettyurls=get(ENV, "CI", "false") == "true", + prettyurls=true, canonical="https://halleysfifthinc.github.io/Peaks.jl", ), authors="Allen Hill and contributors", - repo=Remotes.GitHub("halleysfifthinc", "Peaks.jl") + repo=Remotes.GitHub("halleysfifthinc", "Peaks.jl"), + pages=[ + "Home" => "index.md", + "How-to" => "how-to.md", + "Reference" => [ + "Glossary" => "glossary.md", + "API" => "reference.md", + ], + ], ) # Documenter can also automatically deploy documentation to gh-pages. diff --git a/docs/src/glossary.md b/docs/src/glossary.md new file mode 100644 index 0000000..3898bb9 --- /dev/null +++ b/docs/src/glossary.md @@ -0,0 +1,280 @@ +```@setup prominence + using Peaks, PlotlyJS + + a = 3 + b = 2 + c = 1 + + fs = 100 + T = 1/fs + f1 = .05 + f2 = .10 + f3 = .30 + + sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) + t2 = 10:T:23.5 + x = sinf.(t2) + pks, = findmaxima(x) + currpk = pks[2] + prevpk = pks[1] + nextpk = pks[4] + leftmin = findnextminima(x, prevpk) + rightmin = findnextminima(x, currpk) + + _, proms = peakproms(pks, x) + pkprom = proms[2] + + p = plot(scatter(;x=t2, y=x), Layout(font_size=14); config=PlotConfig(responsive=true,scrollZoom=false)) + add_hline!(p, x[currpk]; line_dash="dash", line_width=2.5, line_color="rgba(89,105,112,0.40)") + add_trace!(p, scatter(;x=t2[pks[[1,4]]], y=x[pks[[1,4]]], mode=:markers)) + add_trace!(p, scatter(;x=[t2[currpk]], y=[x[currpk]], mode=:markers, marker_color=:purple)) + add_trace!(p, scatter(;x=[t2[pks[3]]], y=[x[pks[3]]], mode=:markers, marker_color=:gray)) + add_trace!(p, scatter(;x=t2[[leftmin,rightmin]], y=x[[leftmin,rightmin]], mode=:markers, marker_color=:blue)) + relayout!(p; annotations=[ + attr(;x=22.2, y=x[currpk]+.6, ay=x[currpk], ax=0, + ayref="y", + yref="y", + yanchor="top", + showarrow=true, + arrowhead=2, + arrowwidth=2.5, + arrowsize=.7, + arrowcolor="rgba(89,105,112,0.40)", + standoff=0, + startstandoff=0, + text="Minimum reference maxima", + ), + attr(;x=t2[prevpk], y=x[prevpk], + text="Previous reference peak", + ax=15, + showarrow=true, + arrowhead=2, + arrowsize=1.3, + xshift=2, + yshift=4, + ), + attr(;x=t2[currpk], y=x[currpk], + text="Current peak", + ax=15, + showarrow=true, + arrowhead=2, + arrowsize=1.3, + xshift=2, + yshift=4, + ), + attr(;x=t2[pks[3]], y=x[pks[3]], + text="Ignored (too small)", + hovertext="Peak is smaller than the current peak", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + xshift=-2, + yshift=4, + ), + attr(;x=t2[nextpk], y=x[nextpk], + text="Next reference peak", + ax=-15, + showarrow=true, + arrowhead=2, + arrowsize=1.3, + xshift=-2, + yshift=4, + ), + attr(;x=t2[leftmin], y=x[leftmin], + ax=-15, ay=15, + yanchor="top", + text="Larger minimum", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + xshift=-2, + yshift=-4, + ), + attr(;x=t2[currpk], y=x[leftmin], ax=t2[currpk], ay=x[currpk]-.07, + axref="x", ayref="y", + yanchor="bottom", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowsize=1.3, + ), + attr(;x=14.4, y=x[leftmin] + (x[currpk]-.07-x[leftmin])/2, + xanchor="left", + yanchor="middle", + text="Prominence: $(round(pkprom, digits=2))", + showarrow=false, + ), + ], + margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + showlegend=false, + ) + add_shape!(p, line(t2[leftmin], t2[currpk]+.15, x[leftmin], x[leftmin]; line_width=1.5, line_color=:blue)) +``` + +```@setup plateau + using Peaks, PlotlyJS + + t = 0:.001:1 + y=clamp.(sinpi.(t), 0, 0.75) + + p = plot(scatter(;x=t, y), Layout(; + margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + showlegend=false, + )) + pks = findmaxima(y) + + add_trace!(p, scatter(;x=t[pks[1]], y=y[pks[1]], mode=:markers)) +``` + +```@setup width + using Peaks, PlotlyJS + + t = -1.2:.001:1.2 + y = cospi.(t) .+ (t./-10) + pks = findmaxima(y) + pks = peakproms!(pks) + relheight = 0.7 + pks = peakwidths!(pks; relheight) + + xneg1 = findfirst(x -> x ≈ -1, t) + + p = plot(scatter(;y), Layout(; + margin=attr(b=10, l=10, r=10, t=10), + xlabel="Indices", + showlegend=false, + )) + + add_hline!(p, pks.heights[1] - pks.proms[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") + add_hline!(p, pks.heights[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") + + add_trace!(p, scatter(;x=pks.indices, y=pks.heights, mode=:markers)) + + codefont = attr(; + font_family="JuliaMono,SFMono-Regular,Menlo,Consolas,Liberation Mono,DejaVu Sans Mono,monospace", + bgcolor="#f2f2f2", + borderpad=4, + ) + relayout!(p, font_size=13, annotations=[ + attr(; + x=pks.edges[1][1], ax=pks.edges[1][2], + y=pks.heights[1] - pks.proms[1]*relheight, + ay=pks.heights[1] - pks.proms[1]*relheight, + xanchor="left", + axref="x", ayref="y", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowwidth=2, + ), + attr(; + x=xneg1, ax=xneg1, y=pks.heights[1] - pks.proms[1], ay=pks.heights[1], + axref="x", ayref="y", + yanchor="bottom", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowwidth=2, + ), + attr(; + x=xneg1, y=1, + xanchor="left", + yanchor="top", + xshift=8, yshift=-6, + text="Prominence", + showarrow=false, + ), + attr(codefont; + x=findfirst(x -> x ≈ 0.55, t), + xanchor="left", + y=pks.heights[1], + yshift=-5, + yanchor="top", + text="relheight = 0", + showarrow=false, + ), + attr(codefont; + x=pks.edges[1][2], + xshift=-20, + xanchor="right", + y=pks.heights[1] - pks.proms[1]*relheight, + yshift=2, + yanchor="bottom", + text="relheight = $(relheight)", + showarrow=false, + ), + attr(codefont; +# x=0.75, + x=findfirst(x -> x ≈ 0.75, t), + xshift=-20, + xanchor="right", + y=pks.heights[1] - pks.proms[1], + yshift=5, + yanchor="bottom", + text="relheight = 1", + showarrow=false, + ), + attr(codefont; +# x=-0.48, + x=findfirst(x -> x ≈ -0.55, t), + xanchor="left", + y=pks.heights[1] - pks.proms[1]*relheight, + yanchor="top", + yshift=-6, + text="width = $(round(pks.widths[1], digits=2))", + showarrow=false, + ), + ], + margin=attr(b=10, l=10, r=10, t=10), + ) +``` + +# Common terminology + +##### Peak (a.k.a. [local] extrema, maxima, minima, etc.) + +An element `x[i]` which is more extreme than its adjacent elements, or more extreme than all +elements in `x[i-w:i+w]` where `w` is a positive integer + +!!! note + May specifically refer to the index (i.e. location) of a peak, which is most + broadly relevant when speaking of a specific peak + +##### Plateau + +A "flat" peak, where the value of the maxima occurs multiple times consecutively, but surrounding elements are less than the maximal value. The first maximal value is considered the peak location. Uncommon for floating-point data. + +!!! note "Example plateau" + ```@example plateau + p # hide + ``` + +##### Peak prominence + +For maxima, peak prominence is the absolute difference in height between a maxima and the +larger of the two minimums in the adjacent reference ranges. Reference ranges are the range between the current maxima and adjacent (i.e. previous and next) reference maxima, which must be at least as large as the current maxima. The same is true of minima with opposite extrema/extremum (e.g. minima for maxima, and maximum for minimum, etc.). + +!!! note "Example prominence calculation" + ```@example prominence + p # hide + ``` + +##### Peak width + +Peak width is measured as the distance (in units of indices) between the intersection of a horizontal reference line with the signal on either side of a peak, where the height of the reference line is offset from the peak height by a proportion of the peak prominence. + +!!! note "Example peak width calculation" + ```@example width + p # hide + ``` + +##### "Strict"-ness + +The algorithms for finding peaks and calculating peak characteristics (e.g. prominence, etc.) have specific requirements of input data to return the requested outputs. All functions are `strict == true` by default (keyword argument), but setting the `strict` keyword to `false` allows participating functions to relax some alogithmic requirements. When `strict == false`, functions will make optimistic assumptions in an attempt to return useful information (e.g. not `NaN` or `missing`) when data violates normal algorithmic requirements. + +!!! warning "List of Peaks.jl function behavior/assumptions for `strict == false`" + - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing data in a window is consistent with a peak. For example: + - The maximal/minimal value in an incomplete window (i.e. the value `i` is within `w` elements of the array end, `i+w > lastindex(x)`, or beginning, `i-w < firstindex(x)`) is assumed to be a peak (i.e. if the array continued, the data would be less/more the current maximal/minimal value) + - The maximal/minimal value in a window containing `missing` or `NaN` elements is assumed to be a peak (i.e. the `missing` or `NaN` values would be less/more than the current value if they existed or were real numbers) + - `peakproms` uses the larger present (i.e. not `NaN` or `missing`) value of the minimum values in each reference range (see [prominence definition](#Peak-prominence)) + - `peakwidths` linearly interpolates across a gap at the width reference level + diff --git a/docs/src/index.md b/docs/src/index.md index 9396dbb..11ff9e1 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,21 +1,78 @@ # Peaks.jl -```@docs -argmaxima -argminima -maxima -minima -findmaxima -findminima -peakproms -peakproms! -peakwidths -peakwidths! -peakheights -peakheights! -filterpeaks! -findnextmaxima -findnextminima -ismaxima -isminima +## Installation + +Peaks.jl can be installed from the Julia REPL by running + +```julia-repl +] add Peaks +``` + +```@example +_, io_err = mktemp(); # hide +pkgout = redirect_stdio(stdout=devnull, stderr=io_err) do; # hide + run(`julia --color=yes -E 'using Pkg; Pkg.activate(;temp=true); Pkg.add("Peaks");'`) # hide +end; # hide +seekstart(io_err); # hide +out = read(IOContext(io_err, :color => true), String); # hide +close(io_err); # hide +print(out); # hide +``` + +## Finding peaks + +```@setup tutorial +using Peaks, Plots; gr() +Plots.reset_defaults() + +a = 3 +b = 2 +c = 1 + +fs = 100 +T = 1/fs +f1 = 5 +f2 = 10 +f3 = 30 + +t = T:T:25 + +sinf(t) = a*sin(2*pi*f1*T*t) + b*sin(2*pi*f2*T*t) + c*sin(2*pi*f3*T*t) + +x = sinf.(t); +``` + +```@example tutorial +p = plot(t, x; label="signal") # hide +``` + +To find the peaks in your data you can use the `findmaxima` function: + +```@repl tutorial +indices, heights = findmaxima(x) +``` + +When the peaks are plotted over the data, we see that all the local maxima have been identified. + +```@example tutorial +plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide ``` + +## Peak characteristics + +Two commonly desired peak characteristics can be determined using the `peakproms` and `peakwidths` functions: + +```@repl tutorial +indices, proms = peakproms(indices, x) + +indices, widths, edges... = peakwidths(indices, x, proms) +``` + +## Plotting + +The peaks, prominences, and widths can be visualized all together using `plotpeaks`: + +```@example tutorial +plotpeaks(t, x; peaks=indices, prominences=true, widths=true) +``` + diff --git a/docs/src/reference.md b/docs/src/reference.md new file mode 100644 index 0000000..79ea177 --- /dev/null +++ b/docs/src/reference.md @@ -0,0 +1,34 @@ +## Finding peaks + +```@docs +argmaxima +argminima +maxima +minima +findmaxima +findminima +simplemaxima +simpleminima +``` + +## Peak characteristics & filtering + +```@docs +peakproms +peakproms! +peakwidths +peakwidths! +peakheights +peakheights! +filterpeaks! +``` + +## Convenience functions + +```@docs +findnextmaxima +findnextminima +ismaxima +isminima +``` + diff --git a/src/peakwidth.jl b/src/peakwidth.jl index 2cc35c6..722d4fa 100644 --- a/src/peakwidth.jl +++ b/src/peakwidth.jl @@ -17,8 +17,8 @@ from `pks`. `pks` must have `:indices`, `:heights`, and `:proms` fields. If `pks remaining fields will be copied unmodified. If `strict == true`, the width for a peak with a gap in the signal (e.g. `NaN`, `missing`) -at the reference level will match the value/type of the signal gap. Otherwise, the signal -crossing will be linearly interpolated between the edges of the gap. +at the reference level will match the gap (e.g. `NaN` for `NaN`, etc.). Otherwise, the +signal crossing will be linearly interpolated between the edges of the gap. See also: [`peakwidths!`](@ref), [`peakproms`](@ref), [`findmaxima`](@ref) @@ -207,7 +207,7 @@ function peakwidths!(pks::NamedTuple; strict=true, relheight=0.5, min=nothing, m !hasproperty(pks, :proms) && throw(ArgumentError( "Argument `pks` is expected to have prominences (`:proms`) already calculated. \nExample fix: `peakwidths!(peakproms!(pks))`")) if xor(hasproperty(pks, :widths), hasproperty(pks, :edges)) - hasproperty(pks, :widths) ? + hasproperty(pks, :widths) ? throw(ArgumentError("Argument `pks` has property `:widths`, but not field `:edges`. As functions from Peaks.jl only ever add both, this implies unexpected tampering with the peaks provided. To avoid unexpected behaviour, this is an error." )) : throw(ArgumentError("Argument `pks` has property `:edges`, but not field `:widths`. As functions from Peaks.jl only ever add both, this implies unexpected tampering with the peaks provided. To avoid unexpected behaviour, this is an error." )) end From 45aa68274716bacfdbe9ba7aafb35eb933e36092 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 16 Apr 2024 17:34:36 -0700 Subject: [PATCH 02/25] Add how-to placeholder file --- docs/src/how-to.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/src/how-to.md diff --git a/docs/src/how-to.md b/docs/src/how-to.md new file mode 100644 index 0000000..2295d4f --- /dev/null +++ b/docs/src/how-to.md @@ -0,0 +1,8 @@ +# Find peaks + +Lorem ipsum... + +# Filter peaks + +Lorem ipsum... + From e8fa30567d85c608a75897c4972f063766101831 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 16 Apr 2024 17:47:23 -0700 Subject: [PATCH 03/25] Fix/separate PR contents --- docs/src/reference.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/reference.md b/docs/src/reference.md index 79ea177..b820e75 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -7,8 +7,6 @@ maxima minima findmaxima findminima -simplemaxima -simpleminima ``` ## Peak characteristics & filtering From 97d045a5b73504b37e903a8d59563c908839a19b Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 16 Apr 2024 18:27:42 -0700 Subject: [PATCH 04/25] Attempt to fix docs previews --- .github/workflows/CI.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f6b19fc..779bda0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -44,6 +44,10 @@ jobs: docs: name: Documentation runs-on: ubuntu-latest + permissions: + contents: write # Required when authenticating with `GITHUB_TOKEN`, not needed when authenticating with SSH deploy keys + pull-requests: read # Required when using `push_preview=true` + statuses: write # Optional, used to report documentation build statuses steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v1 From ef3bab53d8cb7a07837756d17504f62aaae161a4 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 17 Apr 2024 13:36:34 -0700 Subject: [PATCH 05/25] Add more examples and info to the front page --- docs/src/index.md | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 11ff9e1..658b873 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -19,7 +19,9 @@ close(io_err); # hide print(out); # hide ``` -## Finding peaks +## Getting started + +### Finding peaks ```@setup tutorial using Peaks, Plots; gr() @@ -31,13 +33,13 @@ c = 1 fs = 100 T = 1/fs -f1 = 5 -f2 = 10 -f3 = 30 +f1 = .05 +f2 = .10 +f3 = .30 -t = T:T:25 +t = T:T:23 -sinf(t) = a*sin(2*pi*f1*T*t) + b*sin(2*pi*f2*T*t) + c*sin(2*pi*f3*T*t) +sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) x = sinf.(t); ``` @@ -58,7 +60,7 @@ When the peaks are plotted over the data, we see that all the local maxima have plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide ``` -## Peak characteristics +### Peak characteristics Two commonly desired peak characteristics can be determined using the `peakproms` and `peakwidths` functions: @@ -68,11 +70,38 @@ indices, proms = peakproms(indices, x) indices, widths, edges... = peakwidths(indices, x, proms) ``` -## Plotting +Mutating bang (`'!'`) functions are available for `peakproms` (e.g. `peakproms!`), +`peakwidths`, and `peakheights`. + +### Peaks `NamedTuple` & pipable API + +There are Peaks.jl functions that bundle the peaks, peak characteristics, and signal into a convenient `NamedTuple`: + +```@repl tutorial +pks = findmaxima(x); +pks = peakproms(pks); +pks = peakwidths(pks) +``` + +Mutating functions are also available for the `NamedTuple` functions; the vectors within the +`NamedTuple` are mutated and re-used in the returned tuple. The `NamedTuple` functions can also be piped: + +```@repl tutorial +pks = findmaxima(x) |> peakproms!(;strict=false) |> peakwidths!(; max=100) +``` + +!!! warning "Performance tip" + Be aware that the `NamedTuple` functions allocate more memory than the functions with + direct/explicit arguments. If maximum performance is needed, mutating functions (e.g. + [`peakproms!`](@ref), etc) and/or the direct/non-`NamedTuple` functions are a better choice. + +### Plotting -The peaks, prominences, and widths can be visualized all together using `plotpeaks`: +The peaks, prominences, and widths can be visualized all together using the `Plots.jl` +recipe `plotpeaks`: ```@example tutorial +using Plots plotpeaks(t, x; peaks=indices, prominences=true, widths=true) ``` From 2d62dcb4c29bf770b87f72203323fcf11840fe05 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 17 Apr 2024 21:24:32 -0700 Subject: [PATCH 06/25] Fix Plots GR warning during build docs --- docs/make.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/make.jl b/docs/make.jl index e42ca19..a6ac0ca 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,6 +1,8 @@ using Documenter using Peaks +ENV["GKSwstype"] = "100" + DocMeta.setdocmeta!(Peaks, :DocTestSetup, :(using Peaks); recursive=true) makedocs( sitename = "Peaks", From e2091dc9906cc723d454686037cb9a9053db36bb Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 17 Apr 2024 21:24:56 -0700 Subject: [PATCH 07/25] Tweak signal gen for plot --- docs/src/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 658b873..2061f50 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -25,13 +25,12 @@ print(out); # hide ```@setup tutorial using Peaks, Plots; gr() -Plots.reset_defaults() a = 3 b = 2 c = 1 -fs = 100 +fs = 25 T = 1/fs f1 = .05 f2 = .10 From 165c1612737b23cd5171e5bbc898555a63d0f3dc Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 17 Apr 2024 21:25:39 -0700 Subject: [PATCH 08/25] Improve language clarity and add rolling peak finding animation --- docs/src/glossary.md | 224 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 208 insertions(+), 16 deletions(-) diff --git a/docs/src/glossary.md b/docs/src/glossary.md index 3898bb9..9399407 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -1,3 +1,151 @@ +```@setup peak-animation +using Peaks, PlotlyJS + +struct PlotForceHTML + p::Plot +end + +Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; + autoplay=false, include_plotlyjs="require", include_mathjax="mathjax-404-intended.js", + full_html=false); + +a = 3 +b = 2 +c = 1 + +T = .1 +f1 = .05 +f2 = .10 +f3 = .30 +w = 15 +frame_len = 550*T + +t = 0.:T:23 +ax = axes(t, 1) +clamp_window(i) = clamp(i-w,ax):clamp(i+w,ax) + +sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) + +y = sinf.(t); +pks = findmaxima(y, w) +pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, +name="Maxima", + legendrank=2, marker=attr(;color="#d62728", opacity=zeros(ax))) +maximum_trace = scatter(;x=[first(t)], y=[first(y)], mode="markers", marker_color="blueviolet", + legendrank=3, zorder=5, name="Window maximum") +windowshade = scatter(;x=[0], y=[0], visible="legendonly", opacity=.65, line=attr(;color=:black, width=15), + name="Window") + +p = Plot([ + scatter(;x=t, y, name="Signal", legendrank=1), + maximum_trace, + pks_trace, + windowshade], + Layout(; + legend=attr(; + itemclick=false, + itemdoubleclick=false, + ), + margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + yaxis_fixedrange=true, + xaxis_fixedrange=true, + xaxis_range=[first(t),last(t)], + updatemenus = [attr(; + x=0, y=0, + active=0, + type="buttons", + yanchor="bottom", + xanchor="left", + direction="left", + pad=attr(;l=6, b=6), + buttons=[ + attr(; + method="animate", + label="Play", + args=[nothing, attr(; + mode="next", + fromcurrent=true, + transition=attr(; + duration=frame_len, + easing="linear", + ), + frame = attr(; + duration=frame_len, + redraw=false + ) + )]), + attr(; + method="animate", + label="Pause", + args=[[nothing], attr(; + mode="next", + fromcurrent=true, + transition_duration=0, + frame = attr(; + duration=0, + redraw=false + ) + )]), + attr(; + method="animate", + label="Reset", + args=[[1], attr(; + mode="next", + transition_duration=0, + frame = attr(; + duration=0, + redraw=false + ) + )]) + ] + )], + sliders = [ attr(; + x=1, xanchor="right", + pad = attr(;l=-8, r=-8, t=20), + len = 1, + transition=attr(; + duration=frame_len, + easing="linear", + ), + currentvalue_visible=false, + ticklen=0, + minorticklen=0, + steps = [ + attr(; + method="animate", + label="", + args=[[i], attr(; + mode="immediate", + transition_duration=0, + frame = attr(; + redraw=false, + duration=0, + ) + )]) + for i in ax[begin:5:end] + ] + )]), + [ + frame(; name = i, + data = [ + attr(; + x=[t[clamp_window(i)[argmax(y[clamp_window(i)])]]], + y=[y[clamp_window(i)[argmax(y[clamp_window(i)])]]] + ), + attr(;marker_opacity=map(x -> x ≥ i ? 0 : 1, pks.indices)), + ], + traces = [1,2], + layout = attr(; + shapes = [ + rect(t[clamp(i-w, ax)], t[clamp(i+w,ax)], 0, 1; + yref="y domain", fillcolor=:black, opacity=0.25, layer="below", + line_width=0), + vline(t[clamp(i, ax)]) + ])) + for i in ax + ]; config=PlotConfig(;displayModeBar=false)) +``` + ```@setup prominence using Peaks, PlotlyJS @@ -115,15 +263,26 @@ using Peaks, PlotlyJS t = 0:.001:1 - y=clamp.(sinpi.(t), 0, 0.75) + y=clamp.(sinpi.(t), 0, 0.7) - p = plot(scatter(;x=t, y), Layout(; - margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + p = make_subplots(;cols=2, shared_yaxes="rows", horizontal_spacing=0.1, + subplot_titles=["Plateau" "Not plateaus"]) + relayout!(p, + margin=attr(autoexpand=true, b=10, l=10, r=10, t=25), showlegend=false, - )) - pks = findmaxima(y) + ) - add_trace!(p, scatter(;x=t[pks[1]], y=y[pks[1]], mode=:markers)) + pks = findmaxima(y) + add_trace!(p, scatter(;x=t, y); col=1) + add_trace!(p, scatter(;x=t[pks[1]], y=y[pks[1]], mode=:markers); col=1) + + t_time = searchsortedfirst(t, 0.35):searchsortedlast(t, 0.65) + clamp_begin = t[findfirst(==(0.7), y)] + clamp_end = t[findlast(==(0.7), y)] + y[t_time] += sinpi.(range(clamp_begin, clamp_end; length=length(t_time))) .- 0.7 + add_trace!(p, scatter(;x=t, y=y, line_color="#636efa"); col=2) + add_trace!(p, scatter(;x=[clamp_begin, clamp_end], y=[0.7,0.7], mode="markers", + marker_color=:gray); col=2) ``` ```@setup width @@ -233,15 +392,21 @@ ##### Peak (a.k.a. [local] extrema, maxima, minima, etc.) An element `x[i]` which is more extreme than its adjacent elements, or more extreme than all -elements in `x[i-w:i+w]` where `w` is a positive integer +elements in the window `x[i-w:i+w]` where `w` is a positive integer + +```@example peak-animation +PlotForceHTML(p) # hide +``` !!! note - May specifically refer to the index (i.e. location) of a peak, which is most + "Peak" may specifically refer to the index (i.e. location) of the peak, which is most broadly relevant when speaking of a specific peak ##### Plateau -A "flat" peak, where the value of the maxima occurs multiple times consecutively, but surrounding elements are less than the maximal value. The first maximal value is considered the peak location. Uncommon for floating-point data. +A "flat" peak, where the value of the extrema occurs multiple times consecutively, but +surrounding elements are less than the extremum. The first occurence of the extrema is +considered the peak location. Uncommon for floating-point data. !!! note "Example plateau" ```@example plateau @@ -251,7 +416,10 @@ A "flat" peak, where the value of the maxima occurs multiple times consecutively ##### Peak prominence For maxima, peak prominence is the absolute difference in height between a maxima and the -larger of the two minimums in the adjacent reference ranges. Reference ranges are the range between the current maxima and adjacent (i.e. previous and next) reference maxima, which must be at least as large as the current maxima. The same is true of minima with opposite extrema/extremum (e.g. minima for maxima, and maximum for minimum, etc.). +larger of the two minimums in the adjacent reference ranges. Reference ranges are the range +between the current maxima and adjacent (i.e. previous and next) reference maxima, which +must be at least as large as the current maxima. The same is true of minima with opposite +extrema/extremum (e.g. minima for maxima, and maximum for minimum, etc.). !!! note "Example prominence calculation" ```@example prominence @@ -260,7 +428,10 @@ larger of the two minimums in the adjacent reference ranges. Reference ranges ar ##### Peak width -Peak width is measured as the distance (in units of indices) between the intersection of a horizontal reference line with the signal on either side of a peak, where the height of the reference line is offset from the peak height by a proportion of the peak prominence. +Peak width is measured as the distance (in units of indices) between the intersection of a +horizontal reference line with the signal on either side of a peak, where the height of the +reference line is offset from the peak height by a proportion of the peak prominence +(keyword argument `relheight` for the `peakwidths` functions). !!! note "Example peak width calculation" ```@example width @@ -269,12 +440,33 @@ Peak width is measured as the distance (in units of indices) between the interse ##### "Strict"-ness -The algorithms for finding peaks and calculating peak characteristics (e.g. prominence, etc.) have specific requirements of input data to return the requested outputs. All functions are `strict == true` by default (keyword argument), but setting the `strict` keyword to `false` allows participating functions to relax some alogithmic requirements. When `strict == false`, functions will make optimistic assumptions in an attempt to return useful information (e.g. not `NaN` or `missing`) when data violates normal algorithmic requirements. +The default behavior of peak finding and related functions (e.g. `peakproms`, etc.) is to +only return results that are exactly correct, and to return nothing (i.e. ignore a potential +peak), `NaN`, or `missing`, as appropriate for a given function. This behavior is +controlled by the `strict` keyword argument (`true` by default). Setting the `strict` +keyword to `false` allows these functions to relax some data requirements. When `strict == +false`, functions will make optimistic assumptions in an attempt to return useful +information (e.g. not `NaN` or `missing`) when data violates default requirements. **This +can produce results that are not technically correct, but sometimes this is +desired/needed.** + +**`strict`-ness should only affect new peaks/characteristics (i.e. only peaks +detected with `strict == false`). Any observed behavior otherwise (i.e. non-`strict` peak +characteristics are altered) is a bug and an +[issue](https://github.com/halleysfifthinc/Peaks.jl/issues/new/choose) should be opened.** !!! warning "List of Peaks.jl function behavior/assumptions for `strict == false`" - - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing data in a window is consistent with a peak. For example: - - The maximal/minimal value in an incomplete window (i.e. the value `i` is within `w` elements of the array end, `i+w > lastindex(x)`, or beginning, `i-w < firstindex(x)`) is assumed to be a peak (i.e. if the array continued, the data would be less/more the current maximal/minimal value) - - The maximal/minimal value in a window containing `missing` or `NaN` elements is assumed to be a peak (i.e. the `missing` or `NaN` values would be less/more than the current value if they existed or were real numbers) - - `peakproms` uses the larger present (i.e. not `NaN` or `missing`) value of the minimum values in each reference range (see [prominence definition](#Peak-prominence)) + - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing + data in a window is consistent with a peak. For example: + - The maximal/minimal value in an incomplete window (e.g. an index `i` within `w` + elements of the array beginning or end, `i-w < firstindex(x)` or `i+w > + lastindex(x)`) is assumed to be a peak (i.e. if the array continued, the data + would be less/more the current maximal/minimal value). This allows the first or + last elements of an array to be considered peaks. + - The maximal/minimal value in a window containing `missing` or `NaN` elements is + assumed to be a peak (i.e. the `missing` or `NaN` values would be less/more than + the current value if they existed or were real numbers) + - `peakproms` uses the larger present (i.e. not `NaN` or `missing`) value of the minimum + values in each reference range (see [prominence definition](#Peak-prominence)) - `peakwidths` linearly interpolates across a gap at the width reference level From e84ddd53393b7398f696c78d33b724cb1ee5a331 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 17 Apr 2024 21:40:06 -0700 Subject: [PATCH 09/25] untested fix for bad header link gen --- docs/src/glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/glossary.md b/docs/src/glossary.md index 9399407..866557a 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -389,7 +389,7 @@ p = Plot([ # Common terminology -##### Peak (a.k.a. [local] extrema, maxima, minima, etc.) +##### [Peak (a.k.a. [local] extrema, maxima, minima, etc.)](@id peak) An element `x[i]` which is more extreme than its adjacent elements, or more extreme than all elements in the window `x[i-w:i+w]` where `w` is a positive integer From 0c8976fc6a9b2022ff333e4aa75a5773fcf2953a Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Thu, 18 Apr 2024 10:50:45 -0700 Subject: [PATCH 10/25] Better heading links --- docs/src/glossary.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/glossary.md b/docs/src/glossary.md index 866557a..d77d611 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -413,7 +413,7 @@ considered the peak location. Uncommon for floating-point data. p # hide ``` -##### Peak prominence +##### [Peak prominence](@id prominence) For maxima, peak prominence is the absolute difference in height between a maxima and the larger of the two minimums in the adjacent reference ranges. Reference ranges are the range @@ -426,7 +426,7 @@ extrema/extremum (e.g. minima for maxima, and maximum for minimum, etc.). p # hide ``` -##### Peak width +##### [Peak width](@id width) Peak width is measured as the distance (in units of indices) between the intersection of a horizontal reference line with the signal on either side of a peak, where the height of the @@ -438,7 +438,7 @@ reference line is offset from the peak height by a proportion of the peak promin p # hide ``` -##### "Strict"-ness +##### ["Strict"-ness](@id strict) The default behavior of peak finding and related functions (e.g. `peakproms`, etc.) is to only return results that are exactly correct, and to return nothing (i.e. ignore a potential From c27d18d1c0b7dd687975b85980001d70090375c7 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Thu, 18 Apr 2024 20:53:23 -0700 Subject: [PATCH 11/25] More writing improvements; move plotting to their own scripts; add animation for prominence --- docs/src/glossary.md | 428 ++----------------------- docs/src/plots/peak-animation.jl | 154 +++++++++ docs/src/plots/plateau.jl | 23 ++ docs/src/plots/prominence-animation.jl | 398 +++++++++++++++++++++++ docs/src/plots/width.jl | 97 ++++++ 5 files changed, 706 insertions(+), 394 deletions(-) create mode 100644 docs/src/plots/peak-animation.jl create mode 100644 docs/src/plots/plateau.jl create mode 100644 docs/src/plots/prominence-animation.jl create mode 100644 docs/src/plots/width.jl diff --git a/docs/src/glossary.md b/docs/src/glossary.md index d77d611..f92f437 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -1,390 +1,17 @@ ```@setup peak-animation -using Peaks, PlotlyJS - -struct PlotForceHTML - p::Plot -end - -Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; - autoplay=false, include_plotlyjs="require", include_mathjax="mathjax-404-intended.js", - full_html=false); - -a = 3 -b = 2 -c = 1 - -T = .1 -f1 = .05 -f2 = .10 -f3 = .30 -w = 15 -frame_len = 550*T - -t = 0.:T:23 -ax = axes(t, 1) -clamp_window(i) = clamp(i-w,ax):clamp(i+w,ax) - -sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) - -y = sinf.(t); -pks = findmaxima(y, w) -pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, -name="Maxima", - legendrank=2, marker=attr(;color="#d62728", opacity=zeros(ax))) -maximum_trace = scatter(;x=[first(t)], y=[first(y)], mode="markers", marker_color="blueviolet", - legendrank=3, zorder=5, name="Window maximum") -windowshade = scatter(;x=[0], y=[0], visible="legendonly", opacity=.65, line=attr(;color=:black, width=15), - name="Window") - -p = Plot([ - scatter(;x=t, y, name="Signal", legendrank=1), - maximum_trace, - pks_trace, - windowshade], - Layout(; - legend=attr(; - itemclick=false, - itemdoubleclick=false, - ), - margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), - yaxis_fixedrange=true, - xaxis_fixedrange=true, - xaxis_range=[first(t),last(t)], - updatemenus = [attr(; - x=0, y=0, - active=0, - type="buttons", - yanchor="bottom", - xanchor="left", - direction="left", - pad=attr(;l=6, b=6), - buttons=[ - attr(; - method="animate", - label="Play", - args=[nothing, attr(; - mode="next", - fromcurrent=true, - transition=attr(; - duration=frame_len, - easing="linear", - ), - frame = attr(; - duration=frame_len, - redraw=false - ) - )]), - attr(; - method="animate", - label="Pause", - args=[[nothing], attr(; - mode="next", - fromcurrent=true, - transition_duration=0, - frame = attr(; - duration=0, - redraw=false - ) - )]), - attr(; - method="animate", - label="Reset", - args=[[1], attr(; - mode="next", - transition_duration=0, - frame = attr(; - duration=0, - redraw=false - ) - )]) - ] - )], - sliders = [ attr(; - x=1, xanchor="right", - pad = attr(;l=-8, r=-8, t=20), - len = 1, - transition=attr(; - duration=frame_len, - easing="linear", - ), - currentvalue_visible=false, - ticklen=0, - minorticklen=0, - steps = [ - attr(; - method="animate", - label="", - args=[[i], attr(; - mode="immediate", - transition_duration=0, - frame = attr(; - redraw=false, - duration=0, - ) - )]) - for i in ax[begin:5:end] - ] - )]), - [ - frame(; name = i, - data = [ - attr(; - x=[t[clamp_window(i)[argmax(y[clamp_window(i)])]]], - y=[y[clamp_window(i)[argmax(y[clamp_window(i)])]]] - ), - attr(;marker_opacity=map(x -> x ≥ i ? 0 : 1, pks.indices)), - ], - traces = [1,2], - layout = attr(; - shapes = [ - rect(t[clamp(i-w, ax)], t[clamp(i+w,ax)], 0, 1; - yref="y domain", fillcolor=:black, opacity=0.25, layer="below", - line_width=0), - vline(t[clamp(i, ax)]) - ])) - for i in ax - ]; config=PlotConfig(;displayModeBar=false)) +include("plots/peak-animation.jl") ``` ```@setup prominence - using Peaks, PlotlyJS - - a = 3 - b = 2 - c = 1 - - fs = 100 - T = 1/fs - f1 = .05 - f2 = .10 - f3 = .30 - - sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) - t2 = 10:T:23.5 - x = sinf.(t2) - pks, = findmaxima(x) - currpk = pks[2] - prevpk = pks[1] - nextpk = pks[4] - leftmin = findnextminima(x, prevpk) - rightmin = findnextminima(x, currpk) - - _, proms = peakproms(pks, x) - pkprom = proms[2] - - p = plot(scatter(;x=t2, y=x), Layout(font_size=14); config=PlotConfig(responsive=true,scrollZoom=false)) - add_hline!(p, x[currpk]; line_dash="dash", line_width=2.5, line_color="rgba(89,105,112,0.40)") - add_trace!(p, scatter(;x=t2[pks[[1,4]]], y=x[pks[[1,4]]], mode=:markers)) - add_trace!(p, scatter(;x=[t2[currpk]], y=[x[currpk]], mode=:markers, marker_color=:purple)) - add_trace!(p, scatter(;x=[t2[pks[3]]], y=[x[pks[3]]], mode=:markers, marker_color=:gray)) - add_trace!(p, scatter(;x=t2[[leftmin,rightmin]], y=x[[leftmin,rightmin]], mode=:markers, marker_color=:blue)) - relayout!(p; annotations=[ - attr(;x=22.2, y=x[currpk]+.6, ay=x[currpk], ax=0, - ayref="y", - yref="y", - yanchor="top", - showarrow=true, - arrowhead=2, - arrowwidth=2.5, - arrowsize=.7, - arrowcolor="rgba(89,105,112,0.40)", - standoff=0, - startstandoff=0, - text="Minimum reference maxima", - ), - attr(;x=t2[prevpk], y=x[prevpk], - text="Previous reference peak", - ax=15, - showarrow=true, - arrowhead=2, - arrowsize=1.3, - xshift=2, - yshift=4, - ), - attr(;x=t2[currpk], y=x[currpk], - text="Current peak", - ax=15, - showarrow=true, - arrowhead=2, - arrowsize=1.3, - xshift=2, - yshift=4, - ), - attr(;x=t2[pks[3]], y=x[pks[3]], - text="Ignored (too small)", - hovertext="Peak is smaller than the current peak", - showarrow=true, - arrowhead=2, - arrowsize=1.3, - xshift=-2, - yshift=4, - ), - attr(;x=t2[nextpk], y=x[nextpk], - text="Next reference peak", - ax=-15, - showarrow=true, - arrowhead=2, - arrowsize=1.3, - xshift=-2, - yshift=4, - ), - attr(;x=t2[leftmin], y=x[leftmin], - ax=-15, ay=15, - yanchor="top", - text="Larger minimum", - showarrow=true, - arrowhead=2, - arrowsize=1.3, - xshift=-2, - yshift=-4, - ), - attr(;x=t2[currpk], y=x[leftmin], ax=t2[currpk], ay=x[currpk]-.07, - axref="x", ayref="y", - yanchor="bottom", - showarrow=true, - arrowside="end+start", - arrowhead=2, - arrowsize=1.3, - ), - attr(;x=14.4, y=x[leftmin] + (x[currpk]-.07-x[leftmin])/2, - xanchor="left", - yanchor="middle", - text="Prominence: $(round(pkprom, digits=2))", - showarrow=false, - ), - ], - margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), - showlegend=false, - ) - add_shape!(p, line(t2[leftmin], t2[currpk]+.15, x[leftmin], x[leftmin]; line_width=1.5, line_color=:blue)) +include("plots/prominence-animation.jl") ``` ```@setup plateau - using Peaks, PlotlyJS - - t = 0:.001:1 - y=clamp.(sinpi.(t), 0, 0.7) - - p = make_subplots(;cols=2, shared_yaxes="rows", horizontal_spacing=0.1, - subplot_titles=["Plateau" "Not plateaus"]) - relayout!(p, - margin=attr(autoexpand=true, b=10, l=10, r=10, t=25), - showlegend=false, - ) - - pks = findmaxima(y) - add_trace!(p, scatter(;x=t, y); col=1) - add_trace!(p, scatter(;x=t[pks[1]], y=y[pks[1]], mode=:markers); col=1) - - t_time = searchsortedfirst(t, 0.35):searchsortedlast(t, 0.65) - clamp_begin = t[findfirst(==(0.7), y)] - clamp_end = t[findlast(==(0.7), y)] - y[t_time] += sinpi.(range(clamp_begin, clamp_end; length=length(t_time))) .- 0.7 - add_trace!(p, scatter(;x=t, y=y, line_color="#636efa"); col=2) - add_trace!(p, scatter(;x=[clamp_begin, clamp_end], y=[0.7,0.7], mode="markers", - marker_color=:gray); col=2) +include("plots/plateau.jl") ``` ```@setup width - using Peaks, PlotlyJS - - t = -1.2:.001:1.2 - y = cospi.(t) .+ (t./-10) - pks = findmaxima(y) - pks = peakproms!(pks) - relheight = 0.7 - pks = peakwidths!(pks; relheight) - - xneg1 = findfirst(x -> x ≈ -1, t) - - p = plot(scatter(;y), Layout(; - margin=attr(b=10, l=10, r=10, t=10), - xlabel="Indices", - showlegend=false, - )) - - add_hline!(p, pks.heights[1] - pks.proms[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") - add_hline!(p, pks.heights[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") - - add_trace!(p, scatter(;x=pks.indices, y=pks.heights, mode=:markers)) - - codefont = attr(; - font_family="JuliaMono,SFMono-Regular,Menlo,Consolas,Liberation Mono,DejaVu Sans Mono,monospace", - bgcolor="#f2f2f2", - borderpad=4, - ) - relayout!(p, font_size=13, annotations=[ - attr(; - x=pks.edges[1][1], ax=pks.edges[1][2], - y=pks.heights[1] - pks.proms[1]*relheight, - ay=pks.heights[1] - pks.proms[1]*relheight, - xanchor="left", - axref="x", ayref="y", - showarrow=true, - arrowside="end+start", - arrowhead=2, - arrowwidth=2, - ), - attr(; - x=xneg1, ax=xneg1, y=pks.heights[1] - pks.proms[1], ay=pks.heights[1], - axref="x", ayref="y", - yanchor="bottom", - showarrow=true, - arrowside="end+start", - arrowhead=2, - arrowwidth=2, - ), - attr(; - x=xneg1, y=1, - xanchor="left", - yanchor="top", - xshift=8, yshift=-6, - text="Prominence", - showarrow=false, - ), - attr(codefont; - x=findfirst(x -> x ≈ 0.55, t), - xanchor="left", - y=pks.heights[1], - yshift=-5, - yanchor="top", - text="relheight = 0", - showarrow=false, - ), - attr(codefont; - x=pks.edges[1][2], - xshift=-20, - xanchor="right", - y=pks.heights[1] - pks.proms[1]*relheight, - yshift=2, - yanchor="bottom", - text="relheight = $(relheight)", - showarrow=false, - ), - attr(codefont; -# x=0.75, - x=findfirst(x -> x ≈ 0.75, t), - xshift=-20, - xanchor="right", - y=pks.heights[1] - pks.proms[1], - yshift=5, - yanchor="bottom", - text="relheight = 1", - showarrow=false, - ), - attr(codefont; -# x=-0.48, - x=findfirst(x -> x ≈ -0.55, t), - xanchor="left", - y=pks.heights[1] - pks.proms[1]*relheight, - yanchor="top", - yshift=-6, - text="width = $(round(pks.widths[1], digits=2))", - showarrow=false, - ), - ], - margin=attr(b=10, l=10, r=10, t=10), - ) +include("plots/width.jl") ``` # Common terminology @@ -392,7 +19,12 @@ p = Plot([ ##### [Peak (a.k.a. [local] extrema, maxima, minima, etc.)](@id peak) An element `x[i]` which is more extreme than its adjacent elements, or more extreme than all -elements in the window `x[i-w:i+w]` where `w` is a positive integer +elements in the window `x[i-w:i+w]` where `w` is a positive integer. + +In the animation below, the maximum in the window `x[i-w:i+w]` is shown as the purple dot. +When the location of the window maximum matches the current index (the vertical black line), +a peak is identified (red dot). Use the scroll bar at the bottom to understand why some +"peaks" aren't found. (Hint: pay attention the window size and the window maximum.) ```@example peak-animation PlotForceHTML(p) # hide @@ -406,7 +38,8 @@ PlotForceHTML(p) # hide A "flat" peak, where the value of the extrema occurs multiple times consecutively, but surrounding elements are less than the extremum. The first occurence of the extrema is -considered the peak location. Uncommon for floating-point data. +considered the peak location. Uncommon for +[floating-point data](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Floating-Point-Numbers). !!! note "Example plateau" ```@example plateau @@ -416,15 +49,15 @@ considered the peak location. Uncommon for floating-point data. ##### [Peak prominence](@id prominence) For maxima, peak prominence is the absolute difference in height between a maxima and the -larger of the two minimums in the adjacent reference ranges. Reference ranges are the range +larger of the two minimums in the adjacent reference ranges. Reference ranges cover the data between the current maxima and adjacent (i.e. previous and next) reference maxima, which -must be at least as large as the current maxima. The same is true of minima with opposite -extrema/extremum (e.g. minima for maxima, and maximum for minimum, etc.). +must be at least as large as the current maxima, or the beginning/end of the array. The same +is true of minima with opposite extrema/extremum (e.g. minima for maxima, and maximum for +minimum, etc.). -!!! note "Example prominence calculation" - ```@example prominence - p # hide - ``` +```@example prominence +PlotForceHTML(p) # hide +``` ##### [Peak width](@id width) @@ -442,19 +75,26 @@ reference line is offset from the peak height by a proportion of the peak promin The default behavior of peak finding and related functions (e.g. `peakproms`, etc.) is to only return results that are exactly correct, and to return nothing (i.e. ignore a potential -peak), `NaN`, or `missing`, as appropriate for a given function. This behavior is -controlled by the `strict` keyword argument (`true` by default). Setting the `strict` -keyword to `false` allows these functions to relax some data requirements. When `strict == -false`, functions will make optimistic assumptions in an attempt to return useful -information (e.g. not `NaN` or `missing`) when data violates default requirements. **This -can produce results that are not technically correct, but sometimes this is -desired/needed.** +peak), +[`NaN`](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Special-floating-point-values), +or [`missing`](https://docs.julialang.org/en/v1/manual/missing/), as appropriate for a given +function. This behavior is controlled by the `strict` keyword argument (`true` by default). +Setting the `strict` keyword to `false` allows these functions to relax some data +requirements. When `strict == false`, functions will make optimistic assumptions in an +attempt to return useful information (e.g. not `NaN` or `missing`) when data violates +default requirements. **This can produce results that are not technically correct, but +sometimes this is desired/needed.** **`strict`-ness should only affect new peaks/characteristics (i.e. only peaks detected with `strict == false`). Any observed behavior otherwise (i.e. non-`strict` peak -characteristics are altered) is a bug and an +characteristics are altered) is undesired[^1] and an [issue](https://github.com/halleysfifthinc/Peaks.jl/issues/new/choose) should be opened.** +[^1]: We try to ensure that non-`strict` peak characteristics will be +unaffected during `strict == false` mode. Any issues with examples of altered +characteristics are appreciated, and fixes will be attempted, but we do **not** guarantee +that altered peak characteristics can be prevented. + !!! warning "List of Peaks.jl function behavior/assumptions for `strict == false`" - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing data in a window is consistent with a peak. For example: diff --git a/docs/src/plots/peak-animation.jl b/docs/src/plots/peak-animation.jl new file mode 100644 index 0000000..bafb701 --- /dev/null +++ b/docs/src/plots/peak-animation.jl @@ -0,0 +1,154 @@ +using Peaks, PlotlyJS + +struct PlotForceHTML + p::Plot +end + +Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; + autoplay=false, include_plotlyjs="require", include_mathjax=missing, + full_html=false); + +a = 3 +b = 2 +c = 1 + +T = .1 +f1 = .05 +f2 = .10 +f3 = .30 +w = 16 +frame_len = 600*T + +t = 0.:T:23 +ax = axes(t, 1) +clamp_window(i) = clamp(i-w,ax):clamp(i+w,ax) + +sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) + +y = sinf.(t); +pks = findmaxima(y, w) +pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, + name="Maxima", legendrank=2, marker=attr(;color="#d62728", opacity=zeros(ax))) +maximum_trace = scatter(;x=[t[argmax(y[clamp_window(1)])]], y=[maximum(y[clamp_window(1)])], + mode="markers", marker_color="blueviolet", legendrank=3, zorder=5, name="Window maximum") +windowshade = scatter(;x=[0], y=[0], visible="legendonly", opacity=.65, + line=attr(;color=:black, width=15), name="Window") + +p = Plot([ + scatter(;x=t, y, name="Signal", legendrank=1), + maximum_trace, + pks_trace, + windowshade], + Layout(; + font_size=14, + legend=attr(; + itemclick=false, + itemdoubleclick=false, + ), + margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + yaxis_fixedrange=true, + xaxis_fixedrange=true, + xaxis_range=[first(t),last(t)], + shapes = [ + rect(t[clamp(1-w, ax)], t[clamp(1+w,ax)], 0, 1; + yref="y domain", fillcolor=:black, opacity=0.25, layer="below", + line_width=0), + vline(t[clamp(1, ax)]) + ], + updatemenus = [attr(; + x=0, y=0, + active=0, + type="buttons", + yanchor="bottom", + xanchor="left", + direction="left", + pad=attr(;l=6, b=6), + buttons=[ + attr(; + method="animate", + label="Play", + args=[nothing, attr(; + mode="next", + fromcurrent=true, + transition=attr(; + duration=frame_len, + easing="linear", + ), + frame = attr(; + duration=frame_len, + redraw=false + ) + )]), + attr(; + method="animate", + label="Pause", + args=[[nothing], attr(; + mode="next", + fromcurrent=true, + transition_duration=0, + frame = attr(; + duration=0, + redraw=false + ) + )]), + attr(; + method="animate", + label="Reset", + args=[[1], attr(; + mode="next", + transition_duration=0, + frame = attr(; + duration=0, + redraw=false + ) + )]) + ] + )], + sliders = [ attr(; + x=1, xanchor="right", + pad = attr(;l=-8, r=-8, t=20), + len = 1, + transition=attr(; + duration=frame_len, + easing="linear", + ), + currentvalue_visible=false, + ticklen=0, + minorticklen=0, + steps = [ + attr(; + method="animate", + label="", + args=[[i], attr(; + mode="immediate", + transition=attr(; + duration=frame_len, + easing="linear", + ), + frame = attr(; + redraw=false, + duration=0, + ) + )]) + for i in ax[begin:5:end] + ] + )]), + [ + frame(; name = i, + data = [ + attr(; + x=[t[clamp_window(i)[argmax(y[clamp_window(i)])]]], + y=[y[clamp_window(i)[argmax(y[clamp_window(i)])]]] + ), + attr(;marker_opacity=map(x -> x ≥ i ? 0 : 1, pks.indices)), + ], + traces = [1,2], + layout = attr(; + shapes = [ + rect(t[clamp(i-w, ax)], t[clamp(i+w,ax)], 0, 1; + yref="y domain", fillcolor=:black, opacity=0.25, layer="below", + line_width=0), + vline(t[clamp(i, ax)]) + ])) + for i in ax + ]; config=PlotConfig(;displayModeBar=false,showLink=false,showEditInChartStudio=false)) diff --git a/docs/src/plots/plateau.jl b/docs/src/plots/plateau.jl new file mode 100644 index 0000000..69cc668 --- /dev/null +++ b/docs/src/plots/plateau.jl @@ -0,0 +1,23 @@ +using Peaks, PlotlyJS + +t = 0:.001:1 +y=clamp.(sinpi.(t), 0, 0.7) + +p = make_subplots(;cols=2, shared_yaxes="rows", horizontal_spacing=0.1, + subplot_titles=["Plateau" "Not plateaus"]) +relayout!(p, + margin=attr(autoexpand=true, b=10, l=10, r=10, t=25), + showlegend=false, +) + +pks = findmaxima(y) +add_trace!(p, scatter(;x=t, y); col=1) +add_trace!(p, scatter(;x=t[pks[1]], y=y[pks[1]], mode=:markers); col=1) + +t_time = searchsortedfirst(t, 0.35):searchsortedlast(t, 0.65) +clamp_begin = t[findfirst(==(0.7), y)] +clamp_end = t[findlast(==(0.7), y)] +y[t_time] += sinpi.(range(clamp_begin, clamp_end; length=length(t_time))) .- 0.7 +add_trace!(p, scatter(;x=t, y=y, line_color="#636efa"); col=2) +add_trace!(p, scatter(;x=[clamp_begin, clamp_end], y=[0.7,0.7], mode="markers", + marker_color=:gray); col=2) diff --git a/docs/src/plots/prominence-animation.jl b/docs/src/plots/prominence-animation.jl new file mode 100644 index 0000000..c236057 --- /dev/null +++ b/docs/src/plots/prominence-animation.jl @@ -0,0 +1,398 @@ +using Peaks, PlotlyJS + +struct PlotForceHTML + p::Plot +end + +# "require-loaded" here because the first peak-animation plot already loaded plotly +Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; + autoplay=false, include_plotlyjs="require-loaded", include_mathjax=missing, + full_html=false); + +a = 3 +b = 2 +c = 1 + +T = .1 +f1 = .05 +f2 = .10 +f3 = .30 + +sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) +t = 10:T:23.5 +y = sinf.(t) +pks, = findmaxima(y) +currpk = pks[2] +prevpk = pks[1] +ignpk = pks[3] +nextpk = pks[4] +leftmin = findnextminima(y, prevpk) +rightmin = findnextminima(y, currpk) + +_, proms = peakproms(pks, y) +pkprom = proms[2] + +min_ref_max_arrow = attr(;x=21.8, y=y[currpk]+.6, ay=y[currpk], ax=0, + ayref="y", + yref="y", + yanchor="top", + showarrow=true, + arrowhead=2, + arrowwidth=2.5, + arrowsize=.7, + arrowcolor="rgba(89,105,112,0.40)", + standoff=0, + startstandoff=0, + text="Minimum reference maxima", +) +prev_peak_arr = attr(;x=t[prevpk], y=y[prevpk], + text="Previous reference peak", + ax=11.5, + axref="x", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=4, +) +curr_peak_arr = attr(;x=t[currpk], y=y[currpk], + text="Current peak", + ax=15, # px + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=4, +) +ign_peak_arr = attr(;x=t[pks[3]], y=y[pks[3]], + text="Ignored", + hovertext="Peak is smaller than the current peak", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=4, +) +next_peak_arr = attr(;x=t[nextpk], y=y[nextpk], + text="Next reference peak", + ax=-15, + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=4, +) +ref_mins_arr = [ + attr(;x=t[leftmin], y=y[leftmin], ax=13.5, ay=-3.4, + ayref="y", axref="x", + yanchor="top", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=5, + text="Reference minimums", + ); + attr(;x=t[rightmin], y=y[rightmin], ax=13.7, ay=-3.9, + ayref="y", axref="x", + yanchor="bottom", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=12, + startstandoff=12, + ) +] + +larger_ref_min = attr(;x=t[leftmin], y=y[leftmin], ax=13.5, ay=-3.4, + ayref="y", axref="x", + yanchor="top", + showarrow=true, + arrowhead=2, + arrowsize=1.3, + standoff=5, + text="Larger minimum", +) + +prom_arrow = attr(; + x=t[currpk], y=y[leftmin], + ax=t[currpk], ay=y[currpk]-.07, + axref="x", ayref="y", + yanchor="bottom", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowsize=1.3, + text="", +) +prom_text = attr(;x=14.4, y=y[leftmin] + (y[currpk]-.07-y[leftmin])/2, + xanchor="left", + yanchor="middle", + text="Prominence: $(round(pkprom, digits=2))", + showarrow=false, +) + +frame_currpeak = [ + frame(;name=0, # reset traces (color, visibility, etc) + data = [ + attr(; + visible=true, + x=fill(t[currpk], 3), + y=fill(y[currpk], 3), + marker_color=["rgba(214,39,40,0)", "rgba(128,128,128,0)", "rgba(214,39,40,0)"], + ), + attr(; + visible=true, + x=fill(t[currpk], 2), + y=fill(y[currpk], 2), + marker_color=["rgba(38,93,128,0)", "rgba(38,93,128,0)"] + ), + attr(; + visible=true, + x=fill(t[leftmin], 2), + y=fill(y[leftmin], 2), + marker_color="rgba(38,93,128,0)", + ), + ], + layout = attr(; + annotations = nothing, + shapes = nothing, + ), + traces = [1,2,3], + ), + frame(;name=1, + layout = attr(; + annotations = [ + curr_peak_arr; + ], + shapes = [], + ), + ), + frame(;name=2, + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + ], + shapes = [ + hline(y[currpk]; line_dash="dash", line_width=2.5, + line_color="rgba(89,105,112,0.40)") + ], + ), + ) +] + +frame_refpeaks = [ + frame(;name=3, + data = [ + attr(; + x=[t[prevpk]; fill(t[currpk], 2)], + y=[y[prevpk]; fill(y[currpk], 2)], + marker_color=["rgba(214,39,40,1)", "rgba(128,128,128,0)", "rgba(214,39,40,0)"], + ), + ], + traces = [1], + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ], + ), + ), + frame(;name=4, + data = [ + attr(; + x=[t[prevpk]; t[ignpk]; t[ignpk]], + y=[y[prevpk]; y[ignpk]; y[ignpk]], + marker_color=["rgba(214,39,40,1)", "rgba(128,128,128,1)", "rgba(214,39,40,0)"], + ), + ], + traces = [1], + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ign_peak_arr; + ], + ), + ), + frame(;name=5, + data = [ + attr(; + x=[t[prevpk]; t[ignpk]; t[nextpk]], + y=[y[prevpk]; y[ignpk]; y[nextpk]], + marker_color=["rgba(214,39,40,1)", "rgba(128,128,128,1)", "rgba(214,39,40,1)"], + ), + ], + traces = [1], + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ign_peak_arr; + next_peak_arr; + ], + ), + ), +] + +frame_minpks = [ + frame(;name=6, + data = [ + attr(; + x=[t[leftmin], t[rightmin]], + y=[y[leftmin], y[rightmin]], + marker_color=["rgba(38,93,128,1)", "rgba(38,93,128,1)"] + ), + ], + traces = [2], + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ign_peak_arr; + next_peak_arr; + ref_mins_arr; + ], + ), + ), + frame(;name=7, + traces=[2], + data = [ + attr(; + x=[t[leftmin], t[rightmin]], + y=[y[leftmin], y[rightmin]], + marker_color=["rgba(38,93,128,1)", "rgba(38,93,128,0)"] + ), + ], + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ign_peak_arr; + next_peak_arr; + larger_ref_min; + attr(;showarrow=false,text=""); + ], + ), + ), +] + +frame_prom = [ + frame(;name=8, + data = [ + attr(; + marker_color="rgba(38,93,128,1)", + ), + ], + traces = [3], + ), + frame(;name=9, + data = [ + attr(; + x=[t[leftmin]; 14], + ), + ], + traces = [3], + ), + frame(;name=10, + layout = attr(; + annotations = [ + curr_peak_arr; + min_ref_max_arrow; + prev_peak_arr; + ign_peak_arr; + next_peak_arr; + larger_ref_min; + prom_text; + prom_arrow; + ], + ), + ), +] + +p = Plot([ + scatter(;x=t, y, hoverinfo="x+y"); + scatter(;x=fill(t[currpk], 3), y=fill(y[currpk], 3), mode=:markers, zorder=10, + hoverinfo="x+y", marker=attr(; + color=["rgba(214,39,40,0)", "rgba(128,128,128,0)", "rgba(214,39,40,0)"] + )) + scatter(;x=fill(t[currpk], 2), y=fill(y[currpk], 2), mode=:markers, zorder=1, + hoverinfo="x+y", marker=attr(; + color=["rgba(38,93,128,0)", "rgba(38,93,128,0)"] + )) + scatter(;x=fill(t[leftmin], 2), y=fill(y[leftmin],2), marker_size=1, zorder=1000, + marker_color="rgba(38,93,128,0)", hoverinfo="none",) + scatter(;x=[t[currpk]], y=[y[currpk]], mode=:markers, zorder=100, marker_color=:purple, + hoverinfo="x+y") + ], Layout(; + font_size=14, + showlegend=false, + legend=attr(; + itemclick=false, + itemdoubleclick=false, + ), + margin=attr(autoexpand=false, b=10, l=10, r=10, t=10), + yaxis_fixedrange=true, + xaxis_fixedrange=true, + updatemenus = [attr(; + x=0, y=0, + active=0, + type="buttons", + yanchor="bottom", + xanchor="left", + direction="left", + pad=attr(;l=6, b=6), + buttons=[ + attr(; + method="animate", + label="Play", + args=[[0:10;], attr(; + mode="immediate", + transition=[ + attr(;duration=0, easing="linear",), + attr(;duration=100, easing="linear",), + attr(;duration=100, easing="linear",), + attr(;duration=800, ordering="traces first"), + attr(;duration=800, ordering="traces first"), + attr(;duration=800, ordering="traces first"), + attr(;duration=800, ordering="traces first"), + attr(;duration=800, ordering="traces first"), + attr(;duration=200, ordering="traces first"), + attr(;duration=400, easing="linear",), + attr(;duration=800), + ], + frame = [ + attr(;duration=10, redraw=true), + attr(;duration=1500, redraw=false), + attr(;duration=1500, redraw=false), + attr(;duration=2000, redraw=false), + attr(;duration=2000, redraw=false), + attr(;duration=2000, redraw=false), + attr(;duration=2000, redraw=false), + attr(;duration=1000, redraw=false), + attr(;duration=200, redraw=false), + attr(;duration=800, redraw=false), + attr(;duration=800, redraw=false), + ], + )]), + # attr(; + # label="Reset", + # method="update", + # args=[ + # attr(;visible=false,), # data + # attr(; # layout + # annotations = nothing, + # shapes = nothing, + # ), + # [1,2,3] # traces + # ]) + ] + )], + ), [ + frame_currpeak; + frame_refpeaks; + frame_minpks; + frame_prom; + ]; config=PlotConfig(displayModeBar=false,showLink=false,showEditInChartStudio=false)) + diff --git a/docs/src/plots/width.jl b/docs/src/plots/width.jl new file mode 100644 index 0000000..3448572 --- /dev/null +++ b/docs/src/plots/width.jl @@ -0,0 +1,97 @@ +using Peaks, PlotlyJS + +t = -1.2:.001:1.2 +y = cospi.(t) .+ (t./-10) +pks = findmaxima(y) +pks = peakproms!(pks) +relheight = 0.7 +pks = peakwidths!(pks; relheight) + +xneg1 = findfirst(x -> x ≈ -1, t) + +p = plot(scatter(;y), Layout(; + margin=attr(b=10, l=10, r=10, t=10), + xlabel="Indices", + showlegend=false, +)) + +add_hline!(p, pks.heights[1] - pks.proms[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") +add_hline!(p, pks.heights[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") + +add_trace!(p, scatter(;x=pks.indices, y=pks.heights, mode=:markers)) + +codefont = attr(; + font_family="JuliaMono,SFMono-Regular,Menlo,Consolas,Liberation Mono,DejaVu Sans Mono,monospace", + bgcolor="#f2f2f2", + borderpad=4, + ) +relayout!(p, font_size=13, annotations=[ + attr(; + x=pks.edges[1][1], ax=pks.edges[1][2], + y=pks.heights[1] - pks.proms[1]*relheight, + ay=pks.heights[1] - pks.proms[1]*relheight, + xanchor="left", + axref="x", ayref="y", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowwidth=2, + ), + attr(; + x=xneg1, ax=xneg1, y=pks.heights[1] - pks.proms[1], ay=pks.heights[1], + axref="x", ayref="y", + yanchor="bottom", + showarrow=true, + arrowside="end+start", + arrowhead=2, + arrowwidth=2, + ), + attr(; + x=xneg1, y=1, + xanchor="left", + yanchor="top", + xshift=8, yshift=-6, + text="Prominence", + showarrow=false, + ), + attr(codefont; + x=findfirst(x -> x ≈ 0.55, t), + xanchor="left", + y=pks.heights[1], + yshift=-5, + yanchor="top", + text="relheight = 0", + showarrow=false, + ), + attr(codefont; + x=pks.edges[1][2], + xshift=-20, + xanchor="right", + y=pks.heights[1] - pks.proms[1]*relheight, + yshift=2, + yanchor="bottom", + text="relheight = $(relheight)", + showarrow=false, + ), + attr(codefont; + x=findfirst(x -> x ≈ 0.75, t), + xshift=-20, + xanchor="right", + y=pks.heights[1] - pks.proms[1], + yshift=5, + yanchor="bottom", + text="relheight = 1", + showarrow=false, + ), + attr(codefont; + x=findfirst(x -> x ≈ -0.55, t), + xanchor="left", + y=pks.heights[1] - pks.proms[1]*relheight, + yanchor="top", + yshift=-6, + text="width = $(round(pks.widths[1], digits=2))", + showarrow=false, + ), +], + margin=attr(b=10, l=10, r=10, t=10), +) From fd17cdf5663cfd5c144373cfe1cd5cce841cff9f Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Thu, 18 Apr 2024 20:58:19 -0700 Subject: [PATCH 12/25] fix footnote --- docs/src/glossary.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/glossary.md b/docs/src/glossary.md index f92f437..dd04870 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -91,9 +91,9 @@ characteristics are altered) is undesired[^1] and an [issue](https://github.com/halleysfifthinc/Peaks.jl/issues/new/choose) should be opened.** [^1]: We try to ensure that non-`strict` peak characteristics will be -unaffected during `strict == false` mode. Any issues with examples of altered -characteristics are appreciated, and fixes will be attempted, but we do **not** guarantee -that altered peak characteristics can be prevented. + unaffected during `strict == false` mode. Any issues with examples of altered + characteristics are appreciated, and fixes will be attempted, but we do **not** guarantee + that altered peak characteristics can be prevented. !!! warning "List of Peaks.jl function behavior/assumptions for `strict == false`" - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing From 3a80ac1dcdc1abb9f410dcd61ef51dda620b6856 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Fri, 26 Apr 2024 15:00:14 -0700 Subject: [PATCH 13/25] Simplify curve formula --- docs/src/index.md | 31 +++++++++----------------- docs/src/plots/peak-animation.jl | 21 +++++++---------- docs/src/plots/prominence-animation.jl | 14 ++++-------- 3 files changed, 23 insertions(+), 43 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 2061f50..f25fb3e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -26,31 +26,22 @@ print(out); # hide ```@setup tutorial using Peaks, Plots; gr() -a = 3 -b = 2 -c = 1 +T = 1/25 +t = 0:T:23 -fs = 25 -T = 1/fs -f1 = .05 -f2 = .10 -f3 = .30 +f(t) = 3sinpi(0.1t) + 2sinpi(0.2t) + sinpi(0.6t) -t = T:T:23 - -sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) - -x = sinf.(t); +y = f.(t); ``` ```@example tutorial -p = plot(t, x; label="signal") # hide +p = plot(t, y; label="signal") # hide ``` To find the peaks in your data you can use the `findmaxima` function: ```@repl tutorial -indices, heights = findmaxima(x) +indices, heights = findmaxima(y) ``` When the peaks are plotted over the data, we see that all the local maxima have been identified. @@ -64,9 +55,9 @@ plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide Two commonly desired peak characteristics can be determined using the `peakproms` and `peakwidths` functions: ```@repl tutorial -indices, proms = peakproms(indices, x) +indices, proms = peakproms(indices, y) -indices, widths, edges... = peakwidths(indices, x, proms) +indices, widths, edges... = peakwidths(indices, y, proms) ``` Mutating bang (`'!'`) functions are available for `peakproms` (e.g. `peakproms!`), @@ -77,7 +68,7 @@ Mutating bang (`'!'`) functions are available for `peakproms` (e.g. `peakproms!` There are Peaks.jl functions that bundle the peaks, peak characteristics, and signal into a convenient `NamedTuple`: ```@repl tutorial -pks = findmaxima(x); +pks = findmaxima(y); pks = peakproms(pks); pks = peakwidths(pks) ``` @@ -86,7 +77,7 @@ Mutating functions are also available for the `NamedTuple` functions; the vector `NamedTuple` are mutated and re-used in the returned tuple. The `NamedTuple` functions can also be piped: ```@repl tutorial -pks = findmaxima(x) |> peakproms!(;strict=false) |> peakwidths!(; max=100) +pks = findmaxima(y) |> peakproms!(;strict=false) |> peakwidths!(; max=100) ``` !!! warning "Performance tip" @@ -101,6 +92,6 @@ recipe `plotpeaks`: ```@example tutorial using Plots -plotpeaks(t, x; peaks=indices, prominences=true, widths=true) +plotpeaks(t, y; peaks=indices, prominences=true, widths=true) ``` diff --git a/docs/src/plots/peak-animation.jl b/docs/src/plots/peak-animation.jl index bafb701..2ae5d86 100644 --- a/docs/src/plots/peak-animation.jl +++ b/docs/src/plots/peak-animation.jl @@ -8,25 +8,20 @@ Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html autoplay=false, include_plotlyjs="require", include_mathjax=missing, full_html=false); -a = 3 -b = 2 -c = 1 T = .1 -f1 = .05 -f2 = .10 -f3 = .30 -w = 16 -frame_len = 600*T - -t = 0.:T:23 +t = round.(0.:T:23; digits=1) ax = axes(t, 1) -clamp_window(i) = clamp(i-w,ax):clamp(i+w,ax) -sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) +sinf(t) = 3sinpi(0.1t) + 2sinpi(0.2t) + sinpi(0.6t) +y = round.(sinf.(t); sigdigits=3) -y = sinf.(t); +frame_len = 600*T +clamp_window(i) = clamp(i-w,ax):clamp(i+w,ax) + +w = 16 pks = findmaxima(y, w) + pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, name="Maxima", legendrank=2, marker=attr(;color="#d62728", opacity=zeros(ax))) maximum_trace = scatter(;x=[t[argmax(y[clamp_window(1)])]], y=[maximum(y[clamp_window(1)])], diff --git a/docs/src/plots/prominence-animation.jl b/docs/src/plots/prominence-animation.jl index c236057..dd196c4 100644 --- a/docs/src/plots/prominence-animation.jl +++ b/docs/src/plots/prominence-animation.jl @@ -9,18 +9,12 @@ Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html autoplay=false, include_plotlyjs="require-loaded", include_mathjax=missing, full_html=false); -a = 3 -b = 2 -c = 1 - T = .1 -f1 = .05 -f2 = .10 -f3 = .30 -sinf(t) = a*sin(2*pi*f1*t) + b*sin(2*pi*f2*t) + c*sin(2*pi*f3*t) -t = 10:T:23.5 -y = sinf.(t) +sinf(t) = 3sinpi(0.1t) + 2sinpi(0.2t) + sinpi(0.6t) +t = round.(10:T:23.5; digits=1) +y = round.(sinf.(t); sigdigits=3) + pks, = findmaxima(y) currpk = pks[2] prevpk = pks[1] From a19d37d9fcbdaa508328c09ff97c64830f9dad60 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Fri, 26 Apr 2024 15:00:44 -0700 Subject: [PATCH 14/25] Simplify pkg add peaks output example code --- docs/src/index.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index f25fb3e..b7d9a14 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -9,14 +9,16 @@ Peaks.jl can be installed from the Julia REPL by running ``` ```@example -_, io_err = mktemp(); # hide -pkgout = redirect_stdio(stdout=devnull, stderr=io_err) do; # hide - run(`julia --color=yes -E 'using Pkg; Pkg.activate(;temp=true); Pkg.add("Peaks");'`) # hide +mktempdir() do tmpdir # hide + out = read(`julia --color=yes -e " # hide + using Pkg; # hide + redirect_stderr(devnull) # hide + Pkg.activate(\"$tmpdir\"); # hide + redirect_stderr(stdout) # hide + Pkg.add(\"Peaks\");"`, String); # hide + out = replace(out, tmpdir => "~/.julia/environments/v$(VERSION.major).$(VERSION.minor)") # hide + print(out); # hide end; # hide -seekstart(io_err); # hide -out = read(IOContext(io_err, :color => true), String); # hide -close(io_err); # hide -print(out); # hide ``` ## Getting started From 7c33e2b37f6ba68f56245365761b8cc78c5df11b Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Fri, 26 Apr 2024 15:01:27 -0700 Subject: [PATCH 15/25] Add more explanations and improve phrasing --- docs/src/glossary.md | 90 ++++++++++++++++++++++++++++------------ docs/src/index.md | 3 ++ docs/src/plots/height.jl | 41 ++++++++++++++++++ 3 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 docs/src/plots/height.jl diff --git a/docs/src/glossary.md b/docs/src/glossary.md index dd04870..183803e 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -2,6 +2,10 @@ include("plots/peak-animation.jl") ``` +```@setup height +include("plots/height.jl") +``` + ```@setup prominence include("plots/prominence-animation.jl") ``` @@ -16,23 +20,45 @@ include("plots/width.jl") # Common terminology +#### Prefixes and suffixes + +##### "Maxim-", "minim-", "extrem-" prefixes + +- "Maxim-" refer to large/larger/etc +- "Minim-" refer to little/small/smaller/etc +- "Extrem-" refer to both large and small + +##### "-a", "-um" suffixes + +- The "-a" suffix (e.g. "maxima") means "of a part [of the data]"; + there can be multiple maxima in a vector (or a part of a vector) +- The "-um" suffix (e.g. "maximum") means "of the whole [data]"; + there can only be one maximum in a vector (or a part of a vector) + +#### Peaks and characteristics + ##### [Peak (a.k.a. [local] extrema, maxima, minima, etc.)](@id peak) -An element `x[i]` which is more extreme than its adjacent elements, or more extreme than all -elements in the window `x[i-w:i+w]` where `w` is a positive integer. +Maxima and minima refer to the maximum or minimum (respectively) value within a window, and +peak or extrema refers to both maxima and/or minima. -In the animation below, the maximum in the window `x[i-w:i+w]` is shown as the purple dot. -When the location of the window maximum matches the current index (the vertical black line), -a peak is identified (red dot). Use the scroll bar at the bottom to understand why some -"peaks" aren't found. (Hint: pay attention the window size and the window maximum.) +More technically, a peak is an element `x[i]` which is more extreme (i.e. larger or smaller) +than all elements in the window `x[i-w:i+w]` where `w` is a positive integer. The simplest +and most common case is `w=1`, which results in an element being more extreme than its +neighbors. + +In the animation below, the maximum in the window `x[i-w:i+w]` (grey band) is shown as the +purple dot. When the maximum lines up with the current "time" (i.e. index, vertical black +line), a peak is identified (red dot). Use the scroll bar at the bottom to understand why +some "peaks" aren't found. (Hint: pay attention the window size and the window maximum.) ```@example peak-animation PlotForceHTML(p) # hide ``` !!! note - "Peak" may specifically refer to the index (i.e. location) of the peak, which is most - broadly relevant when speaking of a specific peak + In this package/documentation, "peak" is often used when referring to the index (i.e. + location) of a peak, which is most broadly relevant when speaking of a specific peak ##### Plateau @@ -41,14 +67,22 @@ surrounding elements are less than the extremum. The first occurence of the extr considered the peak location. Uncommon for [floating-point data](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Floating-Point-Numbers). -!!! note "Example plateau" - ```@example plateau - p # hide - ``` +```@example plateau +p # hide +``` + +##### [Peak height](@id height) + +Peak height is the value of the signal for a specific peak. Mouse over (or touch) each peak +to see its height. + +```@example height +PlotForceHTML(p) # hide +``` ##### [Peak prominence](@id prominence) -For maxima, peak prominence is the absolute difference in height between a maxima and the +For maxima, peak prominence is the (absolute) difference between the height of a maxima and the larger of the two minimums in the adjacent reference ranges. Reference ranges cover the data between the current maxima and adjacent (i.e. previous and next) reference maxima, which must be at least as large as the current maxima, or the beginning/end of the array. The same @@ -66,10 +100,9 @@ horizontal reference line with the signal on either side of a peak, where the he reference line is offset from the peak height by a proportion of the peak prominence (keyword argument `relheight` for the `peakwidths` functions). -!!! note "Example peak width calculation" - ```@example width - p # hide - ``` +```@example width +p # hide +``` ##### ["Strict"-ness](@id strict) @@ -79,30 +112,33 @@ peak), [`NaN`](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Special-floating-point-values), or [`missing`](https://docs.julialang.org/en/v1/manual/missing/), as appropriate for a given function. This behavior is controlled by the `strict` keyword argument (`true` by default). -Setting the `strict` keyword to `false` allows these functions to relax some data +Setting the `strict` keyword to `false` allows these functions to relax some requirements. When `strict == false`, functions will make optimistic assumptions in an -attempt to return useful information (e.g. not `NaN` or `missing`) when data violates -default requirements. **This can produce results that are not technically correct, but -sometimes this is desired/needed.** +attempt to return useful information (e.g. something not `NaN` or `missing`) when data +violates default requirements. **This can produce results that are not correct according to +the strictest definitions of peaks and their characteristics, however, sometimes relaxed +behavior is desired/needed.** **`strict`-ness should only affect new peaks/characteristics (i.e. only peaks -detected with `strict == false`). Any observed behavior otherwise (i.e. non-`strict` peak -characteristics are altered) is undesired[^1] and an +detected with `strict == false`). Any observed behavior otherwise (i.e. characteristics of +non-`strict` peaks are altered) is undesired[^1] and an [issue](https://github.com/halleysfifthinc/Peaks.jl/issues/new/choose) should be opened.** -[^1]: We try to ensure that non-`strict` peak characteristics will be +[^1]: We try to ensure that characteristics of non-`strict` peak will be unaffected during `strict == false` mode. Any issues with examples of altered characteristics are appreciated, and fixes will be attempted, but we do **not** guarantee that altered peak characteristics can be prevented. !!! warning "List of Peaks.jl function behavior/assumptions for `strict == false`" - - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any missing - data in a window is consistent with a peak. For example: + - `maxima`/`minima` finding functions (e.g. `findmaxima`, etc.) assume that any + unobserved (e.g. `missing` or due to the beginning/end of the array) or `NaN` data in + a window is consistent with a peak. For example: - The maximal/minimal value in an incomplete window (e.g. an index `i` within `w` elements of the array beginning or end, `i-w < firstindex(x)` or `i+w > lastindex(x)`) is assumed to be a peak (i.e. if the array continued, the data would be less/more the current maximal/minimal value). This allows the first or - last elements of an array to be considered peaks. + last elements of an array to be considered peaks if the data in the window is + ascending or descending. - The maximal/minimal value in a window containing `missing` or `NaN` elements is assumed to be a peak (i.e. the `missing` or `NaN` values would be less/more than the current value if they existed or were real numbers) diff --git a/docs/src/index.md b/docs/src/index.md index b7d9a14..e16b627 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,5 +1,8 @@ # Peaks.jl +Peaks is a library to find peaks (i.e. local maxima and minima) and peak characteristics +(e.g. how tall or wide are peaks, etc) in vector (1D) data. + ## Installation Peaks.jl can be installed from the Julia REPL by running diff --git a/docs/src/plots/height.jl b/docs/src/plots/height.jl new file mode 100644 index 0000000..38ec03b --- /dev/null +++ b/docs/src/plots/height.jl @@ -0,0 +1,41 @@ +using Peaks, PlotlyJS + +struct PlotForceHTML + p::Plot +end + +Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; + autoplay=false, include_plotlyjs="require", include_mathjax=missing, + full_html=false); + +T = .1 +w = 16 + +t = round.(0.:T:23; digits=3) + +sinf(t) = 3sinpi(0.1t) + 2sinpi(0.2t) + sinpi(0.6t) +y = round.(sinf.(t); sigdigits=3) + +pks = findmaxima(y, w) + +pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, + yhoverformat=".2g", + name="Maxima", legendrank=2, marker=attr(;color="#d62728")) + +p = Plot([ + scatter(;x=t, y, name="Signal", legendrank=1, hoverinfo="none"), + pks_trace + ], + Layout(; + hoverdistance=100, + font_size=14, + legend=attr(; + itemclick=false, + itemdoubleclick=false, + ), + margin=attr(autoexpand=false, b=40, l=10, r=10, t=10), + yaxis_fixedrange=true, + xaxis_fixedrange=true, + xaxis_range=[first(t),last(t)], + ); config=PlotConfig(;displayModeBar=false,showLink=false,showEditInChartStudio=false)) + From 01033c91d12168b281ecc7c790f2827315330a24 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Apr 2024 17:56:55 -0700 Subject: [PATCH 16/25] Move example plots boilerplate to file (DRY) --- docs/src/glossary.md | 1 + docs/src/plots/height.jl | 8 +------- docs/src/plots/peak-animation.jl | 9 +-------- docs/src/plots/prominence-animation.jl | 9 +-------- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/docs/src/glossary.md b/docs/src/glossary.md index 183803e..94b4a19 100644 --- a/docs/src/glossary.md +++ b/docs/src/glossary.md @@ -53,6 +53,7 @@ line), a peak is identified (red dot). Use the scroll bar at the bottom to under some "peaks" aren't found. (Hint: pay attention the window size and the window maximum.) ```@example peak-animation +INCLUDE_PLOTLYJS[] = "require" # hide PlotForceHTML(p) # hide ``` diff --git a/docs/src/plots/height.jl b/docs/src/plots/height.jl index 38ec03b..e8c0719 100644 --- a/docs/src/plots/height.jl +++ b/docs/src/plots/height.jl @@ -1,12 +1,6 @@ using Peaks, PlotlyJS -struct PlotForceHTML - p::Plot -end - -Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; - autoplay=false, include_plotlyjs="require", include_mathjax=missing, - full_html=false); +include(joinpath(@__DIR__, "standards.jl")) T = .1 w = 16 diff --git a/docs/src/plots/peak-animation.jl b/docs/src/plots/peak-animation.jl index 2ae5d86..79814d1 100644 --- a/docs/src/plots/peak-animation.jl +++ b/docs/src/plots/peak-animation.jl @@ -1,13 +1,6 @@ using Peaks, PlotlyJS -struct PlotForceHTML - p::Plot -end - -Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; - autoplay=false, include_plotlyjs="require", include_mathjax=missing, - full_html=false); - +include(joinpath(@__DIR__, "standards.jl")) T = .1 t = round.(0.:T:23; digits=1) diff --git a/docs/src/plots/prominence-animation.jl b/docs/src/plots/prominence-animation.jl index dd196c4..0f9930a 100644 --- a/docs/src/plots/prominence-animation.jl +++ b/docs/src/plots/prominence-animation.jl @@ -1,13 +1,6 @@ using Peaks, PlotlyJS -struct PlotForceHTML - p::Plot -end - -# "require-loaded" here because the first peak-animation plot already loaded plotly -Base.show(io, ::MIME"text/html", p::PlotForceHTML) = PlotlyJS.PlotlyBase.to_html(io, p.p; - autoplay=false, include_plotlyjs="require-loaded", include_mathjax=missing, - full_html=false); +include(joinpath(@__DIR__, "standards.jl")) T = .1 From d79ff6f515f3062fcfecc70656fc1fb879d6bdfa Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Apr 2024 17:57:06 -0700 Subject: [PATCH 17/25] Update pkgs --- docs/Manifest.toml | 54 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 3ea9a7e..f636229 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -122,9 +122,9 @@ version = "1.16.0" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.18" +version = "0.18.20" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -153,9 +153,9 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "4a40af50e8b24333b9ec6892546d9ca5724228eb" +git-tree-sha1 = "f15a91e6e3919055efa4f206f942a73fedf5dfe6" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.3.0" +version = "1.4.0" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -262,9 +262,9 @@ version = "1.3.1" [[deps.Git_jll]] deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "12945451c5d0e2d0dca0724c3a8d6448b46bbdf9" +git-tree-sha1 = "d18fb8a1f3609361ebda9bf029b60fd0f120c809" uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" -version = "2.44.0+1" +version = "2.44.0+2" [[deps.Glib_jll]] deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] @@ -285,9 +285,9 @@ version = "1.0.2" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +git-tree-sha1 = "2c3ec1f90bb4a8f7beafb0cffea8a4c3f4e636ab" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.5" +version = "1.10.6" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -388,9 +388,9 @@ version = "1.3.1" [[deps.Latexify]] deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] -git-tree-sha1 = "cad560042a7cc108f5a4c24ea1431a9221f22c1b" +git-tree-sha1 = "e0b5cd21dc1b44ec6e64f351976f961e6f31d6c4" uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.16.2" +version = "0.16.3" [deps.Latexify.extensions] DataFramesExt = "DataFrames" @@ -445,10 +445,10 @@ uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" version = "3.2.2+1" [[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] -git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" +version = "1.8.11+0" [[deps.Libglvnd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] @@ -470,9 +470,9 @@ version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +git-tree-sha1 = "4b683b19157282f50bfd5dcaa2efe5295814ea22" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.39.3+0" +version = "2.40.0+0" [[deps.Libtiff_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] @@ -482,9 +482,9 @@ version = "4.5.1+1" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +git-tree-sha1 = "27fd5cc10be85658cacfe11bb81bee216af13eda" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+1" +version = "2.40.0+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -605,15 +605,15 @@ version = "0.8.1+2" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.2" +version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+0" +version = "3.0.13+1" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -709,9 +709,9 @@ version = "2.2.4" [[deps.Plots]] deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] -git-tree-sha1 = "3bdfa4fa528ef21287ef659a89d686e8a1bcb1a9" +git-tree-sha1 = "442e1e7ac27dd5ff8825c3fa62fbd1e86397974b" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.40.3" +version = "1.40.4" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -729,9 +729,9 @@ version = "1.40.3" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" +version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] @@ -885,9 +885,9 @@ deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TranscodingStreams]] -git-tree-sha1 = "3caa21522e7efac1ba21834a03734c57b4611c7e" +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.4" +version = "0.10.7" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] From 6dba73d0b79b706da4bbf95c1a6c1fd5e318db41 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Apr 2024 17:57:41 -0700 Subject: [PATCH 18/25] Reduce glossary page size by removing redundant info in plot --- docs/src/plots/peak-animation.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/src/plots/peak-animation.jl b/docs/src/plots/peak-animation.jl index 79814d1..fb55f27 100644 --- a/docs/src/plots/peak-animation.jl +++ b/docs/src/plots/peak-animation.jl @@ -16,7 +16,7 @@ w = 16 pks = findmaxima(y, w) pks_trace = scatter(;x=t[pks.indices], y=pks.heights, mode="markers", zorder=10, - name="Maxima", legendrank=2, marker=attr(;color="#d62728", opacity=zeros(ax))) +name="Maxima", legendrank=2, marker=attr(;color="#d62728", opacity=zeros(Int, size(pks.indices)))) maximum_trace = scatter(;x=[t[argmax(y[clamp_window(1)])]], y=[maximum(y[clamp_window(1)])], mode="markers", marker_color="blueviolet", legendrank=3, zorder=5, name="Window maximum") windowshade = scatter(;x=[0], y=[0], visible="legendonly", opacity=.65, @@ -133,9 +133,7 @@ p = Plot([ traces = [1,2], layout = attr(; shapes = [ - rect(t[clamp(i-w, ax)], t[clamp(i+w,ax)], 0, 1; - yref="y domain", fillcolor=:black, opacity=0.25, layer="below", - line_width=0), + rect(t[clamp(i-w, ax)], t[clamp(i+w,ax)], 0, 1) vline(t[clamp(i, ax)]) ])) for i in ax From 4b7619885aca6ae48d465b1754f022ae27c9230e Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Apr 2024 21:59:55 -0700 Subject: [PATCH 19/25] Add missing standards file --- docs/src/plots/standards.jl | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/src/plots/standards.jl diff --git a/docs/src/plots/standards.jl b/docs/src/plots/standards.jl new file mode 100644 index 0000000..9e5585d --- /dev/null +++ b/docs/src/plots/standards.jl @@ -0,0 +1,34 @@ +using PlotlyBase +using PlotlyBase: _TRACE_TYPES + +struct PlotForceHTML + p::Plot +end + +const INCLUDE_PLOTLYJS = Ref("require-loaded") + +# "require-loaded" here because the first peak-animation plot already loaded plotly +function Base.show(io, ::MIME"text/html", p::PlotForceHTML) + PlotlyBase.to_html(io, filter_template!(p.p; no_colorscales=true); + autoplay=false, full_html=false, + include_plotlyjs=INCLUDE_PLOTLYJS[], include_mathjax=missing) +end + +# Default template in PlotlyBase includes templates for many different trace types, +# filtering unnecessary elements can save 4.8 KiB per plot +function filter_template!(p::Plot; no_colorscales=false) + template = deepcopy(p.layout.template) + tracetypes = unique!(map(x -> x.type, p.data)) + rmtraces = setdiff(_TRACE_TYPES, tracetypes) + foreach(rmtraces) do trace + delete!(template.data, trace) + end + + if no_colorscales + delete!(template.layout.fields, :colorscale) + end + + p.layout.template = template + return p +end + From 0009611e223d87c1a20c3f8e668e96e415b22b09 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Wed, 1 May 2024 17:22:31 -0700 Subject: [PATCH 20/25] Add plotlybase to docs env --- docs/Manifest.toml | 6 +++--- docs/Project.toml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index f636229..c29f212 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.2" +julia_version = "1.10.3" manifest_format = "2.0" -project_hash = "bd88975b48268047d3c3a80bea50368febdfc240" +project_hash = "0aafd5257cc76f8dd633a6b3c182bcbe3262e5db" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -102,7 +102,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.0+0" +version = "1.1.1+0" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] diff --git a/docs/Project.toml b/docs/Project.toml index 6bb9aec..6942289 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" From 2981cb3eefcf6c01511edd174e7786d83dca63b8 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Jul 2024 10:46:56 -0700 Subject: [PATCH 21/25] Tweak width plot --- docs/src/plots/width.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/src/plots/width.jl b/docs/src/plots/width.jl index 3448572..dc28a59 100644 --- a/docs/src/plots/width.jl +++ b/docs/src/plots/width.jl @@ -1,7 +1,7 @@ using Peaks, PlotlyJS -t = -1.2:.001:1.2 -y = cospi.(t) .+ (t./-10) +t = round.(-1.2:.01:1.2; digits=2) +y = round.(cospi.(t) .+ (t./-10); digits=3) pks = findmaxima(y) pks = peakproms!(pks) relheight = 0.7 @@ -9,7 +9,7 @@ pks = peakwidths!(pks; relheight) xneg1 = findfirst(x -> x ≈ -1, t) -p = plot(scatter(;y), Layout(; +p = Plot(scatter(;y), Layout(; margin=attr(b=10, l=10, r=10, t=10), xlabel="Indices", showlegend=false, @@ -18,7 +18,7 @@ p = plot(scatter(;y), Layout(; add_hline!(p, pks.heights[1] - pks.proms[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") add_hline!(p, pks.heights[1]; line_dash="dash", line_width=2, line_color="rgba(89,105,112,0.40)") -add_trace!(p, scatter(;x=pks.indices, y=pks.heights, mode=:markers)) +add_trace!(p, scatter(;x=pks.indices.-1, y=pks.heights, mode=:markers)) codefont = attr(; font_family="JuliaMono,SFMono-Regular,Menlo,Consolas,Liberation Mono,DejaVu Sans Mono,monospace", @@ -27,7 +27,7 @@ codefont = attr(; ) relayout!(p, font_size=13, annotations=[ attr(; - x=pks.edges[1][1], ax=pks.edges[1][2], + x=pks.edges[1][1]-1, ax=pks.edges[1][2]-1, y=pks.heights[1] - pks.proms[1]*relheight, ay=pks.heights[1] - pks.proms[1]*relheight, xanchor="left", @@ -64,7 +64,7 @@ relayout!(p, font_size=13, annotations=[ showarrow=false, ), attr(codefont; - x=pks.edges[1][2], + x=pks.edges[1][2]-1, xshift=-20, xanchor="right", y=pks.heights[1] - pks.proms[1]*relheight, From 240b35cf1c756c19f16f6f51164f897512df2a56 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Jul 2024 11:02:50 -0700 Subject: [PATCH 22/25] Update main page slightly --- docs/src/index.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index e16b627..6238093 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,7 +1,7 @@ # Peaks.jl -Peaks is a library to find peaks (i.e. local maxima and minima) and peak characteristics -(e.g. how tall or wide are peaks, etc) in vector (1D) data. +Peaks is a library for finding peaks (i.e. local maxima and minima) and peak characteristics +(e.g. how tall or wide are peaks, etc) in vector (1D) data signals. ## Installation @@ -43,7 +43,7 @@ y = f.(t); p = plot(t, y; label="signal") # hide ``` -To find the peaks in your data you can use the `findmaxima` function: +To find the peaks in your data you can use the [`findmaxima`](@ref) function: ```@repl tutorial indices, heights = findmaxima(y) @@ -57,7 +57,8 @@ plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide ### Peak characteristics -Two commonly desired peak characteristics can be determined using the `peakproms` and `peakwidths` functions: +Two commonly desired peak characteristics can be determined using the [`peakproms`](@ref) +and [`peakwidths`](@ref) functions: ```@repl tutorial indices, proms = peakproms(indices, y) @@ -65,7 +66,7 @@ indices, proms = peakproms(indices, y) indices, widths, edges... = peakwidths(indices, y, proms) ``` -Mutating bang (`'!'`) functions are available for `peakproms` (e.g. `peakproms!`), +Mutating bang (`'!'`) functions are available for `peakproms` (e.g. [`peakproms!`](@ref)), `peakwidths`, and `peakheights`. ### Peaks `NamedTuple` & pipable API @@ -88,7 +89,7 @@ pks = findmaxima(y) |> peakproms!(;strict=false) |> peakwidths!(; max=100) !!! warning "Performance tip" Be aware that the `NamedTuple` functions allocate more memory than the functions with direct/explicit arguments. If maximum performance is needed, mutating functions (e.g. - [`peakproms!`](@ref), etc) and/or the direct/non-`NamedTuple` functions are a better choice. + [`peakproms!`](@ref), etc) and/or the direct, non-`NamedTuple` methods are a better choice. ### Plotting From 4c06c19058aa53aacc5fe28c818b972532de1857 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Jul 2024 12:34:25 -0700 Subject: [PATCH 23/25] More main page improvements; added links to Base Julia docs where relevant --- docs/Manifest.toml | 250 ++++++++++++++++++++++++++------------------- docs/Project.toml | 1 + docs/make.jl | 7 +- docs/src/index.md | 26 +++-- 4 files changed, 166 insertions(+), 118 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index c29f212..d3c9615 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.3" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "0aafd5257cc76f8dd633a6b3c182bcbe3262e5db" +project_hash = "e1151a67dbddb9db9f0ef03c53826c232897325b" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -31,9 +31,9 @@ version = "0.1.0" uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BitFlags]] -git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.8" +version = "0.1.9" [[deps.Blink]] deps = ["Base64", "Distributed", "HTTP", "JSExpr", "JSON", "Lazy", "Logging", "MacroTools", "Mustache", "Mux", "Pkg", "Reexport", "Sockets", "WebIO"] @@ -49,21 +49,21 @@ version = "1.0.8+1" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+1" +version = "1.18.0+2" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.4" +version = "0.7.5" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +git-tree-sha1 = "b5278586822443594ff615963b0c09755771b3e0" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" +version = "3.26.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -85,15 +85,15 @@ version = "0.10.0" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" +version = "0.12.11" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.14.0" +version = "4.15.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -106,9 +106,9 @@ version = "1.1.1+0" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.4.1" +version = "2.4.2" [[deps.Contour]] git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" @@ -145,6 +145,12 @@ version = "1.9.1" deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +[[deps.DocInventories]] +deps = ["CodecZlib", "Downloads", "TOML"] +git-tree-sha1 = "e97cfa8680a39396924dcdca4b7ff1014ed5c499" +uuid = "43dc2714-ed3b-44b5-b226-857eda1aa7de" +version = "1.0.0" + [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" @@ -153,9 +159,21 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "f15a91e6e3919055efa4f206f942a73fedf5dfe6" +git-tree-sha1 = "76deb8c15f37a3853f13ea2226b8f2577652de05" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.4.0" +version = "1.5.0" + +[[deps.DocumenterInterLinks]] +deps = ["CodecZlib", "DocInventories", "Documenter", "DocumenterInventoryWritingBackport", "Markdown", "MarkdownAST", "TOML"] +git-tree-sha1 = "00dceb038f6cb24f4d8d6a9f2feb85bbe58305fd" +uuid = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" +version = "1.0.0" + +[[deps.DocumenterInventoryWritingBackport]] +deps = ["CodecZlib", "Documenter", "TOML"] +git-tree-sha1 = "1b89024e375353961bb98b9818b44a4e38961cc4" +uuid = "195adf08-069f-4855-af3e-8933a2cdae94" +version = "0.1.0" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -176,9 +194,9 @@ version = "0.1.10" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" +version = "2.6.2+0" [[deps.FFMPEG]] deps = ["FFMPEG_jll"] @@ -197,15 +215,15 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" +version = "0.8.5" [[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" +version = "2.13.96+0" [[deps.Format]] git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" @@ -214,15 +232,15 @@ version = "1.3.7" [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" +version = "2.13.2+0" [[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" +version = "1.0.14+0" [[deps.FunctionalCollections]] deps = ["Test"] @@ -231,22 +249,22 @@ uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" version = "0.5.0" [[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "3f74912a156096bd8fdbef211eff66ab446e7297" uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.9+0" +version = "3.4.0+0" [[deps.GR]] -deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] -git-tree-sha1 = "3437ade7073682993e092ca570ad68a2aba26983" +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "629693584cef594c3f6f99e76e7a7ad17e60e8d5" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.73.3" +version = "0.73.7" [[deps.GR_jll]] deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "a96d5c713e6aa28c242b0d25c1347e258d6541ab" +git-tree-sha1 = "a8863b69c2a0859f2c2c87ebdc4c6712e88bdf0d" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.73.3+0" +version = "0.73.7+0" [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] @@ -268,9 +286,9 @@ version = "2.44.0+2" [[deps.Glib_jll]] deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +git-tree-sha1 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.0+0" +version = "2.80.2+0" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -285,9 +303,9 @@ version = "1.0.2" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "2c3ec1f90bb4a8f7beafb0cffea8a4c3f4e636ab" +git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.6" +version = "1.10.8" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -303,9 +321,9 @@ version = "0.2.2" [[deps.IOCapture]] deps = ["Logging", "Random"] -git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.4" +version = "0.2.5" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -347,9 +365,9 @@ version = "0.21.4" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +git-tree-sha1 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.2+0" +version = "3.0.3+0" [[deps.Kaleido_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -358,10 +376,10 @@ uuid = "f7e6163d-2fa5-5f23-b69c-1db539e41963" version = "0.2.1+0" [[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" +version = "3.100.2+0" [[deps.LERC_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -376,10 +394,10 @@ uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" version = "15.0.7+0" [[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" +version = "2.10.2+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -388,9 +406,9 @@ version = "1.3.1" [[deps.Latexify]] deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] -git-tree-sha1 = "e0b5cd21dc1b44ec6e64f351976f961e6f31d6c4" +git-tree-sha1 = "5b0d630f3020b82c0775a51d05895852f8506f50" uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.16.3" +version = "0.16.4" [deps.Latexify.extensions] DataFramesExt = "DataFrames" @@ -457,10 +475,10 @@ uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" version = "1.6.0+0" [[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" +version = "1.49.0+0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -470,9 +488,9 @@ version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4b683b19157282f50bfd5dcaa2efe5295814ea22" +git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.40.0+0" +version = "2.40.1+0" [[deps.Libtiff_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] @@ -482,9 +500,9 @@ version = "4.5.1+1" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "27fd5cc10be85658cacfe11bb81bee216af13eda" +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.40.0+0" +version = "2.40.1+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -492,9 +510,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.27" +version = "0.3.28" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -611,9 +629,9 @@ version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+1" +version = "3.0.14+0" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -656,9 +674,9 @@ version = "1.3.0" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" +version = "0.43.4+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -667,9 +685,9 @@ version = "1.10.0" [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] -git-tree-sha1 = "1f03a2d339f42dca4a4da149c7e15e9b896ad899" +git-tree-sha1 = "6e55c6841ce3411ccb3457ee52fc48cb698d6fb0" uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" -version = "3.1.0" +version = "3.2.0" [[deps.PlotUtils]] deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] @@ -708,10 +726,10 @@ uuid = "f2990250-8cf9-495f-b13a-cce12b45703c" version = "2.2.4" [[deps.Plots]] -deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] -git-tree-sha1 = "442e1e7ac27dd5ff8825c3fa62fbd1e86397974b" +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "082f0c4b70c202c37784ce4bfbc33c9f437685bf" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.40.4" +version = "1.40.5" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -745,9 +763,27 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" [[deps.Qt6Base_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] -git-tree-sha1 = "37b7bb7aabf9a085e0044307e1717436117f2b3b" +git-tree-sha1 = "492601870742dcd38f233b23c3ec629628c1d724" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" -version = "6.5.3+1" +version = "6.7.1+1" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "e5dd466bf2569fe08c91a2cc29c1003f4797ac3b" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.7.1+2" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "1a180aeced866700d4bebc3120ea1451201f16bc" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.7.1+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "729927532d48cf79f49070341e1d918a65aba6b0" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.7.1+1" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -864,10 +900,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "1.0.1" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" +version = "1.12.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -885,9 +921,9 @@ deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TranscodingStreams]] -git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.7" +version = "0.11.1" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -918,9 +954,9 @@ version = "0.4.1" [[deps.Unitful]] deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "3c793be6df9dd77a0cf49d80984ef9ff996948fa" +git-tree-sha1 = "d95fe458f26209c66a187b1114df96fd70839efd" uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.19.0" +version = "1.21.0" [deps.Unitful.extensions] ConstructionBaseUnitfulExt = "ConstructionBase" @@ -932,9 +968,9 @@ version = "1.19.0" [[deps.UnitfulLatexify]] deps = ["LaTeXStrings", "Latexify", "Unitful"] -git-tree-sha1 = "e2d817cc500e960fdbafcf988ac8436ba3208bfd" +git-tree-sha1 = "975c354fcd5f7e1ddcc1f1a23e6e091d99e99bc8" uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" -version = "1.6.3" +version = "1.6.4" [[deps.Unzip]] git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" @@ -979,15 +1015,15 @@ version = "0.6.6" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +git-tree-sha1 = "d9717ce3518dc68a99e6b96300813760d887a01d" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.6+0" +version = "2.13.1+0" [[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.34+0" +version = "1.1.41+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -996,16 +1032,16 @@ uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" version = "5.4.6+0" [[deps.Xorg_libICE_jll]] -deps = ["Libdl", "Pkg"] -git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "326b4fea307b0b39892b3e85fa451692eda8d46c" uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" -version = "1.0.10+1" +version = "1.1.1+0" [[deps.Xorg_libSM_jll]] -deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] -git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "3796722887072218eabafb494a13c963209754ce" uuid = "c834827a-8449-5923-a945-d239c165b7dd" -version = "1.2.3+0" +version = "1.2.4+0" [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] @@ -1032,10 +1068,10 @@ uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" version = "1.1.4+0" [[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" +version = "1.3.6+0" [[deps.Xorg_libXfixes_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] @@ -1062,10 +1098,10 @@ uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" version = "1.5.2+4" [[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" +version = "0.9.11+0" [[deps.Xorg_libpthread_stubs_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1075,9 +1111,9 @@ version = "0.1.1+0" [[deps.Xorg_libxcb_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +git-tree-sha1 = "bcd466676fef0878338c61e655629fa7bbc69d8e" uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.15.0+0" +version = "1.17.0+0" [[deps.Xorg_libxkbfile_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] @@ -1169,10 +1205,10 @@ uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" version = "3.1.1+0" [[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" +version = "3.9.0+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] @@ -1211,9 +1247,9 @@ version = "1.6.43+1" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +git-tree-sha1 = "490376214c4721cdaca654041f635213c6165cb3" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+1" +version = "1.3.7+2" [[deps.mtdev_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] diff --git a/docs/Project.toml b/docs/Project.toml index 6942289..c4f9e04 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" diff --git a/docs/make.jl b/docs/make.jl index a6ac0ca..054c053 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,4 +1,4 @@ -using Documenter +using Documenter, DocumenterInterLinks using Peaks ENV["GKSwstype"] = "100" @@ -22,6 +22,11 @@ makedocs( "API" => "reference.md", ], ], + plugins = [ + InterLinks( + "Base" => "https://docs.julialang.org/en/v1/objects.inv" + ) + ] ) # Documenter can also automatically deploy documentation to gh-pages. diff --git a/docs/src/index.md b/docs/src/index.md index 6238093..070a3f6 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,7 +1,8 @@ # Peaks.jl -Peaks is a library for finding peaks (i.e. local maxima and minima) and peak characteristics -(e.g. how tall or wide are peaks, etc) in vector (1D) data signals. +Peaks.jl is a library for finding [peaks](glossary.md#peak) (i.e. local maxima and minima) +and peak characteristics (e.g. how prominent or wide are peaks, etc) in vector (1D) data +signals. ## Installation @@ -43,13 +44,16 @@ y = f.(t); p = plot(t, y; label="signal") # hide ``` -To find the peaks in your data you can use the [`findmaxima`](@ref) function: +To find the peaks in your data you can use the [`findmaxima`](@ref) function, which returns +a [`NamedTuple`](@extref Base Core.NamedTuple) with fields for each calculated peak +characteristic (indices, heights) and a reference to the data. ```@repl tutorial indices, heights = findmaxima(y) ``` -When the peaks are plotted over the data, we see that all the local maxima have been identified. +When the peaks are plotted over the data, we see that all the local maxima have been +identified. ```@example tutorial plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide @@ -57,8 +61,10 @@ plot!(p, t[indices], heights; seriestype=:scatter, label="maxima") # hide ### Peak characteristics -Two commonly desired peak characteristics can be determined using the [`peakproms`](@ref) -and [`peakwidths`](@ref) functions: +Peaks have various characteristics, including [height](glossary.md#height), +[prominence](glossary.md#prominence), and [width](glossary.md#width). Peaks.jl exports +functions for finding each characteristic: [`peakheights`](@ref), [`peakproms`](@ref), +[`peakwidths`](@ref): ```@repl tutorial indices, proms = peakproms(indices, y) @@ -66,8 +72,8 @@ indices, proms = peakproms(indices, y) indices, widths, edges... = peakwidths(indices, y, proms) ``` -Mutating bang (`'!'`) functions are available for `peakproms` (e.g. [`peakproms!`](@ref)), -`peakwidths`, and `peakheights`. +Mutating bang (`'!'`) functions are available (i.e. [`peakproms!`](@ref), etc.) when +allocations are a concern. ### Peaks `NamedTuple` & pipable API @@ -80,7 +86,7 @@ pks = peakwidths(pks) ``` Mutating functions are also available for the `NamedTuple` functions; the vectors within the -`NamedTuple` are mutated and re-used in the returned tuple. The `NamedTuple` functions can also be piped: +`NamedTuple` are mutated and re-used in the returned tuple. The `NamedTuple` functions can also be [chained/piped](@extref Base.:|>): ```@repl tutorial pks = findmaxima(y) |> peakproms!(;strict=false) |> peakwidths!(; max=100) @@ -93,7 +99,7 @@ pks = findmaxima(y) |> peakproms!(;strict=false) |> peakwidths!(; max=100) ### Plotting -The peaks, prominences, and widths can be visualized all together using the `Plots.jl` +The peaks, prominences, and widths can be visualized all together using a `Plots.jl` recipe `plotpeaks`: ```@example tutorial From ec3fcbd5351f2aea54f2003531540b42cf374cfd Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Jul 2024 16:47:19 -0700 Subject: [PATCH 24/25] Add how-to section --- docs/Manifest.toml | 59 ++++++++++++++++++++++++++++- docs/Project.toml | 1 + docs/src/how-to.md | 94 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 149 insertions(+), 5 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index d3c9615..705e6c0 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "e1151a67dbddb9db9f0ef03c53826c232897325b" +project_hash = "9ca50599c8e7d5c62a0bb6c6823fcb00549d07c1" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -115,11 +115,22 @@ git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" version = "0.6.3" +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + [[deps.DataAPI]] git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" version = "1.16.0" +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" @@ -248,6 +259,10 @@ git-tree-sha1 = "04cb9cfaa6ba5311973994fe3496ddec19b6292a" uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" version = "0.5.0" +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + [[deps.GLFW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] git-tree-sha1 = "3f74912a156096bd8fdbef211eff66ab446e7297" @@ -325,10 +340,28 @@ git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" version = "0.2.5" +[[deps.InlineStrings]] +git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.2" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" @@ -745,6 +778,12 @@ version = "1.40.5" ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" @@ -757,6 +796,12 @@ git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.3" +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.2" + [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -838,6 +883,12 @@ git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" uuid = "6c6a2e73-6563-6170-7368-637461726353" version = "1.2.1" +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "ff11acffdb082493657550959d4feb4b6149e73a" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.5" + [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -883,6 +934,12 @@ git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.34.3" +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" diff --git a/docs/Project.toml b/docs/Project.toml index c4f9e04..29acf3d 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,4 +1,5 @@ [deps] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" diff --git a/docs/src/how-to.md b/docs/src/how-to.md index 2295d4f..8c957df 100644 --- a/docs/src/how-to.md +++ b/docs/src/how-to.md @@ -1,8 +1,94 @@ -# Find peaks +```@setup spacing +using Peaks, Plots, DataFrames; gr() -Lorem ipsum... +using Random +Random.seed!(0xFEED) +``` +Signals often contain peaks that you aren't interested in. This guide will show you how to +filter peaks you don't want. + +## How to filter peaks by peak spacing + +Real data typically has noise that can create lots of closely spaced, unwanted peaks. + +```@example spacing +T = 1/25 +t = 0:T:23 + +multisin(t) = 3sinpi(0.1t) + 2sinpi(0.2t) + sinpi(0.6t) + +y = multisin.(t) .+ 0.1rand(length(t)) + +pks = findmaxima(y) +plotpeaks(t, y; peaks=pks.indices) +``` + +The simplest way to remove those peaks (assuming the signal is already filtered) is by +setting the window `w` argument in `findmaxima` and friends: + +```@example spacing +pks = findmaxima(y, 15) +f = plotpeaks(t, y; peaks=pks.indices) +``` + +If only the peaks circled in blue are wanted, then setting the window `w` too wide won't +work, since there are larger peaks that would become dominant. + +```@example spacing +pks = findmaxima(y, 15) # hide +wpks = peakproms(pks; max=1) # hide +f = plot(t[wpks.indices], wpks.heights; seriestype=:scatter, markershape=:circle, label="", # hide + markersize=10, markercolor=RGBA(1,1,1,0), markerstrokealpha=.1, markerstrokecolor=:blue, # hide + markerstrokewidth=2, z_order=1) # hide +plotpeaks!(f, t, y; peaks=pks.indices) # hide +``` + +## How to filter peaks by peak characteristics + +Every peak-characteristic finding function can optionally filter the newly calculated +characteristics using the keyword arguments `min` and `max`. + +Plotting all the peak characteristics and/or looking at the characteristic values can help +show which characteristics should be filtered to remove all the unwanted peaks. + +```@example spacing +pks = findmaxima(y, 15) # hide +wpks = peakproms(pks; max=1) # hide +f = plot(t[wpks.indices], wpks.heights; seriestype=:scatter, markershape=:circle, label="", # hide + markersize=10, markercolor=RGBA(1,1,1,0), markerstrokealpha=.1, markerstrokecolor=:blue, # hide + markerstrokewidth=2, z_order=1) # hide +plotpeaks!(f, t, y; peaks=pks.indices, prominences=true, widths=true) +``` +```@example spacing +pks = peakproms(pks) |> peakwidths # hide +DataFrame(pks[Not(:data)]) +``` + +Looking at the figure and the characteristic values, we can list the usefulness of each +characteristic for filtering: + + - Peak height? + - There are other peaks around the same height as the peaks we want, so applying a + `min` or `max` height filter would remove peaks we want, or allow peaks we don't + want. + - Peak prominence? + - All the peaks we want have similarly small prominences (<1) and the other peaks + have much larger prominences (>2). This would be a good filtering option, using + `peakproms(pks; max=1)`. + - Peak width? + - The peaks we want have fairly similar widths (~15-25 elements wide), and the other + peaks have larger widths (>40 elements wide). This would be a good filter, using + `peakwidths(pks; max=30)`. + +In this case, filtering by peak prominence would be the better choice, because calculating +peak widths depends on prominences, so filtering by peak prominence would do the job while +avoiding unnecessary work. + +In many cases, the desired peaks aren't very different from many other peaks in any one peak +characteristic. In these situations, it may be necessary to filter multiple times based on +different peak characteristics or different `min`/`max` thresholds. There is also a +[`filterpeaks!`](@ref) function which allows you to give a filter predicate and filter by multiple +characteristics at once. -# Filter peaks -Lorem ipsum... From d103fad91480cdb294e65dfd915b8dcb276e81fe Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Tue, 30 Jul 2024 17:05:52 -0700 Subject: [PATCH 25/25] Update README [skip ci] --- README.md | 57 +++---------------------------------------------------- 1 file changed, 3 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 55d0f53..889ecfa 100644 --- a/README.md +++ b/README.md @@ -8,68 +8,17 @@ [![codecov](https://codecov.io/gh/halleysfifthinc/Peaks.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/halleysfifthinc/Peaks.jl) [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) -Peaks.jl contains peak (local extrema) finding functions for vector data. Contributions welcome. +Peaks.jl contains peak (local extrema) finding functions for vector data. Visit the documentation for a complete introduction, how-to guide, and reference. Contributions welcome. [![signal-with-peaks-prominences-and-widths](docs/src/assets/images/maxima_prom_width.png)](#) -```julia -julia> using Peaks - -julia> t = 0:1/100:1; - -julia> y = 2*sin.(5*t)+3*sin.(10*t)+2*sin.(30*t); - -julia> pks, vals = findmaxima(y) -([8, 26, 48, 70, 88], [4.344867409921723, 5.5693856245725195, 0.42179571038522123, 3.050541716751975, -1.765468536605815]) - -julia> pks, proms = peakproms(pks, y) -([8, 26, 48, 70, 88], [1.9441651653930858, 5.5693856245725195, 2.203426259167901, 6.0957723300230855, -2.195991801053836]) - -julia> pks, widths, leftedge, rightedge = peakwidths(pks, y, proms) -([8, 26, 48, 70, 88], [7.168551512183585, 13.02544712081329, 8.262715646139178, 13.80559202119737, -7.663187146933097], [4.916043956211862, 18.50125024651451, 43.35170982447645, 63.83409366134414, 84.28425741824285], -[12.084595468395447, 31.5266973673278, 51.61442547061563, 77.63968568254151, 91.94744456517594]) - -julia> _, proms = peakproms!(pks, y; minprom=1) -([8, 26, 48, 70, 88], [1.9441651653930858, 5.5693856245725195, 2.203426259167901, 6.0957723300230855, 2.195991801053836]) - -julia> using Plots -julia> plotpeaks(t, y, peaks=pks, prominences=true, widths=true) # see above plot for result -``` - ## Features -- Find peaks (maxima or minima), peak prominence, and peak width - - Filter peaks by peak spacing (window size), prominence, and width - - Compute "Full Width Half Maximum" (FWHM) of discrete or sampled functions using `peakwidths` +- Find peak (maxima or minima) locations, height, prominence, and width + - Filter peaks by peak spacing (window size), height, prominence, and width (including "Full Width Half Maximum (FWHM)") - Fully supports `NaN`/`missing` with optional tolerance using keyword arg `strict`: - Conventional handling/propagation of `NaN`/`missing` when `strict = true` (the default) - ```julia - julia> argmaxima([missing,2,0,1,1,0]) # equivalent to [2,0,1,1,0] - 1-element Vector{Int64}: - 4 - - julia> peakproms([2,4], [NaN,2,0,1,1,0]) - ([2, 4], [NaN, 1.0]) - - julia> peakwidths([2,4], [NaN,2,0,1,1,0], [2,1]) - ([2, 4], [NaN, 2.0], [NaN, 3.5], [2.5, 5.5]) - ``` - Reasonable alternatives when `strict = false` - ```julia - julia> argmaxima([missing,2,0,1,1,0]; strict=false) - 2-element Vector{Int64}: - 2 - 4 - - julia> peakproms([2,4], [NaN,2,0,1,1,0]; strict=false) - ([2, 4], [2.0, 1.0]) - - julia> peakwidths([2,4], [NaN,2,0,1,1,0], [2,1]; strict=false) - ([2, 4], [1.5, 2.0], [1.0, 3.5], [2.5, 5.5]) - ``` ## Related