diff --git a/docs/_quarto.yml b/docs/_quarto.yml index d014135..54a27fd 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -25,8 +25,13 @@ website: style: floating align: left contents: - - index.qmd + - section: Home + contents: + - index.qmd - auto: usage + - section: Dev Notes + contents: + - auto: dev # - usage/getting_started.qmd # - usage/all_arguments.qmd # - usage/pythonic_use.ipynb @@ -82,34 +87,48 @@ quartodoc: - fave_corpus - fave_subcorpora - title: Vowel Measurements - desc: Vowel Measurements + #kind: page options: dynamic: true - contents: - - name: VowelMeasurement - members: - - to_tracks_df - - to_param_df - - to_point_df + contents: + - name: measurements.vowel_measurement + children: linked + - VowelMeasurement + - VowelClass + - VowelClassCollection + - SpeakerCollection - - name: VowelClass - members: - - to_tracks_df - - to_param_df - - to_point_df + # - title: Vowel Measurements + # desc: Vowel Measurements + # options: + # dynamic: true + # contents: + # - name: VowelMeasurement + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - - name: VowelClassCollection - members: - - to_tracks_df - - to_param_df - - to_point_df + # - name: VowelClass + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - - name: SpeakerCollection - members: - - to_tracks_df - - to_param_df - - to_point_df + # - name: VowelClassCollection + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df + # - name: SpeakerCollection + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df + - title: Calculations + contents: + - measurements.calcs.mahalanobis - title: Optimization desc: Functions for optimizing formant measurements contents: diff --git a/docs/dev_plan/assets/ay.wav b/docs/dev/assets/ay.wav similarity index 100% rename from docs/dev_plan/assets/ay.wav rename to docs/dev/assets/ay.wav diff --git a/docs/dev_plan/assets/corpus/josef-fruehwald_speaker.TextGrid b/docs/dev/assets/corpus/josef-fruehwald_speaker.TextGrid similarity index 100% rename from docs/dev_plan/assets/corpus/josef-fruehwald_speaker.TextGrid rename to docs/dev/assets/corpus/josef-fruehwald_speaker.TextGrid diff --git a/docs/dev_plan/assets/corpus/josef-fruehwald_speaker.wav b/docs/dev/assets/corpus/josef-fruehwald_speaker.wav similarity index 100% rename from docs/dev_plan/assets/corpus/josef-fruehwald_speaker.wav rename to docs/dev/assets/corpus/josef-fruehwald_speaker.wav diff --git a/docs/dev_plan/index.qmd b/docs/dev/index.qmd similarity index 100% rename from docs/dev_plan/index.qmd rename to docs/dev/index.qmd diff --git a/docs/dev_plan/new-fave-approach.qmd b/docs/dev/new-fave-approach.qmd similarity index 100% rename from docs/dev_plan/new-fave-approach.qmd rename to docs/dev/new-fave-approach.qmd diff --git a/docs/dev/variable_names.qmd b/docs/dev/variable_names.qmd new file mode 100644 index 0000000..803f894 --- /dev/null +++ b/docs/dev/variable_names.qmd @@ -0,0 +1,53 @@ +--- +title: Variable Naming Conventions +--- + +## Property naming descriptors + +### From Descriptors + +- `cand`: candidate tracks. + - Returns + - list of [](`fasttrackpy.OneTrack`)s + - a [](`numpy.array`) of concatenated results from [](`fasttrackpy.OneTrack`)s +- `winner`: The winner track + - Returns + - A single [](`fasttrackpy.OneTrack`) + - a [](`numpy.array`) of concatenated results from winner [](`fasttrackpy.OneTrack`)s + +### Value Descriptors + +- `param`: The DCT parameters +- `maxformant`: The maximum formant +- `error`: The smoothing error term +- `bparam`: The formant bandwidths parameters + +### Summary Descriptors + +- `mean`: A mean +- `cov`: A covariance matrix +- `icov`: An inverse covariance matrix + + +### Derived Values Descriptors + +- `mahal`: Mahalanobis distance +- `logprob`: The log probability + +### Scope Descriptors + +- `vm`: Vowel Measurement +- `vclass`: Vowel Class +- `speaker`: Speaker +- `corpus`: Corpus + +### Scope Subdivision Descriptors + +- `global`: Global +- `byvclass`: By VowelClass + +## Property Naming Structure + +- `source`_`value`_`derived`_`scope`_`subdivision` +- `source`_`value`_`summary` +- `source`_`value` diff --git a/docs/usage/index.qmd b/docs/usage/index.qmd new file mode 100644 index 0000000..198f514 --- /dev/null +++ b/docs/usage/index.qmd @@ -0,0 +1,3 @@ +--- +title: Usage +--- \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 6e2eb03..62745a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -270,14 +270,14 @@ css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "bokeh" -version = "3.4.1" +version = "3.4.2" description = "Interactive plots and applications in the browser from Python" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "bokeh-3.4.1-py3-none-any.whl", hash = "sha256:1e3c502a0a8205338fc74dadbfa321f8a0965441b39501e36796a47b4017b642"}, - {file = "bokeh-3.4.1.tar.gz", hash = "sha256:d824961e4265367b0750ce58b07e564ad0b83ca64b335521cd3421e9b9f10d89"}, + {file = "bokeh-3.4.2-py3-none-any.whl", hash = "sha256:931a43ee59dbf1720383ab904f8205e126b85561aac55592415b800c96f1b0eb"}, + {file = "bokeh-3.4.2.tar.gz", hash = "sha256:a16d5cc0abb93d2d270d70fc35851f3e1b9208814a985a4678e0ba5ef2d9cd42"}, ] [package.dependencies] @@ -638,64 +638,64 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.5.3" +version = "7.5.4" description = "Code coverage measurement for Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, - {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, - {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, - {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, - {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, - {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, - {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, - {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, - {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, - {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, - {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, - {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, - {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, - {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.extras] @@ -719,34 +719,34 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "debugpy" -version = "1.8.1" +version = "1.8.2" description = "An implementation of the Debug Adapter Protocol for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, - {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, - {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, - {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, - {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, - {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, - {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, - {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, - {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, - {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, - {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, - {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, - {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, - {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, - {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, - {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, - {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, - {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, - {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, - {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, - {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, - {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, + {file = "debugpy-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7ee2e1afbf44b138c005e4380097d92532e1001580853a7cb40ed84e0ef1c3d2"}, + {file = "debugpy-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8c3f7c53130a070f0fc845a0f2cee8ed88d220d6b04595897b66605df1edd6"}, + {file = "debugpy-1.8.2-cp310-cp310-win32.whl", hash = "sha256:f179af1e1bd4c88b0b9f0fa153569b24f6b6f3de33f94703336363ae62f4bf47"}, + {file = "debugpy-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:0600faef1d0b8d0e85c816b8bb0cb90ed94fc611f308d5fde28cb8b3d2ff0fe3"}, + {file = "debugpy-1.8.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8a13417ccd5978a642e91fb79b871baded925d4fadd4dfafec1928196292aa0a"}, + {file = "debugpy-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acdf39855f65c48ac9667b2801234fc64d46778021efac2de7e50907ab90c634"}, + {file = "debugpy-1.8.2-cp311-cp311-win32.whl", hash = "sha256:2cbd4d9a2fc5e7f583ff9bf11f3b7d78dfda8401e8bb6856ad1ed190be4281ad"}, + {file = "debugpy-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:d3408fddd76414034c02880e891ea434e9a9cf3a69842098ef92f6e809d09afa"}, + {file = "debugpy-1.8.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:5d3ccd39e4021f2eb86b8d748a96c766058b39443c1f18b2dc52c10ac2757835"}, + {file = "debugpy-1.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62658aefe289598680193ff655ff3940e2a601765259b123dc7f89c0239b8cd3"}, + {file = "debugpy-1.8.2-cp312-cp312-win32.whl", hash = "sha256:bd11fe35d6fd3431f1546d94121322c0ac572e1bfb1f6be0e9b8655fb4ea941e"}, + {file = "debugpy-1.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:15bc2f4b0f5e99bf86c162c91a74c0631dbd9cef3c6a1d1329c946586255e859"}, + {file = "debugpy-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5a019d4574afedc6ead1daa22736c530712465c0c4cd44f820d803d937531b2d"}, + {file = "debugpy-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f062d6877d2e45b112c0bbade9a17aac507445fd638922b1a5434df34aed02"}, + {file = "debugpy-1.8.2-cp38-cp38-win32.whl", hash = "sha256:c78ba1680f1015c0ca7115671fe347b28b446081dada3fedf54138f44e4ba031"}, + {file = "debugpy-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf327316ae0c0e7dd81eb92d24ba8b5e88bb4d1b585b5c0d32929274a66a5210"}, + {file = "debugpy-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1523bc551e28e15147815d1397afc150ac99dbd3a8e64641d53425dba57b0ff9"}, + {file = "debugpy-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e24ccb0cd6f8bfaec68d577cb49e9c680621c336f347479b3fce060ba7c09ec1"}, + {file = "debugpy-1.8.2-cp39-cp39-win32.whl", hash = "sha256:7f8d57a98c5a486c5c7824bc0b9f2f11189d08d73635c326abef268f83950326"}, + {file = "debugpy-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:16c8dcab02617b75697a0a925a62943e26a0330da076e2a10437edd9f0bf3755"}, + {file = "debugpy-1.8.2-py2.py3-none-any.whl", hash = "sha256:16e16df3a98a35c63c3ab1e4d19be4cbc7fdda92d9ddc059294f18910928e0ca"}, + {file = "debugpy-1.8.2.zip", hash = "sha256:95378ed08ed2089221896b9b3a8d021e642c24edc8fef20e5d4342ca8be65c00"}, ] [[package]] @@ -806,14 +806,14 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastjsonschema" -version = "2.19.1" +version = "2.20.0" description = "Fastest Python implementation of JSON schema" category = "dev" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, ] [package.extras] @@ -821,14 +821,14 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "fasttrackpy" -version = "0.4.7" +version = "0.4.8" description = "A python implementation of FastTrack" category = "main" optional = false python-versions = "<3.13,>=3.10" files = [ - {file = "fasttrackpy-0.4.7-py3-none-any.whl", hash = "sha256:ed5043e18455851abc76ad2a451e2774321b12dacfb60fc1cdda6d828a33771c"}, - {file = "fasttrackpy-0.4.7.tar.gz", hash = "sha256:ff6aa89a05cfbfaf806cac59873c263fce371f4b6d119a3fbb3936413c1c5838"}, + {file = "fasttrackpy-0.4.8-py3-none-any.whl", hash = "sha256:95de91df09237c7defdac5b209d875c5c3e4b3aa703ecffe2b1e8604932e09ad"}, + {file = "fasttrackpy-0.4.8.tar.gz", hash = "sha256:2b54cdc338a80b905cae2c299ed4f3bda48587621d6a4dbecccf6068eb558652"}, ] [package.dependencies] @@ -964,14 +964,14 @@ files = [ [[package]] name = "griffe" -version = "0.45.2" +version = "0.47.0" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "griffe-0.45.2-py3-none-any.whl", hash = "sha256:297ec8530d0c68e5b98ff86fb588ebc3aa3559bb5dc21f3caea8d9542a350133"}, - {file = "griffe-0.45.2.tar.gz", hash = "sha256:83ce7dcaafd8cb7f43cbf1a455155015a1eb624b1ffd93249e5e1c4a22b2fdb2"}, + {file = "griffe-0.47.0-py3-none-any.whl", hash = "sha256:07a2fd6a8c3d21d0bbb0decf701d62042ccc8a576645c7f8799fe1f10de2b2de"}, + {file = "griffe-0.47.0.tar.gz", hash = "sha256:95119a440a3c932b13293538bdbc405bee4c36428547553dc6b327e7e7d35e5a"}, ] [package.dependencies] @@ -991,41 +991,29 @@ files = [ [[package]] name = "holoviews" -version = "1.18.3" -description = "Stop plotting your data - annotate your data and let it visualize itself." +version = "1.19.0" +description = "A high-level plotting API for the PyData ecosystem built on HoloViews." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "holoviews-1.18.3-py2.py3-none-any.whl", hash = "sha256:b94b96560b64a84c07e89115aaf9b226e6009684800ec84d3c88cbad122c0c46"}, - {file = "holoviews-1.18.3.tar.gz", hash = "sha256:578e30e89d72754f97a83ebe08198fec8e87cc7e49b25b9f31ec393f939ca500"}, + {file = "holoviews-1.19.0-py3-none-any.whl", hash = "sha256:a74b26dc3285b4f8b801e23f0e23b4ac93ab4ec162ea76c69ae585fff627a21b"}, + {file = "holoviews-1.19.0.tar.gz", hash = "sha256:cab1522f75a9b46377f9364b675befd79812e220059714470a58e21475d531ba"}, ] [package.dependencies] +bokeh = ">=3.1" colorcet = "*" -numpy = ">=1.0" +numpy = ">=1.21" packaging = "*" -pandas = ">=0.20.0" +pandas = ">=1.3" panel = ">=1.0" -param = ">=1.12.0,<3.0" -pyviz-comms = ">=0.7.4" +param = ">=2.0,<3.0" +pyviz-comms = ">=2.1" [package.extras] -all = ["bokeh (>=3.1)", "cftime", "codecov", "contourpy", "cudf", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "graphviz", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "myst-nb (<1)", "nbconvert", "nbsite (>=0.8.4,<0.9.0)", "nbval", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "playwright", "plotly (>=4.0)", "pooch", "pre-commit", "pyarrow", "pytest", "pytest-cov", "pytest-github-actions-annotate-failures", "pytest-playwright", "pytest-rerunfailures", "pytest-xdist", "ruff", "scikit-image", "scipy", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -build = ["param (>=1.7.0)", "pyct (>=0.4.4)", "setuptools (>=30.3.0)"] -doc = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "graphviz", "ipython (>=5.4.0)", "matplotlib (>=3)", "myst-nb (<1)", "nbsite (>=0.8.4,<0.9.0)", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "selenium", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -examples = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ipython (>=5.4.0)", "matplotlib (>=3)", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -examples-tests = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbval", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -lint = ["pre-commit", "ruff"] -notebook = ["ipython (>=5.4.0)", "notebook"] -recommended = ["bokeh (>=3.1)", "ipython (>=5.4.0)", "matplotlib (>=3)", "notebook"] -tests = ["bokeh (>=3.1)", "cftime", "contourpy", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "networkx", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "xarray (>=0.10.4)"] -tests-ci = ["codecov", "pytest-github-actions-annotate-failures"] -tests-core = ["bokeh (>=3.1)", "contourpy", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist"] -tests-gpu = ["bokeh (>=3.1)", "cftime", "contourpy", "cudf", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "networkx", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "xarray (>=0.10.4)"] -tests-nb = ["nbval"] -ui = ["playwright", "pytest-playwright"] -unit-tests = ["bokeh (>=3.1)", "cftime", "contourpy", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pre-commit", "pyarrow", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "ruff", "scikit-image", "scipy", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] +recommended = ["matplotlib (>=3)", "plotly (>=4.0)"] +tests = ["pytest", "pytest-rerunfailures"] [[package]] name = "httpcore" @@ -1120,23 +1108,23 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.1.0" +version = "8.0.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" @@ -1339,14 +1327,14 @@ files = [ [[package]] name = "jsonpointer" -version = "2.4" +version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] [[package]] @@ -1584,14 +1572,14 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.2.1" +version = "4.2.3" description = "JupyterLab computational environment" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.2.1-py3-none-any.whl", hash = "sha256:6ac6e3827b3c890e6e549800e8a4f4aaea6a69321e2240007902aa7a0c56a8e4"}, - {file = "jupyterlab-4.2.1.tar.gz", hash = "sha256:a10fb71085a6900820c62d43324005046402ffc8f0fde696103e37238a839507"}, + {file = "jupyterlab-4.2.3-py3-none-any.whl", hash = "sha256:0b59d11808e84bb84105c73364edfa867dd475492429ab34ea388a52f2e2e596"}, + {file = "jupyterlab-4.2.3.tar.gz", hash = "sha256:df6e46969ea51d66815167f23d92f105423b7f1f06fa604d4f44aeb018c82c7b"}, ] [package.dependencies] @@ -1605,6 +1593,7 @@ jupyter-server = ">=2.4.0,<3" jupyterlab-server = ">=2.27.1,<3" notebook-shim = ">=0.2" packaging = "*" +setuptools = ">=40.1.0" tornado = ">=6.2.0" traitlets = "*" @@ -2120,14 +2109,14 @@ files = [ [[package]] name = "notebook" -version = "7.2.0" +version = "7.2.1" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "notebook-7.2.0-py3-none-any.whl", hash = "sha256:b4752d7407d6c8872fc505df0f00d3cae46e8efb033b822adacbaa3f1f3ce8f5"}, - {file = "notebook-7.2.0.tar.gz", hash = "sha256:34a2ba4b08ad5d19ec930db7484fb79746a1784be9e1a5f8218f9af8656a141f"}, + {file = "notebook-7.2.1-py3-none-any.whl", hash = "sha256:f45489a3995746f2195a137e0773e2130960b51c9ac3ce257dbc2705aab3a6ca"}, + {file = "notebook-7.2.1.tar.gz", hash = "sha256:4287b6da59740b32173d01d641f763d292f49c30e7a51b89c46ba8473126341e"}, ] [package.dependencies] @@ -2242,14 +2231,14 @@ files = [ [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -2374,25 +2363,25 @@ ui = ["jupyter-server", "playwright", "pytest-playwright", "tomli"] [[package]] name = "param" -version = "2.1.0" +version = "2.1.1" description = "Make your Python code clearer and more reliable by declaring Parameters." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "param-2.1.0-py3-none-any.whl", hash = "sha256:f31d3745d227347d29b5868c4e4e3077df07463889b91d3bb28e634fde211e1c"}, - {file = "param-2.1.0.tar.gz", hash = "sha256:a7b30b08b547e2b78b02aeba6ed34e3c6a638f8e4824a76a96ffa2d7cf57e71f"}, + {file = "param-2.1.1-py3-none-any.whl", hash = "sha256:81066d040526fbaa44b6419f3e92348fa8856ea44c8d3915e9245937ddabe2d6"}, + {file = "param-2.1.1.tar.gz", hash = "sha256:3b1da14abafa75bfd908572378a58696826b3719a723bc31b40ffff2e9a5c852"}, ] [package.extras] -all = ["param[doc]", "param[lint]", "param[tests-full]"] -doc = ["nbsite (==0.8.4)", "param[examples]", "sphinx-remove-toctrees"] +all = ["aiohttp", "cloudpickle", "coverage[toml]", "flake8", "gmpy", "ipython", "jsonschema", "nbsite (==0.8.4)", "nbval", "nest-asyncio", "numpy", "odfpy", "openpyxl", "pandas", "panel", "pre-commit", "pyarrow", "pytest", "pytest-asyncio", "pytest-xdist", "sphinx-remove-toctrees", "tables", "xlrd"] +doc = ["aiohttp", "nbsite (==0.8.4)", "pandas", "panel", "sphinx-remove-toctrees"] examples = ["aiohttp", "pandas", "panel"] lint = ["flake8", "pre-commit"] tests = ["coverage[toml]", "pytest", "pytest-asyncio"] tests-deser = ["odfpy", "openpyxl", "pyarrow", "tables", "xlrd"] -tests-examples = ["nbval", "param[examples]", "pytest (<8.1)", "pytest-asyncio", "pytest-xdist"] -tests-full = ["cloudpickle", "gmpy", "ipython", "jsonschema", "nest-asyncio", "numpy", "pandas", "param[tests-deser]", "param[tests-examples]", "param[tests]"] +tests-examples = ["aiohttp", "nbval", "pandas", "panel", "pytest", "pytest-asyncio", "pytest-xdist"] +tests-full = ["aiohttp", "cloudpickle", "coverage[toml]", "gmpy", "ipython", "jsonschema", "nbval", "nest-asyncio", "numpy", "odfpy", "openpyxl", "pandas", "panel", "pyarrow", "pytest", "pytest-asyncio", "pytest-xdist", "tables", "xlrd"] [[package]] name = "parso" @@ -2547,14 +2536,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "plum-dispatch" -version = "2.4.1" +version = "2.4.2" description = "Multiple dispatch in Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "plum_dispatch-2.4.1-py3-none-any.whl", hash = "sha256:015b35c3081706718282da7ab248eec34b0f87cfc4aaa7fbc98ad9c34ee84a94"}, - {file = "plum_dispatch-2.4.1.tar.gz", hash = "sha256:23914fefc8ca79148c6acf04651f4916510a62e13f105bb7dc7c64de8587fe93"}, + {file = "plum_dispatch-2.4.2-py3-none-any.whl", hash = "sha256:72f35f6b44443a979c73b67b8a7245623d6f14f64b68ff912ba0adbb4cd50288"}, + {file = "plum_dispatch-2.4.2.tar.gz", hash = "sha256:248f73b2ca79ff5c1d307fb7c28e78a306c8f8c10776b71b3f0788aeeeae99ac"}, ] [package.dependencies] @@ -2719,14 +2708,14 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.46" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.46-py3-none-any.whl", hash = "sha256:45abe60a8300f3c618b23c16c4bb98c6fc80af8ce8b17c7ae92db48db3ee63c1"}, - {file = "prompt_toolkit-3.0.46.tar.gz", hash = "sha256:869c50d682152336e23c4db7f74667639b5047494202ffe7670817053fd57795"}, + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, ] [package.dependencies] @@ -2734,28 +2723,29 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.8" +version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, ] [package.extras] @@ -2851,14 +2841,14 @@ files = [ [[package]] name = "pydantic" -version = "2.7.3" +version = "2.7.4" description = "Data validation using Python type hints" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.3-py3-none-any.whl", hash = "sha256:ea91b002777bf643bb20dd717c028ec43216b24a6001a280f83877fd2655d0b4"}, - {file = "pydantic-2.7.3.tar.gz", hash = "sha256:c46c76a40bb1296728d7a8b99aa73dd70a48c3510111ff290034f860c99c419e"}, + {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, + {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, ] [package.dependencies] @@ -3362,14 +3352,14 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] [[package]] name = "quartodoc" -version = "0.7.3" +version = "0.7.5" description = "Generate API documentation with Quarto." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "quartodoc-0.7.3-py3-none-any.whl", hash = "sha256:697a0d919d5bd4ff169b67bbd1a201b2f0699ea3de6ea4bb0cd97a884edefead"}, - {file = "quartodoc-0.7.3.tar.gz", hash = "sha256:6d8c7266ede844cebc9980c29956701f4b65e882daaa860a0f1391c539913f20"}, + {file = "quartodoc-0.7.5-py3-none-any.whl", hash = "sha256:293c45c4b1b10936d562921ff32f7a5d3e24bde250c638f0033c0c38ecbc9a92"}, + {file = "quartodoc-0.7.5.tar.gz", hash = "sha256:328d40374fa4397cab67a820cdac3dca47a90eb0a33328ccf50c8f41507ef125"}, ] [package.dependencies] @@ -3380,6 +3370,7 @@ importlib-resources = ">=5.10.2" plum-dispatch = {version = ">2.0.0", markers = "python_version >= \"3.10\""} pydantic = "*" pyyaml = "*" +requests = "*" sphobjinv = ">=2.3.1" tabulate = ">=0.9.0" typing-extensions = ">=4.4.0" @@ -3583,46 +3574,46 @@ files = [ [[package]] name = "scipy" -version = "1.13.1" +version = "1.14.0" description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, -] - -[package.dependencies] -numpy = ">=1.22.4,<2.3" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, + {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, + {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, + {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, + {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, + {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, + {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, + {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, +] + +[package.dependencies] +numpy = ">=1.23.5,<2.3" + +[package.extras] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "send2trash" @@ -3641,6 +3632,22 @@ nativelib = ["pyobjc-framework-Cocoa", "pywin32"] objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] +[[package]] +name = "setuptools" +version = "70.1.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "six" version = "1.16.0" @@ -3772,23 +3779,23 @@ test = ["pytest", "ruff"] [[package]] name = "tornado" -version = "6.4" +version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "dev" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, ] [[package]] @@ -3842,14 +3849,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.1" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, - {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -3896,14 +3903,14 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -3971,19 +3978,19 @@ files = [ [[package]] name = "webcolors" -version = "1.13" +version = "24.6.0" description = "A library for working with the color formats defined by HTML and CSS." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, - {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, + {file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"}, + {file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"}, ] [package.extras] docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["pytest", "pytest-cov"] +tests = ["coverage[toml]"] [[package]] name = "webencodings" @@ -4039,14 +4046,14 @@ files = [ [[package]] name = "xyzservices" -version = "2024.4.0" +version = "2024.6.0" description = "Source of XYZ tiles providers" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "xyzservices-2024.4.0-py3-none-any.whl", hash = "sha256:b83e48c5b776c9969fffcfff57b03d02b1b1cd6607a9d9c4e7f568b01ef47f4c"}, - {file = "xyzservices-2024.4.0.tar.gz", hash = "sha256:6a04f11487a6fb77d92a98984cd107fbd9157fd5e65f929add9c3d6e604ee88c"}, + {file = "xyzservices-2024.6.0-py3-none-any.whl", hash = "sha256:fecb2508f0f2b71c819aecf5df2c03cef001c56a4b49302e640f3b34710d25e4"}, + {file = "xyzservices-2024.6.0.tar.gz", hash = "sha256:58c1bdab4257d2551b9ef91cd48571f77b7c4d2bc45bf5e3c05ac97b3a4d7282"}, ] [[package]] @@ -4068,4 +4075,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "8dfc857869aa848a81242cb1a192b2138571a4a17078a3cc8c0d69967d0afe68" +content-hash = "8b58df8e65cb17ef83f3c76a9513f237bdc5b73c7815eb6672743d1b9cc488c9" diff --git a/pyproject.toml b/pyproject.toml index 04461a0..5d90d5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ repository = "https://github.com/Forced-Alignment-and-Vowel-Extraction/new-fave" [tool.poetry.dependencies] python = ">=3.11,<3.12" aligned-textgrid = "^0.6.7" -fasttrackpy = "^0.4.7" +fasttrackpy = "^0.4.8" numpy = "^1.26.4" tqdm = "^4.66.2" fave-recode = "^0.3.0" @@ -26,6 +26,7 @@ python-magic = {version = "^0.4.27", markers = "sys_platform != 'win32'"} python-magic-bin = {version = "^0.4.14", markers = "sys_platform == 'win32'"} scipy = "^1.13.1" cloudpickle = "^3.0.0" +nptyping = "^2.5.0" [tool.poetry.group.docs.dependencies] diff --git a/src/new_fave/__init__.py b/src/new_fave/__init__.py index 6826c77..39243a4 100644 --- a/src/new_fave/__init__.py +++ b/src/new_fave/__init__.py @@ -8,6 +8,8 @@ from new_fave.patterns.fave_subcorpora import fave_subcorpora from new_fave.patterns.writers import write_data, pickle_speakers, unpickle_speakers +from importlib.metadata import version + __all__ = [ "VowelMeasurement", "VowelClass", diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py new file mode 100644 index 0000000..af2d596 --- /dev/null +++ b/src/new_fave/measurements/calcs.py @@ -0,0 +1,129 @@ +import numpy as np +import nptyping as npt +from nptyping import NDArray, Shape, Float +from typing import Any +import scipy.stats as stats +import warnings +import functools + +def mahalanobis( + params:NDArray[Shape['Dim, Cand'], Float], + param_means:NDArray[Shape['Dim, 1'], Float], + inv_cov:NDArray[Shape['Dim, Dim'], Float] + )->NDArray[Shape["Cand"], Float]: + """ + Calculates the Mahalanobis distance. + + Args: + params (NDArray[Shape['Dim, Cand'], Float]): + The parameters for which the Mahalanobis distance is to be calculated. + param_means (NDArray[Shape['Dim, 1'], Float]): + The mean of the distribution. + inv_cov (NDArray[Shape['Dim, Dim'], Float]): + The inverse of the covariance matrix of the distribution. + + Returns: + (NDArray[Shape["Cand"], Float]): + The Mahalanobis distance of each parameter from the distribution. + """ + + x_mu = params - param_means + left = np.dot(x_mu.T, inv_cov) + mahal = np.dot(left, x_mu) + return mahal.diagonal() + +def mahal_log_prob( + mahals: NDArray[Shape["Cand"], Float], + params: NDArray[Shape["*, *, ..."], Float] + ) -> NDArray[Shape["Cand"], Float]: + """ + + Args: + mahals (NDArray[Shape["Cand"], Float]): + The Mahalanobis distances. + params (NDArray[Shape["*, *, ..."], Float]): + The parameters across which the mahalanobis + distance was calculated + + Returns: + (NDArray[Shape["Cand"], Float]): + The log probability + """ + df = np.prod(params.shape[0:-1]) + log_prob = stats.chi2.logsf( + mahals, + df = df + ) + if np.isfinite(log_prob).mean() < 0.5: + log_prob = np.zeros(shape = log_prob.shape) + return log_prob + + +def param_to_cov( + params:NDArray[Shape["*, *, ..."], Float] +) -> NDArray[Shape["X, X"], Float]: + """ + Calculates the covariance matrix of the given parameters. + + Args: + params (NDArray[Shape["*, *, ..."], Float]): + The parameters for which the covariance matrix is to be calculated. + + Returns: + (NDArray[Shape["X, X"], Float]): + The covariance matrix of the parameters. + """ + N = params.shape[-1] + square_params = params.reshape(-1, N) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + param_cov = np.cov(square_params) + + return param_cov + +def cov_to_icov( + cov_mat: NDArray[Shape["X, X"], Float] +) -> NDArray[Shape["X, X"], Float]: + """ + Calculates the inverse covariance matrix of the given covariance matrix. + + Args: + cov_mat (NDArray[Shape["X, X"], Float]): + The covariance matrix for which the inverse is to be calculated. + + Returns: + (NDArray[Shape["X, X"], Float]): + The inverse covariance matrix of the given covariance matrix. + """ + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + params_icov = np.linalg.inv(cov_mat) + except: + params_icov = np.array([ + [np.nan] * cov_mat.size + ]).reshape( + cov_mat.shape[0], + cov_mat.shape[1] + ) + + return params_icov + +def clear_cached_properties(obj:object) -> None: + """Clear the cache of any property in an object + + Args: + obj (object): Any object. + """ + clses = obj.__class__.mro() + to_clear = [] + + to_clear += [ + k + for cls in clses + for k, v in vars(cls).items() + if isinstance(v, functools.cached_property) + ] + for var in to_clear: + if var in obj.__dict__: + del obj.__dict__[var] diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index a0d81ff..c4a7add 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -1,9 +1,54 @@ +""" +This module contains classes to represent vowel measurements and their +aggregations at different levels. + +```{mermaid} +classDiagram +direction LR + +class VowelMeasurement~list~{ + .vowel_class +} +class VowelClass~list~{ + .vowel_system +} +class VowelClassCollection~dict~{ + .corpus +} +class SpeakerCollection~dict~ + +SpeakerCollection --o VowelClassCollection +VowelClassCollection --o VowelClass +VowelClass --o VowelMeasurement +``` + +When a class has a numpy array for an attribute, its +type is annotated using [nptyping](https://pypi.org/project/nptyping/) +to provide the expected dimensions. For example: + +``` +cand_param (NDArray[Shape["Param, Formant, Cand"], Float]) +``` + +This indicates that `cand_param` is a three dimensional array. +The first dimension is `"Param"` (the number of DCT parameters) +long, the second is `"Formant"` (the number of formants) long, +and the third is `"Cand"` (the number of candidates) long. +""" +import fasttrackpy from fasttrackpy import CandidateTracks, OneTrack from aligned_textgrid import AlignedTextGrid, SequenceInterval from fave_measurement_point.heuristic import Heuristic from fave_measurement_point.formants import FormantArray + from new_fave.utils.textgrid import get_textgrid from new_fave.speaker.speaker import Speaker +from new_fave.measurements.calcs import mahalanobis, \ + mahal_log_prob,\ + param_to_cov,\ + cov_to_icov,\ + clear_cached_properties + from collections import defaultdict import numpy as np from typing import Literal @@ -15,6 +60,9 @@ from collections.abc import Sequence, Iterable from dataclasses import dataclass, field +from nptyping import NDArray, Shape, Float + +from functools import lru_cache, cached_property NCPU = cpu_count() @@ -27,7 +75,112 @@ def blank_list(): return [] EMPTY_LIST = blank_list() + +class StatPropertyMixins: + + @cached_property + def winner_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: + params = np.array( + [ + x.parameters + for x in self.winners + ] + ).T + return params + + @cached_property + def winner_bparam( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: + params = np.array([ + x.bandwidth_parameters + for x in self.winners + ]).T + return params + + @cached_property + def winner_maxformant( + self + ) -> NDArray[Shape["1, N"], Float]: + max_formants = np.array([[ + x.maximum_formant + for x in self.winners + ]]) + + return max_formants + + @cached_property + def winner_param_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: + N = len(self.winners) + winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + return winner_mean + + @cached_property + def winner_bparam_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: + N = len(self.winners) + winner_mean = self.winner_bparam.reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + return winner_mean + pass + + @cached_property + def winner_param_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + param_cov = param_to_cov(self.winner_param) + return param_cov + + @cached_property + def winner_param_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + params_icov = cov_to_icov(self.winner_param_cov) + return params_icov + @cached_property + def winner_bparam_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + param_cov = param_to_cov(self.winner_bparam) + return param_cov + + @cached_property + def winner_bparam_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + params_icov = cov_to_icov(self.winner_bparam_cov) + return params_icov + + + @cached_property + def winner_maxformant_mean( + self + ) -> float: + return self.winner_maxformant.mean() + + @cached_property + def winner_maxformant_cov( + self + ) -> NDArray[Shape["1, 1"], Float]: + cov = param_to_cov(self.winner_maxformant) + cov = cov.reshape(1,1) + return cov + + @cached_property + def winner_maxformant_icov( + self + ) -> NDArray[Shape["1, 1"], Float]: + icov = cov_to_icov(self.winner_maxformant_cov) + return icov + + @dataclass class VowelMeasurement(Sequence): """ A class used to represent a vowel measurement. @@ -81,37 +234,37 @@ class VowelMeasurement(Sequence): The number of optimization iterations the vowel measurement has been through. - winner: fasttrackpy.OneTrack The winning formant track winner_index (int): The index of the winning formant track - - error_log_prob (np.array): - A conversion of the log-mean-squared-error to a - log-probabilities, based on an empirical cumulative - density function. - cand_errors (np.array): - A numpy array of the log-mean-squared-errors - for each candidate track. - cand_mahals (np.array): - The mahalanobis distance across DCT parameters - for each candidate from the vowel system - distribution. - cand_mahal_log_prob (np.array): - A conversion of `cand_mahals` to log-probabilies. - cand_max_formants (np.array): - A numpy array of the maximum formants for - this VowelMeasurement - cand_params (np.array): - A numpy array of the candidate track - DCT parameters. - max_formant_log_prob (np.array): - A conversion of `max_formant_mahal` to log-probabilities. - max_formant_mahal (np.array): - The mahalanobis distance of each - maximum formant to the speaker's entire - distribution. + + cand_param (NDArray[Shape["Param, Formant, Cand"], Float]): + A array of the candidate DCT parameters. + cand_maxformant (NDArray[Shape["1, Cand"], Float]): + An array of the candidate maximum formants. + cand_error (NDArray[Shape["Cand"], Float]): + An array of the candidate smoothing error. + + cand_error_logprob_vm (NDArray[Shape["Cand"], Float]): + Conversion of the smooth error to log probabilities. The candidate with + the lowest error = log(1), and the candidate with the largest + error = log(0). + cand_param_(mahal/logprob)_speaker_byvclass (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to the VowelClass for this speaker. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class` + cand_param_(mahal/logprob)_speaker_global (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to *all* vowel measurements for this speaker. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class.vowel_system` + cand_param_(mahal/logprob)_corpus_byvclass (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to this vowel class across all speakers. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class.vowel_system.corpus` point_measure (pl.DataFrame): A polars dataframe of the point measurement for this vowel. @@ -153,7 +306,7 @@ def __repr__(self): return out @property - def label(self): + def label(self) -> str: if (not self._label) or (self._label != self.interval.label): for cand in self.candidates: cand.label = self.interval.label @@ -168,7 +321,7 @@ def label(self, x:str): @property - def formant_array(self): + def formant_array(self) -> FormantArray: return FormantArray( self.winner.smoothed_formants, self.winner.time_domain, @@ -181,11 +334,11 @@ def vowel_class(self): return self._vclass @vowel_class.setter - def vowel_class(self, vclass): + def vowel_class(self, vclass: 'VowelClass'): self._vclass = vclass @property - def winner(self): + def winner(self)->OneTrack: return self._winner @winner.setter @@ -197,28 +350,32 @@ def winner(self, idx): self._optimized += 1 @property - def optimized(self): + def optimized(self)->int: return self._optimized @property - def winner_index(self): + def winner_index(self)->int: return self.candidates.index(self.winner) @property - def expanded_formants(self): + def expanded_formants( + self + )->NDArray[Shape['N, Formant, Cand'], Float]: if self._expanded_formants is not None: return self._expanded_formants self._expanded_formants = np.apply_along_axis( lambda x: idct(x.T, n = 20, orthogonalize=True, norm = "forward"), 0, - self.cand_params + self.cand_param ) return self._expanded_formants @property - def cand_params(self): + def cand_param( + self + ) -> NDArray[Shape["Param, Formant, Cand"], Float]: params = np.array( [ x.parameters @@ -227,16 +384,31 @@ def cand_params(self): ).T return params + + @property + def cand_bparam( + self + ) -> NDArray[Shape["Param, Formant, Cand"], Float]: + params = np.array([ + x.bandwidth_parameters + for x in self.candidates + ]) + + return params @property - def cand_max_formants(self): + def cand_maxformant( + self + ) -> NDArray[Shape["1, Cand"], Float]: return np.array([[ c.maximum_formant for c in self.candidates ]]) @property - def cand_errors(self): + def cand_error( + self + ) -> NDArray[Shape["Cand"], Float]: with warnings.catch_warnings(): warnings.simplefilter("ignore") return np.array([ @@ -245,84 +417,166 @@ def cand_errors(self): ]) @property - def cand_mahals(self): + def cand_param_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: N = len(self.candidates) - square_params = self.cand_params.reshape(-1, N) - inv_covmat = self.vowel_class.vowel_system.params_icov - param_means = self.vowel_class.vowel_system.params_means - x_mu = square_params - param_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + square_params = self.cand_param.reshape(-1, N) + mahal = mahalanobis( + square_params, + self.vowel_class.vowel_system.winner_param_mean, + self.vowel_class.vowel_system.winner_param_icov + ) + return mahal @property - def cand_mahal_log_prob(self): - winner_shape = self.cand_params.shape - df = winner_shape[0] * winner_shape[1] - log_prob = stats.chi2.logsf( - self.cand_mahals, - df = df + def cand_param_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_param_mahal_speaker_global, + self.cand_param ) - if np.isfinite(log_prob).mean() < 0.5: - log_prob = np.zeros(shape = log_prob.shape) return log_prob @property - def cand_vclass_mahals(self): + def cand_param_mahal_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: N = len(self.candidates) - square_params = self.cand_params.reshape(-1, N) - inv_covmat = self.vowel_class.params_icov - param_means = self.vowel_class.params_means - x_mu = square_params - param_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + square_params = self.cand_param.reshape(-1, N) + inv_covmat = self.vowel_class.winner_param_icov + param_means = self.vowel_class.winner_param_mean + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal @property - def cand_vclass_mahal_log_prob(self): - df = self.cand_params.size - log_prob = stats.chi2.logsf( - self.cand_vclass_mahals, - df = df + def cand_param_logprob_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_param_mahal_speaker_byvclass, + self.cand_param ) - if np.isfinite(log_prob).mean() < 0.5: - log_prob = np.zeros(shape = log_prob.shape) if len(self.vowel_class) < 10: log_prob = np.zeros(shape = log_prob.shape) - return log_prob + return log_prob - @property - def max_formant_mahal(self): - inv_covmat = self.vowel_class.vowel_system.max_formant_icov - maximum_formant_means = self.vowel_class.vowel_system.maximum_formant_means - x_mu = self.cand_max_formants - maximum_formant_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + + @property + def cand_param_mahal_corpus_byvowel( + self + ) -> NDArray[Shape["Cand"], Float]: + + N = len(self.candidates) + square_params = self.cand_param.reshape(-1, N) + inv_covmat = self\ + .vowel_class\ + .vowel_system\ + .corpus\ + .winner_param_icov[self.label] + param_means = self\ + .vowel_class\ + .vowel_system\ + .corpus\ + .winner_param_mean[self.label] + + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal + + @property + def cand_param_logprob_corpus_byvowel( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_param_mahal_corpus_byvowel, + self.cand_param + ) + return log_prob + + @property + def cand_bparam_mahal_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + N = len(self.candidates) + square_params = self.cand_bparam.reshape(-1, N) + inv_covmat = self.vowel_class.winner_bparam_icov + param_means = self.vowel_class.winner_bparam_mean + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal @property - def max_formant_log_prob(self): - log_prob = stats.chi2.logsf( - self.max_formant_mahal, - df = 1 + def cand_bparam_logprob_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_bparam_mahal_speaker_byvclass, + self.cand_bparam ) + if len(self.vowel_class) < 10: + log_prob = np.zeros(shape = log_prob.shape) + return log_prob - if np.isfinite(log_prob).mean() < 0.5: + @property + def cand_bparam_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + N = len(self.candidates) + square_params = self.cand_bparam.reshape(-1, N) + inv_covmat = self.vowel_class.vowel_system.winner_bparam_icov + param_means = self.vowel_class.vowel_system.winner_bparam_mean + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal + + @property + def cand_bparam_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_bparam_mahal_speaker_global, + self.cand_bparam + ) + if len(self.vowel_class) < 10: log_prob = np.zeros(shape = log_prob.shape) + return log_prob + + + + @property + def cand_maxformant_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + inv_covmat = self.vowel_class.vowel_system.winner_maxformant_icov + maximum_formant_means = self.vowel_class.vowel_system.winner_maxformant_mean + mahal = mahalanobis(self.cand_maxformant, maximum_formant_means, inv_covmat) + return mahal + + @property + def cand_maxformant_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_maxformant_mahal_speaker_global, + self.cand_maxformant + ) return log_prob @property - def error_log_prob(self): + def cand_error_logprob_vm( + self + ) -> NDArray[Shape["Cand"], Float]: with warnings.catch_warnings(): warnings.simplefilter("ignore") - err_norm = self.cand_errors - np.nanmin(self.cand_errors) + err_norm = self.cand_error - np.nanmin(self.cand_error) err_surv = 1 - (err_norm/np.nanmax(err_norm)) err_log_prob = np.log(err_surv) return err_log_prob @property - def point_measure(self): + def point_measure( + self + ) -> pl.DataFrame: winner_slice = self.heuristic.apply_heuristic( self.label, formants=self.formant_array @@ -344,8 +598,10 @@ def point_measure(self): return pl.DataFrame(point_dict) - @property - def vm_context(self): + @cached_property + def vm_context( + self + ) -> pl.DataFrame: optimized = self.optimized id = self.winner.id word = self.winner.interval.within.label @@ -451,7 +707,7 @@ def to_point_df(self) -> pl.DataFrame: return(df) @dataclass -class VowelClass(Sequence): +class VowelClass(Sequence, StatPropertyMixins): """A class used to represent a vowel class. ## Intended Usage @@ -465,7 +721,6 @@ class VowelClass(Sequence): vowel_measurements = [VowelMeasurement(t) for t in fasttrack_tracks] vowel_class = VowelClass("ay", vowel_measurements) ``` - Args: label (str): @@ -474,28 +729,32 @@ class VowelClass(Sequence): A list of VowelMeasurements Attributes: - label (str): + label (str): label of the vowel class - tracks (list): - A list of `VowelMeasurement`s + tracks (list): + A list of VowelMeasurements vowel_system (VowelClassCollection): - A the containing vowel system - winners (list[fasttrackpy.OneTrack]): - A list of winner OneTracks from - the vowel class - winner_params (np.array): - An `np.array` of winner DCT parameters - from the vowel class. + The containing vowel system + winners (list[OneTrack]): + A list of winner [](`~fasttrackpy.OneTrack`)s from the vowel class + winner_param (NDArray[Shape["Param, Formant, N"], Float]): + An np.array of winner DCT parameters from the vowel class + winner_param_mean (NDArray[Shape["ParamFormant, 1"], Float]): + Mean of winner DCT parameters + winner_param_cov (NDArray[Shape["ParamFormant, ParamFormant"], Float]): + Covariance of winner DCT parameters + winner_param_icov (NDArray[Shape["ParamFormant, ParamFormant"], Float]): + Inverse covariance of winner DCT parameters """ label: str = field(default="") tracks: list[VowelMeasurement] = field(default_factory= lambda : []) def __post_init__(self): super().__init__() self._winners = [x.winner for x in self.tracks] - self._winner_params = None - self._params_means = None - self._params_cov = None - self._params_icov = None + self._winner_param = None + self._winner_param_mean = None + self._winner_param_cov = None + self._winner_param_icov = None for t in self.tracks: t.vowel_class = self @@ -515,78 +774,19 @@ def __repr__(self): return out def _reset_winners(self): - self._winner_params = None - self._params_means = None - self._params_cov = None - self._params_icov = None + clear_cached_properties(self) @property def vowel_system(self): return self._vowel_system @vowel_system.setter - def vowel_system(self, vowel_system): + def vowel_system(self, vowel_system: 'VowelClassCollection'): self._vowel_system = vowel_system - @property + @cached_property def winners(self): - self._winners = [x.winner for x in self.tracks] - return self._winners - - @property - def winner_params(self): - if not self._winner_params is None: - return self._winner_params - - params = np.array( - [ - x.parameters - for x in self.winners - ] - ).T - - return params - - @property - def params_means(self): - if self._params_means is not None: - return self._params_means - N = len(self.winners) - winner_mean = self.winner_params.reshape(-1, N).mean(axis = 1) - winner_mean = winner_mean[:, np.newaxis] - self._params_means = winner_mean - return winner_mean - - @property - def params_covs(self): - if self._params_cov is not None: - return self._params_cov - N = len(self.winners) - square_param = self.winner_params.reshape(-1, N) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - param_cov = np.cov(square_param) - return param_cov - - @property - def params_icov(self): - if self._params_icov is not None: - return self._params_icov - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - try: - params_icov = np.linalg.inv(self.params_covs) - self._params_icov = params_icov - return params_icov - except: - params_icov = np.array([ - [np.nan] * self.params_covs.size - ]).reshape( - self.params_covs.shape[0], - self.params_covs.shape[1] - ) - self._params_icov = params_icov - return params_icov + return [x.winner for x in self.tracks] def to_param_df( self, @@ -632,7 +832,7 @@ def to_point_df(self) -> pl.DataFrame: return df -class VowelClassCollection(defaultdict): +class VowelClassCollection(defaultdict, StatPropertyMixins): """ A class for an entire vowel system. @@ -650,39 +850,39 @@ class VowelClassCollection(defaultdict): A list of `VowelMeasurement`s. Attributes: - maximum_formant_cov (np.array): - The covariance matrix for the winners maximum formant - across the entire vowel system - maximum_formant_means (np.array): - The mean maximum formant for the winners - across the entire vowel system - max_formant_icov (np.array): - The inverse covariance matrix for the winners maximum formant - across the entire vowel system - params_covs (np.array): - The covariance matrix for the winners' DCT - parameters. - params_icov (np.array): - The inverse covariance matrix for the winners' - DCT parameters. - params_means (np.array): - An `np.array` for the winners' DCT parameters - in the entire vowel system. - vowel_measurements (list[VowelMeasurement]): - A list of all vowel measurements in the - vowel system - winner_formants (np.array): - An `np.array` for the formants - for the winners in the entire vowel system. - winner_params (np.array): - An `np.array` of DCT parameters for - the winners in entire vowel system. - winners (list[fasttrackpy.OneTrack]): - The winning `fasttrackpy.OneTrack` for - the entire vowel system - winners_maximum_formant (np.array): - An `np.array` of the maximum formants - for the winners in the entire vowel system + winners (list[OneTrack]): + All winner tracks from the entire vowel system. + vowel_measurements (list[VowelMeasurement]): + All `VowelMeasurement` objects within this vowel system + textgrid (AlignedTextGrid): + The `AlignedTextGrid` associated with this vowel system. + winner_expanded_formants (NDArray[Shape["20, FormantN"], Float]): + A cached property that returns the expanded formants for the winners. + + + winner_param (NDArray[Shape["Param, Formant, N"], Float]): + An array of all parameters from all winners across the + vowel system. + winner_maxformant (NDArray[Shape["1, N"], Float]): + An array of the maximum formants of all winners across + the vowel system + + winner_param_mean (NDArray[Shape["1, FormantParam"], Float]): + The mean of all DCT parameters across all formants for the winners + in this vowel system. + winner_param_cov (NDArray[Shape["FormantParam, FormantParam"], Float]): + The covariance of all parameters across all formants for the winners + in this vowel system + winner_param_icov (NDArray[Shape["FormantParam, FormantParam"], Float]): + The inverse of `winner_param_cov`. + + winner_maxformant_mean (float): + The mean maximum formant across all winners in this vowel system. + winner_maxformant_cov (NDArray[Shape["1, 1"], Float]): + The covariance of the maximum formant across all winners + in this vowel system. + winner_maxformant_icov (NDArray[Shape["1, 1"], Float]): + The inverse of `winner_maxformant_cov` """ def __init__(self, track_list:list[VowelMeasurement] = EMPTY_LIST): super().__init__(blank) @@ -692,22 +892,15 @@ def __init__(self, track_list:list[VowelMeasurement] = EMPTY_LIST): self._make_tracks_dict() self._dictify() self._vowel_system() - self._params_means = None - self._params_icov = None - self._maximum_formant_means = None - self._max_formant_icov = None - self._textgrid = None self._file_name = None + self._corpus = None def __setitem__(self, __key, __value) -> None: super().__setitem__(__key, __value) def _reset_winners(self): - self._params_means = None - self._params_icov = None - self._maximum_formant_means = None - self._max_formant_icov = None + clear_cached_properties(self) def _make_tracks_dict(self): for v in self.track_list: @@ -724,8 +917,21 @@ def _vowel_system(self): for v in self.tracks_dict: self[v].vowel_system = self + def _reset_winners(self): + clear_cached_properties(self) + @property - def winners(self): + def corpus(self): + return self._corpus + + @corpus.setter + def corpus(self, corp): + self._corpus = corp + + @cached_property + def winners( + self + ) -> list[OneTrack]: return [ x for vc in self.values() @@ -733,53 +939,35 @@ def winners(self): ] @property - def vowel_measurements(self): + def vowel_measurements( + self + ) -> list[VowelMeasurement]: return [ x for vc in self.values() for x in vc.tracks ] - @property - def textgrid(self): - if self._textgrid: - return self._textgrid - - self._textgrid = get_textgrid(self.vowel_measurements[0].interval) - return self._textgrid + @cached_property + def textgrid( + self + ) -> AlignedTextGrid: + return get_textgrid(self.vowel_measurements[0].interval) @property - def file_name(self): + def file_name( + self + ) -> str: if self._file_name: return self._file_name self._file_name = self.vowel_measurements[0].winner.file_name return self._file_name - - @property - def winner_params(self): - params = np.array( - [ - x.parameters - for x in self.winners - ] - ).T - - return params - @property - def winner_formants(self): - formants = np.hstack( - [ - x.formants - for x in self.winners - ] - ) - - return formants - - @property - def winner_expanded_formants(self): + @cached_property + def winner_expanded_formants( + self + ) -> NDArray[Shape["20, FormantN"], Float]: formants = np.hstack( [ x.expanded_formants[:, :, x.winner_index] @@ -788,84 +976,8 @@ def winner_expanded_formants(self): ) return formants - - @property - def winners_maximum_formant(self): - max_formants = np.array([[ - x.maximum_formant - for x in self.winners - ]]) - - return max_formants - - - @property - def params_means(self): - if self._params_means is not None: - return self._params_means - N = len(self.winners) - winner_mean = self.winner_params.reshape(-1, N).mean(axis = 1) - winner_mean = winner_mean[:, np.newaxis] - self._params_means = winner_mean - return winner_mean - - @property - def params_covs(self): - N = len(self.winners) - square_param = self.winner_params.reshape(-1, N) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - param_cov = np.cov(square_param) - return param_cov - - @property - def params_icov(self): - if self._params_icov is not None: - return self._params_icov - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - try: - params_icov = np.linalg.inv(self.params_covs) - self._params_icov = params_icov - return params_icov - except: - params_icov = np.array([ - [np.nan] * self.params_covs.size - ]).reshape( - self.params_covs.shape[0], - self.params_covs.shape[1] - ) - self._params_icov = params_icov - return params_icov - - @property - def maximum_formant_means(self): - if self._maximum_formant_means is not None: - return self._maximum_formant_means - self._maximum_formant_means = self.winners_maximum_formant.mean() - return self.winners_maximum_formant.mean() - - @property - def maximum_formant_cov(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - cov = np.cov(self.winners_maximum_formant).reshape(1,1) - return cov - - @property - def max_formant_icov(self): - if self._max_formant_icov is not None: - return self._max_formant_icov - - try: - icov = np.linalg.inv(self.maximum_formant_cov) - self._max_formant_icov = icov - return icov - except: - self._max_formant_icov = np.array([[np.nan]]) - return np.array([[np.nan]]) - def to_tracks_df(self): + def to_tracks_df(self)->pl.DataFrame: """Return a DataFrame of the formant tracks Returns: @@ -894,7 +1006,7 @@ def to_param_df( return df - def to_point_df(self): + def to_point_df(self) -> pl.DataFrame: """Return a DataFrame of point measurements Returns: @@ -907,7 +1019,7 @@ def to_point_df(self): return df -class SpeakerCollection(defaultdict): +class SpeakerCollection(defaultdict, StatPropertyMixins): """ A class to represent the vowel system of all speakers in a TextGrid. @@ -925,15 +1037,19 @@ class SpeakerCollection(defaultdict): track_list (list[VowelMeasurement]): A list of `VowelMeasurement`s. """ + __hash__ = object.__hash__ + def __init__(self, track_list:list[VowelMeasurement] = []): self.track_list = track_list self.speakers_dict = defaultdict(blank_list) self._make_tracks_dict() self._dictify() self._speaker = None + self._associate_corpus() def __setitem__(self, __key, __value) -> None: super().__setitem__(__key, __value) + self._associate_corpus() def _make_tracks_dict(self): for v in self.track_list: @@ -945,6 +1061,88 @@ def _dictify(self): self[fs] = VowelClassCollection( self.speakers_dict[fs] ) + + def _associate_corpus(self): + for speaker in self.values(): + speaker.corpus = self + + def _reset_winners(self): + clear_cached_properties(self) + + @cached_property + def vowel_dict( + self + ) -> defaultdict[str, list[VowelMeasurement]]: + out = defaultdict(blank_list) + for speaker in self.values(): + for vowel in speaker: + out[vowel] += speaker[vowel] + return out + + @cached_property + def vowel_winners( + self + ) -> defaultdict[str, list[OneTrack]]: + out = defaultdict(blank_list) + for vowel in self.vowel_dict: + out[vowel] += [x.winner for x in self.vowel_dict[vowel]] + + return out + + @cached_property + def winner_param( + self + ) -> defaultdict[str, NDArray[Shape["Param, Formant, N"], Float]]: + out = defaultdict(blank_list) + for vowel in self.vowel_winners: + params = np.array( + [ + x.parameters + for x in self.vowel_winners[vowel] + ] + ).T + + out[vowel] = params + return out + + @cached_property + def winner_param_mean( + self + ) -> defaultdict[str, NDArray[Shape["FormantParam, 1"], Float]]: + out = defaultdict(lambda: np.array([])) + + for vowel in self.winner_param: + N = len(self.vowel_dict[vowel]) + winner_mean = self.winner_param[vowel].reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + out[vowel] = winner_mean + return out + + + @property + def winner_param_cov( + self + )->defaultdict[str, NDArray[Shape["FormantParam, FormantParam"], Float]]: + out = defaultdict(lambda: np.array([])) + + for vowel in self.winner_param: + param_cov = param_to_cov(self.winner_param[vowel]) + out[vowel] = param_cov + + return out + + @cached_property + def winner_param_icov( + self + )->defaultdict[str, NDArray[Shape["FormantParam, FormantParam"], Float]]: + out = defaultdict(lambda: np.array([])) + + for vowel in self.winner_param_cov: + params_icov = cov_to_icov(self.winner_param_cov[vowel]) + out[vowel] = params_icov + + return out + @property def speaker(self): diff --git a/src/new_fave/optimize/optimize.py b/src/new_fave/optimize/optimize.py index 3b1afce..7f71c7a 100644 --- a/src/new_fave/optimize/optimize.py +++ b/src/new_fave/optimize/optimize.py @@ -8,9 +8,26 @@ def run_optimize( vowel_system: VowelClassCollection, - optim_params = ["cand_mahal", "vclass_mahal", "max_formant"], + optim_params: list[ + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ], max_iter = 10 ): + + """ Repeatedly run optimization until either `max_iter` is reached, or the difference between two iterations becomes small. @@ -18,9 +35,8 @@ def run_optimize( Args: vowel_system (VowelClassCollection): The vowel space to be optimized - optim_params (list, optional): - The parameters to use for optimization. - Defaults to ["cand_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. max_iter (int, optional): The maximum number of iterations to run. Defaults to 10. @@ -51,8 +67,21 @@ def run_optimize( def optimize_vowel_measures( vowel_measurements: list[VowelMeasurement], optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "max_formant"] - ] = ["cand_mahal", "vclass_mahal", "max_formant"] + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ] ): """ Optimize a list of VowelMeasurements. @@ -60,8 +89,8 @@ def optimize_vowel_measures( Args: vowel_measurements (list[VowelMeasurement]): The list of vowel measurements to optimize - optim_params (list[Literal["cand_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. """ new_winners = [ @@ -80,35 +109,58 @@ def optimize_vowel_measures( def optimize_one_measure( vowel_measurement: VowelMeasurement, optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "max_formant"] - ] = ["cand_mahal", "vclass_mahal", "max_formant"] + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ] )->int: """ + Optimize a single vowel measurement + This function optimizes a given vowel measurement based on the - specified optimization parameters. The optimization parameters - can include 'cand_mahal' and 'max_formant'. + specified optimization parameters. Args: vowel_measurement (VowelMeasurement): The VowelMeasurement to optimize - optim_params (list[Literal["cand_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. Returns: - (int): The index of the winning candidate. + int: _description_ """ prob_dict = dict() - if "cand_mahal" in optim_params: - prob_dict["cand_mahal"] = vowel_measurement.cand_mahal_log_prob + if "param_speaker_global" in optim_params: + prob_dict["param_speaker_global"] = vowel_measurement.cand_param_logprob_speaker_global + + if "param_speaker_byvclass" in optim_params: + prob_dict["param_speaker_byvclass"] = vowel_measurement.cand_param_logprob_speaker_byvclass + + if "bparam_speaker_global" in optim_params: + prob_dict["bparam_speaker_global"] = vowel_measurement.cand_bparam_logprob_speaker_global + + if "bparam_speaker_byvclass" in optim_params: + prob_dict["bparam_speaker_byvclass"] = vowel_measurement.cand_bparam_logprob_speaker_byvclass - if "vclass_mahal" in optim_params: - prob_dict["vclass_mahal"] = vowel_measurement.cand_vclass_mahal_log_prob + if "param_corpus_byvclass" in optim_params: + prob_dict["param_corpus_byvclass"] = vowel_measurement.cand_param_logprob_corpus_byvowel - if "max_formant" in optim_params: - prob_dict["max_formant"] = vowel_measurement.max_formant_log_prob + if "maxformant_speaker_global" in optim_params: + prob_dict["maxformant_speaker_global"] = vowel_measurement.cand_maxformant_logprob_speaker_global - joint_prob = vowel_measurement.error_log_prob + joint_prob = vowel_measurement.cand_error_logprob_vm for dim in optim_params: joint_prob += prob_dict[dim] diff --git a/tests/test_measurements/test_calcs.py b/tests/test_measurements/test_calcs.py new file mode 100644 index 0000000..638345c --- /dev/null +++ b/tests/test_measurements/test_calcs.py @@ -0,0 +1,59 @@ +from new_fave.measurements.calcs import mahalanobis, \ + mahal_log_prob,\ + param_to_cov,\ + cov_to_icov, \ + clear_cached_properties + +import numpy as np +from functools import cached_property + +NParam = 15 +NToken = 100 + +PARAM = np.random.random(NParam * NToken).reshape(NParam, NToken) + + +def test_param_to_cov(): + cov_mat = param_to_cov(PARAM) + assert cov_mat.shape == (NParam, NParam) + +def test_cov_to_icov(): + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + assert icov_mat.shape == (NParam, NParam) + +def test_mahalanobis(): + mean = PARAM.mean(axis=1) + mean = mean[:, np.newaxis] + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + distances = mahalanobis(PARAM, mean, icov_mat) + assert distances.shape == (NToken,) + +def test_mahalanobis_logprob(): + mean = PARAM.mean(axis=1) + mean = mean[:, np.newaxis] + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + distances = mahalanobis(PARAM, mean, icov_mat) + log_prob = mahal_log_prob(distances, PARAM) + assert log_prob.shape == (NToken,) + assert np.all(log_prob < 0) + +def test_clear_cache(): + class MyClass: + @cached_property + def name(self): + return "Cache Test" + + foo = MyClass() + + assert not "name" in foo.__dict__ + + emitted = foo.name + + assert "name" in foo.__dict__ + + clear_cached_properties(foo) + + assert not "name" in foo.__dict__ diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index a855699..df1cf16 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -2,6 +2,7 @@ from fasttrackpy import CandidateTracks, OneTrack, process_corpus from pathlib import Path from functools import reduce +from copy import copy import polars as pl import numpy as np @@ -86,12 +87,14 @@ def test_winner_reset(): speaker = speakers[first_speaker] speaker_vms = speaker.vowel_measurements - initial_mean = speaker.maximum_formant_means + initial_mean = copy(speaker.winner_maxformant_mean) + assert "winner_maxformant_mean" in speaker.__dict__ initial_index = speaker_vms[0].winner_index - speaker_vms[0].winner = initial_index+1 + speaker_vms[0].winner = initial_index+2 + assert not "winner_maxformant_mean" in speaker.__dict__ - new_mean = speaker.maximum_formant_means + new_mean = speaker.winner_maxformant_mean assert ~np.isclose(initial_mean, new_mean) @@ -143,7 +146,7 @@ def test_winner_param(): ] for vc in all_vcs: - params = vc.winner_params + params = vc.winner_param expected_shape = (5, NFORMANT, len(vc)) for s1, s2 in zip(params.shape, expected_shape): assert s1 == s2 @@ -153,16 +156,20 @@ def test_probs(): """ Test that the length of log probs is equal to the number of steps + And all log probs are finite and <= 0 """ - for vm in vms: - cand_mahal_log_prob = vm.cand_mahal_log_prob - max_formant_log_prob = vm.max_formant_log_prob - error_log_prob = vm.error_log_prob - - assert cand_mahal_log_prob.size == NSTEP - assert max_formant_log_prob.size == NSTEP - assert error_log_prob.size == NSTEP + target_properties = [ + x + for x in VowelMeasurement.__dict__.keys() + if "logprob" in x + ] + for vm in vms: + for target in target_properties: + log_prob = getattr(vm, target) + assert log_prob.size == NSTEP, f"{target}" + assert np.all(~np.isnan(log_prob)) + assert np.all(log_prob <= 0) ## output tests def test_vm_context(): diff --git a/tests/test_optimize/test_optimize.py b/tests/test_optimize/test_optimize.py index ebec20a..a9a6b09 100644 --- a/tests/test_optimize/test_optimize.py +++ b/tests/test_optimize/test_optimize.py @@ -8,10 +8,12 @@ def __init__(self, len, winner_idx): log_prob = -np.ones(len)*2 log_prob[winner_idx] = -0.5 - self.cand_mahal_log_prob = log_prob - self.cand_vclass_mahal_log_prob = log_prob - self.max_formant_log_prob = log_prob - self.error_log_prob = log_prob + self.cand_param_logprob_speaker_global = log_prob + self.cand_param_logprob_speaker_byvclass = log_prob + self.cand_maxformant_logprob_speaker_global = log_prob + self.cand_bparam_logprob_speaker_global = log_prob + self.cand_bparam_logprob_speaker_byvclass = log_prob + self.cand_error_logprob_vm = log_prob self.winner = None class MockVowelClassCollection: