First analysis
This commit is contained in:
parent
f9df8e9fe6
commit
a0cb298e8f
15 changed files with 3508 additions and 1227 deletions
210
pixi.lock
generated
210
pixi.lock
generated
|
|
@ -258,7 +258,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/31/4a/72dc383d1a0d14f1d453e334e3461e229762edb1bf3f75b3ab977e9386ed/arro3_core-0.6.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/31/4a/72dc383d1a0d14f1d453e334e3461e229762edb1bf3f75b3ab977e9386ed/arro3_core-0.6.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/1b/df/2a5a1306dc1699b51b02c1c38c55f3564a8c4f84087c23c61e7e7ae37dfa/arro3_io-0.6.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/1b/df/2a5a1306dc1699b51b02c1c38c55f3564a8c4f84087c23c61e7e7ae37dfa/arro3_io-0.6.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/c3/1c/f06ad85180e7dd9855aa5ede901bfc2be858d7bee17d4e978a14c0ecec14/astropy-7.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/c3/1c/f06ad85180e7dd9855aa5ede901bfc2be858d7bee17d4e978a14c0ecec14/astropy-7.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/4e/67/6af8b422c04dec79c908cf60fdcd4725c3c112b2a058087c4ff58284a142/astropy_iers_data-0.2026.2.9.0.50.33-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/49/94/dcdac330d2c26776956555610ef584147584acc6b060e451aa65dd9142d9/astropy_iers_data-0.2026.2.16.0.48.25-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/2d/1b/37d8a28965907d23eeba8bce56272932ee01176d192cefdf19a4a0b53c00/autogluon_common-1.5.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/2d/1b/37d8a28965907d23eeba8bce56272932ee01176d192cefdf19a4a0b53c00/autogluon_common-1.5.0-py3-none-any.whl
|
||||||
|
|
@ -270,6 +270,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl
|
||||||
|
- pypi: https://files.pythonhosted.org/packages/0b/c7/b2e7aca3de8981f4ecb6ab1e0334c3c4a512e5e9898b57b3d8734b086da7/biopython-1.86-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/bf/51/472e7b36a6bedb5242a9757e7486f702c3619eff76e256735d0c8b1679c6/blis-1.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/bf/51/472e7b36a6bedb5242a9757e7486f702c3619eff76e256735d0c8b1679c6/blis-1.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/f6/a8/877f306720bc114c612579c5af36bcb359026b83d051226945499b306b1a/bokeh-3.8.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/f6/a8/877f306720bc114c612579c5af36bcb359026b83d051226945499b306b1a/bokeh-3.8.2-py3-none-any.whl
|
||||||
|
|
@ -281,7 +282,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/7e/50/fc9680058e63161f2f63165b84c957a0df1415431104c408e8104a3a18ef/branca-0.8.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/7e/50/fc9680058e63161f2f63165b84c957a0df1415431104c408e8104a3a18ef/branca-0.8.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/19/0d/669d4bbeb36b87ba504409d85c68ec297e6f434ea6525424f8aa5f14abac/cartopy-0.25.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/19/0d/669d4bbeb36b87ba504409d85c68ec297e6f434ea6525424f8aa5f14abac/cartopy-0.25.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/9e/96/d32b941a501ab566a16358d68b6eb4e4acc373fab3c3c4d7d9e649f7b4bb/catalogue-2.0.10-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/9e/96/d32b941a501ab566a16358d68b6eb4e4acc373fab3c3c4d7d9e649f7b4bb/catalogue-2.0.10-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/0c/4b/d04e067df4401902cb2249df241bc1502bf90e990c6a3da5f82ba7de60fa/catboost-1.2.8-cp313-cp313-manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/e7/07/893b53c492fc2c827d0c6de5fe4d47cd016c57596b1f7318cc14cf57121f/catboost-1.2.9-cp313-cp313-manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/4f/f4/4a65460d5cb6784128019fd707a87993f378db25e796eba01400a0903f62/cdsapi-0.7.7-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/4f/f4/4a65460d5cb6784128019fd707a87993f378db25e796eba01400a0903f62/cdsapi-0.7.7-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/ce/0c/00c768197bbcba5835f22b69c2611cb422c0f8a9dc93af62e26d14584b29/cdshealpix-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/ce/0c/00c768197bbcba5835f22b69c2611cb422c0f8a9dc93af62e26d14584b29/cdshealpix-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl
|
||||||
|
|
@ -302,7 +303,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/6b/e7/237155ae19a9023de7e30ec64e5d99a9431a567407ac21170a046d22a5a3/cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/6b/e7/237155ae19a9023de7e30ec64e5d99a9431a567407ac21170a046d22a5a3/cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/fa/25/0be9314cd72fe2ee2ef89ceb1f438bc156428a12177d684040456eee4a56/cupy_xarray-0.1.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/fa/25/0be9314cd72fe2ee2ef89ceb1f438bc156428a12177d684040456eee4a56/cupy_xarray-0.1.4-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/2b/03/f906829bcfcbb945f19d6a64240ffb66a31d69ca5533e95882f0efc9c13c/cyclopts-4.5.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/3a/1f/d8bce383a90d8a6a11033327777afa4d4d611ec11869284adb6f48152906/cyclopts-4.5.3-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/36/36/bc980b9a14409f3356309c45a8d88d58797d02002a9d794dd6c84e809d3a/cymem-2.0.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/36/36/bc980b9a14409f3356309c45a8d88d58797d02002a9d794dd6c84e809d3a/cymem-2.0.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/28/0e/b11ad5fd77e3dd0baad9cac3184315be7654ae401e3b0b0c324503f23d96/datashader-0.18.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/28/0e/b11ad5fd77e3dd0baad9cac3184315be7654ae401e3b0b0c324503f23d96/datashader-0.18.2-py3-none-any.whl
|
||||||
|
|
@ -315,7 +316,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/53/32/256df3dbaa198c58539ad94f9a41e98c2c8ff23f126b8f5f52c7dcd0a738/duckdb-1.4.4-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/c2/0f/875b6df73f884062f3bd7d62a2fb9bfc1d07d1c93a611e999401c5b10ca0/earthengine_api-1.7.13-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/fd/62/d5aa7b3a3e637def1df38ac114dc04f042489cd22210ffc6cd03e259f87a/earthengine_api-1.7.14-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/04/40/2ccf4c87a5f9c8198fe71600d5f307f5dada201c091af8774a9c1e360865/ecmwf_datastores_client-0.4.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/04/40/2ccf4c87a5f9c8198fe71600d5f307f5dada201c091af8774a9c1e360865/ecmwf_datastores_client-0.4.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/65/54/5e3b0e41799e17e5eff1547fda4aab53878c0adb4243de6b95f8ddef899e/ee_extra-2025.7.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/65/54/5e3b0e41799e17e5eff1547fda4aab53878c0adb4243de6b95f8ddef899e/ee_extra-2025.7.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/06/98/3e22f4386f6c1957f5994c9aa9cedd8a442bb75766bd0b2e2c1c92854af9/eemont-2025.7.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/06/98/3e22f4386f6c1957f5994c9aa9cedd8a442bb75766bd0b2e2c1c92854af9/eemont-2025.7.1-py3-none-any.whl
|
||||||
|
|
@ -326,13 +327,13 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/cf/22/fdc2e30d43ff853720042fa15baa3e6122722be1a7950a98233ebb55cd71/eval_type_backport-0.3.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/cf/22/fdc2e30d43ff853720042fa15baa3e6122722be1a7950a98233ebb55cd71/eval_type_backport-0.3.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/7e/31/d229f6cdb9cbe03020499d69c4b431b705aa19a55aa0fe698c98022b2fef/faiss_cpu-1.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/7e/31/d229f6cdb9cbe03020499d69c4b431b705aa19a55aa0fe698c98022b2fef/faiss_cpu-1.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/c7/7d/74dd43d58f37584b32f0d781c8dbea9a286ee73e90393394e70569d4f254/fastai-2.8.6-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/49/92/9429cce6bd4048cec9e4c2458c6bdb56144327afe1e7f29341f807d97dca/fastai-2.8.7-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/59/f3/f71552b94a39509b62e72c4a26b6e4440bb9ce6decacf90af2916829e69e/fastcluster-1.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/59/f3/f71552b94a39509b62e72c4a26b6e4440bb9ce6decacf90af2916829e69e/fastcluster-1.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/ea/d6/bb13c44b5863c0be7a27ef02982eca88f50d717549df1979e85942292239/fastcore-1.12.12-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d0/c0/b7fa771dda08001eb004112114094370d6b94b857ed902a32472ed74a8fe/fastcore-1.12.14-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/47/60/ed35253a05a70b63e4f52df1daa39a6a464a3e22b0bd060b77f63e2e2b6a/fastdownload-0.0.7-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/47/60/ed35253a05a70b63e4f52df1daa39a6a464a3e22b0bd060b77f63e2e2b6a/fastdownload-0.0.7-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/fe/a7/af33584fa6d17b911cfaba460efd3409cb5dd47083c181a4fdfec4bef840/fastlite-0.2.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/fe/a7/af33584fa6d17b911cfaba460efd3409cb5dd47083c181a4fdfec4bef840/fastlite-0.2.4-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/79/45/4aa502bbda9b63c792463c3466a2c5ef3c0830935f81906043f66b2b6c74/fastprogress-1.1.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/da/8e/4ffb242418e2924ef3216b712f1382d4369a5f494c30052c3ac8dfb757d9/fastprogress-1.1.5-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/47/3d/4b85b47a7e70d5c7cc0cf7d7b2883646c9c0bd3ef54a33f23d5873aa910c/fasttransform-0.0.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/47/3d/4b85b47a7e70d5c7cc0cf7d7b2883646c9c0bd3ef54a33f23d5873aa910c/fasttransform-0.0.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/92/54/dc5aec836660a37f11a8c66300bc2c18be254ef3a78ff08869ed1960c0fb/flox-0.11.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/92/54/dc5aec836660a37f11a8c66300bc2c18be254ef3a78ff08869ed1960c0fb/flox-0.11.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/b5/a8/5f764f333204db0390362a4356d03a43626997f26818a0e9396f1b3bd8c9/folium-0.20.0-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/b5/a8/5f764f333204db0390362a4356d03a43626997f26818a0e9396f1b3bd8c9/folium-0.20.0-py2.py3-none-any.whl
|
||||||
|
|
@ -445,8 +446,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/c0/db/61efa0d08a99f897ef98256b03e563092d36cc38dc4ebe4a85020fe40b31/pbr-7.0.3-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/c0/db/61efa0d08a99f897ef98256b03e563092d36cc38dc4ebe4a85020fe40b31/pbr-7.0.3-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/de/f0/c81e05b613866b76d2d1066490adf1a3dbc4ee9d9c839961c3fc8a6997af/pip-26.0.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/da/10/1b0dcf51427326f70e50d98df21b18c228117a743a1fc515a42f8dc7d342/platformdirs-4.6.0-py3-none-any.whl
|
|
||||||
- pypi: https://files.pythonhosted.org/packages/8a/67/f95b5460f127840310d2187f916cf0023b5875c0717fdf893f71e1325e87/plotly-6.5.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/8a/67/f95b5460f127840310d2187f916cf0023b5875c0717fdf893f71e1325e87/plotly-6.5.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/42/88/71fa06eb487ed9d4fab0ad173300b7a58706385f98fb66b1ccdc3ec3d4dd/plum_dispatch-2.6.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/42/88/71fa06eb487ed9d4fab0ad173300b7a58706385f98fb66b1ccdc3ec3d4dd/plum_dispatch-2.6.1-py3-none-any.whl
|
||||||
|
|
@ -466,11 +466,12 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/68/fb/bc7f639aed026bca6e7beb1e33f6951e16b7d315594e7635a4f7d21d63f4/py_spy-0.4.1-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/68/fb/bc7f639aed026bca6e7beb1e33f6951e16b7d315594e7635a4f7d21d63f4/py_spy-0.4.1-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl
|
||||||
|
- pypi: https://files.pythonhosted.org/packages/35/ef/a0090b20af352b9e8ca7b5ccef81940df63ba15cf5c66baf5c6145620537/pycirclize-1.10.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/8c/b2/23f4032cd1c9744aa8e9ecda43cd4d755fcb209f7f40fae035248f31a679/pyct-0.6.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/8c/b2/23f4032cd1c9744aa8e9ecda43cd4d755fcb209f7f40fae035248f31a679/pyct-0.6.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/b0/1a/dd1b9d7e627486cf8e7523d09b70010e05a4bc41414f4ae6ce184cf0afb6/pydantic_settings-2.13.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/ab/4c/b888e6cf58bd9db9c93f40d1c6be8283ff49d88919231afe93a6bcf61626/pydeck-0.9.1-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/ab/4c/b888e6cf58bd9db9c93f40d1c6be8283ff49d88919231afe93a6bcf61626/pydeck-0.9.1-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e5/e0/050018d855d26d3c0b4a7d1b2ed692be758ce276d8289e2a2b44ba1014a5/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/e5/e0/050018d855d26d3c0b4a7d1b2ed692be758ce276d8289e2a2b44ba1014a5/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/46/35/b874f79d03e9f900012cf609f7fff97b77164f2e14ee5aac282f8a999c1b/pyogrio-0.12.1-cp313-cp313-manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/46/35/b874f79d03e9f900012cf609f7fff97b77164f2e14ee5aac282f8a999c1b/pyogrio-0.12.1-cp313-cp313-manylinux_2_28_x86_64.whl
|
||||||
|
|
@ -485,7 +486,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/88/ae/baf3a8057d8129896a7e02619df43ea0d918fc5b2bb66eb6e2470595fbac/python_box-7.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/88/ae/baf3a8057d8129896a7e02619df43ea0d918fc5b2bb66eb6e2470595fbac/python_box-7.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/22/da/e890190fd9b3bd465c796a341fb24cbb1b0f9d831f511d21db9faf056e32/python_fasthtml-0.12.41-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d8/83/9a9188aad05b3fe84d3f163e3978458e95d6db0991de614501a5473fe6c7/python_fasthtml-0.12.42-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/0e/93/c8c361bf0a2fe50f828f32def460e8b8a14b93955d3fd302b1a9b63b19e4/pytorch_lightning-2.6.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/0e/93/c8c361bf0a2fe50f828f32def460e8b8a14b93955d3fd302b1a9b63b19e4/pytorch_lightning-2.6.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
|
|
@ -506,7 +507,7 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/a3/bb/bbae36d06c0fd670e8373da67096cd57058b57c9bad7d92969b5e3b730af/scooby-0.11.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/a3/bb/bbae36d06c0fd670e8373da67096cd57058b57c9bad7d92969b5e3b730af/scooby-0.11.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/ca/63/2c6daf59d86b1c30600bff679d039f57fd1932af82c43c0bde1cbc55e8d4/sentry_sdk-2.52.0-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/47/d4/2fdf854bc3b9c7f55219678f812600a20a138af2dd847d99004994eada8f/sentry_sdk-2.53.0-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/6b/6a/c006de5df0e0f4850aa94019df1f79bf6a5342fa851ca85e4728691fd0c4/shap-0.50.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/6b/6a/c006de5df0e0f4850aa94019df1f79bf6a5342fa851ca85e4728691fd0c4/shap-0.50.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/f2/a2/83fc37e2a58090e3d2ff79175a95493c664bcd0b653dd75cb9134645a4e5/shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/f2/a2/83fc37e2a58090e3d2ff79175a95493c664bcd0b653dd75cb9134645a4e5/shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl
|
||||||
|
|
@ -535,9 +536,9 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/02/be/5d2d47b1fb58943194fb59dcf222f7c4e35122ec0ffe8c36e18b5d728f0b/tblib-3.2.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/02/be/5d2d47b1fb58943194fb59dcf222f7c4e35122ec0ffe8c36e18b5d728f0b/tblib-3.2.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e0/1d/b5d63f1a6b824282b57f7b581810d20b7a28ca951f2d5b59f1eb0782c12b/tensorboardx-2.6.4-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e0/1d/b5d63f1a6b824282b57f7b581810d20b7a28ca951f2d5b59f1eb0782c12b/tensorboardx-2.6.4-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/9c/78/96ddb99933e11d91bc6e05edae23d2687e44213066bcbaca338898c73c47/textual-7.5.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d3/be/e191c2a15da20530fde03564564e3e4b4220eb9d687d4014957e5c6a5e85/textual-8.0.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/45/ef/e7fca88074cb0aa1c1a23195470b4549492c2797fe7dc9ff79a85500153a/thinc-8.3.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/45/ef/e7fca88074cb0aa1c1a23195470b4549492c2797fe7dc9ff79a85500153a/thinc-8.3.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/09/19/529b28ca338c5a88315e71e672badc85eef89460c248c4164f6ce058f8c7/tifffile-2026.1.28-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/48/06/a8e97165d82f866a40117f213d2f8a32f297c9c76ec9c16a1a2c680e0f59/tifffile-2026.2.16-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl
|
||||||
|
|
@ -549,20 +550,20 @@ environments:
|
||||||
- pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/03/b8/e484ef633af3887baeeb4b6ad12743363af7cce68ae51e938e00aaa0529d/transformers-4.57.6-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/03/b8/e484ef633af3887baeeb4b6ad12743363af7cce68ae51e938e00aaa0529d/transformers-4.57.6-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/74/18/8dd4fe6df1fd66f3e83b4798eddb1d8482d9d9b105f25099b76703402ebb/ty-0.0.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/74/18/8dd4fe6df1fd66f3e83b4798eddb1d8482d9d9b105f25099b76703402ebb/ty-0.0.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/7a/ed/d6fca788b51d0d4640c4bc82d0e85bad4b49809bca36bf4af01b4dcb66a7/typer-0.23.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/85/d0/4da85c2a45054bb661993c93524138ace4956cb075a7ae0c9d1deadc331b/typer-0.24.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/07/3e/ba3a222c80ee070d9497ece3e1fe77253c142925dd4c90f04278aac0a9eb/typer_slim-0.23.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/a7/24/5480c20380dfd18cf33d14784096dca45a24eae6102e91d49a718d3b6855/typer_slim-0.24.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e7/c1/56ef16bf5dcd255155cc736d276efa6ae0a5c26fd685e28f0412a4013c01/types_pytz-2025.2.0.20251108-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e7/c1/56ef16bf5dcd255155cc736d276efa6ae0a5c26fd685e28f0412a4013c01/types_pytz-2025.2.0.20251108-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/d6/32/48209716f9715d77f1bce084ad74c5d3cfcf41fd78d0c7e7dbe4829cfa3a/ultraplot-1.72.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/36/48/33f00ffd1c62ca4e66f91024049107b7b372fda7bbe4d20e6a492a39ff02/ultraplot-2.0.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/3d/d8/2083a1daa7439a66f3a48589a57d576aa117726762618f6bb09fe3798796/uvicorn-0.40.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/83/e4/d04a086285c20886c0daad0e026f250869201013d18f81d9ff5eada73a88/uvicorn-0.41.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/e6/9f/ca52771fe972e0dcc5167fedb609940e01516066938ff2ee28b273ae4f29/vega_datasets-0.9.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e6/9f/ca52771fe972e0dcc5167fedb609940e01516066938ff2ee28b273ae4f29/vega_datasets-0.9.0-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/04/d5/81d1403788f072e7d0e2b2fe539a0ae4410f27886ff52df094e5348c99ea/vegafusion-2.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/04/d5/81d1403788f072e7d0e2b2fe539a0ae4410f27886ff52df094e5348c99ea/vegafusion-2.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/a0/18/88e02899b72fa8273ffb32bde12b0e5776ee0fd9fb29559a49c48ec4c5fa/vl_convert_python-1.9.0.post1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/a0/18/88e02899b72fa8273ffb32bde12b0e5776ee0fd9fb29559a49c48ec4c5fa/vl_convert_python-1.9.0.post1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/70/c8/1b758bd903afee000f023cd03f335ff328a21b3914f9f9deda49b1e57723/wandb-0.24.2-py3-none-manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/de/91/ec9465d014cfd199c5b2083d271d31b3c2aedeae66f3d8a0712f7f54bdf3/wandb-0.25.0-py3-none-manylinux_2_28_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl
|
||||||
- pypi: https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
||||||
|
|
@ -931,10 +932,10 @@ packages:
|
||||||
- astropy[dev] ; extra == 'dev-all'
|
- astropy[dev] ; extra == 'dev-all'
|
||||||
- astropy[test-all] ; extra == 'dev-all'
|
- astropy[test-all] ; extra == 'dev-all'
|
||||||
requires_python: '>=3.11'
|
requires_python: '>=3.11'
|
||||||
- pypi: https://files.pythonhosted.org/packages/4e/67/6af8b422c04dec79c908cf60fdcd4725c3c112b2a058087c4ff58284a142/astropy_iers_data-0.2026.2.9.0.50.33-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/49/94/dcdac330d2c26776956555610ef584147584acc6b060e451aa65dd9142d9/astropy_iers_data-0.2026.2.16.0.48.25-py3-none-any.whl
|
||||||
name: astropy-iers-data
|
name: astropy-iers-data
|
||||||
version: 0.2026.2.9.0.50.33
|
version: 0.2026.2.16.0.48.25
|
||||||
sha256: ac01dede0240499b23c2b89fdc93093500336197c5c794e6a01173cfd78a7620
|
sha256: 180d1c3f59d18aa616345560799c2d88ec6e5164b8c45c746380acf892946136
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- pytest ; extra == 'docs'
|
- pytest ; extra == 'docs'
|
||||||
- hypothesis ; extra == 'test'
|
- hypothesis ; extra == 'test'
|
||||||
|
|
@ -1523,6 +1524,13 @@ packages:
|
||||||
- html5lib ; extra == 'html5lib'
|
- html5lib ; extra == 'html5lib'
|
||||||
- lxml ; extra == 'lxml'
|
- lxml ; extra == 'lxml'
|
||||||
requires_python: '>=3.7.0'
|
requires_python: '>=3.7.0'
|
||||||
|
- pypi: https://files.pythonhosted.org/packages/0b/c7/b2e7aca3de8981f4ecb6ab1e0334c3c4a512e5e9898b57b3d8734b086da7/biopython-1.86-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
|
name: biopython
|
||||||
|
version: '1.86'
|
||||||
|
sha256: 593ec6a2a4fedec08ddcee1a8a0e0b0ed56835b2714904b352ec4a93d5b9d973
|
||||||
|
requires_dist:
|
||||||
|
- numpy
|
||||||
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl
|
||||||
name: blinker
|
name: blinker
|
||||||
version: 1.9.0
|
version: 1.9.0
|
||||||
|
|
@ -1685,15 +1693,15 @@ packages:
|
||||||
- zipp>=0.5 ; python_full_version < '3.8'
|
- zipp>=0.5 ; python_full_version < '3.8'
|
||||||
- typing-extensions>=3.6.4 ; python_full_version < '3.8'
|
- typing-extensions>=3.6.4 ; python_full_version < '3.8'
|
||||||
requires_python: '>=3.6'
|
requires_python: '>=3.6'
|
||||||
- pypi: https://files.pythonhosted.org/packages/0c/4b/d04e067df4401902cb2249df241bc1502bf90e990c6a3da5f82ba7de60fa/catboost-1.2.8-cp313-cp313-manylinux2014_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/e7/07/893b53c492fc2c827d0c6de5fe4d47cd016c57596b1f7318cc14cf57121f/catboost-1.2.9-cp313-cp313-manylinux2014_x86_64.whl
|
||||||
name: catboost
|
name: catboost
|
||||||
version: 1.2.8
|
version: 1.2.9
|
||||||
sha256: 8d2b58781c7ff2f974bde857da0d10d867366979193a4e7052746330a8b76b55
|
sha256: 46a34a5f241c85f3184ca6fd7c3de338f2db8d6daf3ac05f81411f366e4387c8
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- graphviz
|
- graphviz
|
||||||
- matplotlib
|
- matplotlib
|
||||||
- numpy>=1.16.0,<3.0
|
- numpy>=1.16.0,<3.0
|
||||||
- pandas>=0.24
|
- pandas>=0.24,<4.0
|
||||||
- scipy
|
- scipy
|
||||||
- plotly
|
- plotly
|
||||||
- six
|
- six
|
||||||
|
|
@ -2401,10 +2409,10 @@ packages:
|
||||||
- pytest-cov ; extra == 'tests'
|
- pytest-cov ; extra == 'tests'
|
||||||
- pytest-xdist ; extra == 'tests'
|
- pytest-xdist ; extra == 'tests'
|
||||||
requires_python: '>=3.8'
|
requires_python: '>=3.8'
|
||||||
- pypi: https://files.pythonhosted.org/packages/2b/03/f906829bcfcbb945f19d6a64240ffb66a31d69ca5533e95882f0efc9c13c/cyclopts-4.5.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/3a/1f/d8bce383a90d8a6a11033327777afa4d4d611ec11869284adb6f48152906/cyclopts-4.5.3-py3-none-any.whl
|
||||||
name: cyclopts
|
name: cyclopts
|
||||||
version: 4.5.2
|
version: 4.5.3
|
||||||
sha256: ee56ee23c2c81abc34b66b5aa8fd2698ca699740054e84e534449ec3eb7f944d
|
sha256: 50af3085bb15d4a6f2582dd383dad5e4ba6a0d4d4c64ee63326d881a752a6919
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- attrs>=23.1.0
|
- attrs>=23.1.0
|
||||||
- docstring-parser>=0.15,<4.0
|
- docstring-parser>=0.15,<4.0
|
||||||
|
|
@ -2587,10 +2595,10 @@ packages:
|
||||||
- pyarrow ; extra == 'all'
|
- pyarrow ; extra == 'all'
|
||||||
- adbc-driver-manager ; extra == 'all'
|
- adbc-driver-manager ; extra == 'all'
|
||||||
requires_python: '>=3.9.0'
|
requires_python: '>=3.9.0'
|
||||||
- pypi: https://files.pythonhosted.org/packages/c2/0f/875b6df73f884062f3bd7d62a2fb9bfc1d07d1c93a611e999401c5b10ca0/earthengine_api-1.7.13-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/fd/62/d5aa7b3a3e637def1df38ac114dc04f042489cd22210ffc6cd03e259f87a/earthengine_api-1.7.14-py3-none-any.whl
|
||||||
name: earthengine-api
|
name: earthengine-api
|
||||||
version: 1.7.13
|
version: 1.7.14
|
||||||
sha256: 32a24b6003287f71afb24e2cee7718296f8d82778488b88c1e760279c7e47840
|
sha256: 35cad802047117193931596c0b79a41569db0b65013fc468990d8d8410cd8967
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- google-cloud-storage
|
- google-cloud-storage
|
||||||
- google-api-python-client>=1.12.1
|
- google-api-python-client>=1.12.1
|
||||||
|
|
@ -2766,13 +2774,11 @@ packages:
|
||||||
- numpy>=1.25.0,<3.0
|
- numpy>=1.25.0,<3.0
|
||||||
- packaging
|
- packaging
|
||||||
requires_python: '>=3.9,<3.15'
|
requires_python: '>=3.9,<3.15'
|
||||||
- pypi: https://files.pythonhosted.org/packages/c7/7d/74dd43d58f37584b32f0d781c8dbea9a286ee73e90393394e70569d4f254/fastai-2.8.6-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/49/92/9429cce6bd4048cec9e4c2458c6bdb56144327afe1e7f29341f807d97dca/fastai-2.8.7-py3-none-any.whl
|
||||||
name: fastai
|
name: fastai
|
||||||
version: 2.8.6
|
version: 2.8.7
|
||||||
sha256: 6dcaa2e0f9d1cc6a1bd462d38f907ab908e09b9070542fee7b271018c2a2e0da
|
sha256: 840145fe563bed47d35fb5da47121f9749b9ae7deca1a7f31189b045a6a72d9d
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- pip
|
|
||||||
- packaging
|
|
||||||
- fastdownload>=0.0.5,<2
|
- fastdownload>=0.0.5,<2
|
||||||
- fastcore>=1.8.0
|
- fastcore>=1.8.0
|
||||||
- fasttransform>=0.0.2
|
- fasttransform>=0.0.2
|
||||||
|
|
@ -2789,7 +2795,7 @@ packages:
|
||||||
- packaging
|
- packaging
|
||||||
- plum-dispatch
|
- plum-dispatch
|
||||||
- cloudpickle
|
- cloudpickle
|
||||||
- torch>=1.10,<2.10
|
- torch>=1.10,<3
|
||||||
- nbdev ; extra == 'dev'
|
- nbdev ; extra == 'dev'
|
||||||
- ipywidgets ; extra == 'dev'
|
- ipywidgets ; extra == 'dev'
|
||||||
- lightning ; extra == 'dev'
|
- lightning ; extra == 'dev'
|
||||||
|
|
@ -2821,10 +2827,10 @@ packages:
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- numpy>=2
|
- numpy>=2
|
||||||
requires_python: '>=3'
|
requires_python: '>=3'
|
||||||
- pypi: https://files.pythonhosted.org/packages/ea/d6/bb13c44b5863c0be7a27ef02982eca88f50d717549df1979e85942292239/fastcore-1.12.12-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d0/c0/b7fa771dda08001eb004112114094370d6b94b857ed902a32472ed74a8fe/fastcore-1.12.14-py3-none-any.whl
|
||||||
name: fastcore
|
name: fastcore
|
||||||
version: 1.12.12
|
version: 1.12.14
|
||||||
sha256: bb1a3a3accd62a72bad56af974e0617af078316be5bb5dcc8763b8244c197fa8
|
sha256: 19e5adcee3af6f357af4f66954e17f335f208bb9cb422dcdef03d2e9d586eca3
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- numpy ; extra == 'dev'
|
- numpy ; extra == 'dev'
|
||||||
- nbdev>=0.2.39 ; extra == 'dev'
|
- nbdev>=0.2.39 ; extra == 'dev'
|
||||||
|
|
@ -2868,13 +2874,14 @@ packages:
|
||||||
- apswutils>=0.1.2
|
- apswutils>=0.1.2
|
||||||
- graphviz ; extra == 'dev'
|
- graphviz ; extra == 'dev'
|
||||||
requires_python: '>=3.10'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/79/45/4aa502bbda9b63c792463c3466a2c5ef3c0830935f81906043f66b2b6c74/fastprogress-1.1.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/da/8e/4ffb242418e2924ef3216b712f1382d4369a5f494c30052c3ac8dfb757d9/fastprogress-1.1.5-py3-none-any.whl
|
||||||
name: fastprogress
|
name: fastprogress
|
||||||
version: 1.1.3
|
version: 1.1.5
|
||||||
sha256: b7ad6a1a589407174ceaa3368c212bf13136548f9b4a85d3f6c6e489289ffdad
|
sha256: 7763ba4d87d60f51550ac07425f0308e58fd0e450e4404a9a8d7e1e1191f8e44
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- fastcore>=1.10.0
|
- fastcore>=1.10.0
|
||||||
- python-fasthtml>=0.12.34
|
- python-fasthtml>=0.12.34
|
||||||
|
- numpy ; extra == 'dev'
|
||||||
requires_python: '>=3.10'
|
requires_python: '>=3.10'
|
||||||
- conda: https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda
|
- conda: https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda
|
||||||
sha256: 30498ed45133f457fd9ed14d5fac6512347f05d11fe1ed89842c7dfdb516f78f
|
sha256: 30498ed45133f457fd9ed14d5fac6512347f05d11fe1ed89842c7dfdb516f78f
|
||||||
|
|
@ -6832,15 +6839,10 @@ packages:
|
||||||
- trove-classifiers>=2024.10.12 ; extra == 'tests'
|
- trove-classifiers>=2024.10.12 ; extra == 'tests'
|
||||||
- defusedxml ; extra == 'xmp'
|
- defusedxml ; extra == 'xmp'
|
||||||
requires_python: '>=3.10'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/de/f0/c81e05b613866b76d2d1066490adf1a3dbc4ee9d9c839961c3fc8a6997af/pip-26.0.1-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl
|
||||||
name: pip
|
|
||||||
version: 26.0.1
|
|
||||||
sha256: bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b
|
|
||||||
requires_python: '>=3.9'
|
|
||||||
- pypi: https://files.pythonhosted.org/packages/da/10/1b0dcf51427326f70e50d98df21b18c228117a743a1fc515a42f8dc7d342/platformdirs-4.6.0-py3-none-any.whl
|
|
||||||
name: platformdirs
|
name: platformdirs
|
||||||
version: 4.6.0
|
version: 4.9.2
|
||||||
sha256: dd7f808d828e1764a22ebff09e60f175ee3c41876606a6132a688d809c7c9c73
|
sha256: 9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd
|
||||||
requires_python: '>=3.10'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/8a/67/f95b5460f127840310d2187f916cf0023b5875c0717fdf893f71e1325e87/plotly-6.5.2-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/8a/67/f95b5460f127840310d2187f916cf0023b5875c0717fdf893f71e1325e87/plotly-6.5.2-py3-none-any.whl
|
||||||
name: plotly
|
name: plotly
|
||||||
|
|
@ -7179,6 +7181,17 @@ packages:
|
||||||
- pkg:pypi/pybind11-global?source=hash-mapping
|
- pkg:pypi/pybind11-global?source=hash-mapping
|
||||||
size: 228871
|
size: 228871
|
||||||
timestamp: 1755953338243
|
timestamp: 1755953338243
|
||||||
|
- pypi: https://files.pythonhosted.org/packages/35/ef/a0090b20af352b9e8ca7b5ccef81940df63ba15cf5c66baf5c6145620537/pycirclize-1.10.1-py3-none-any.whl
|
||||||
|
name: pycirclize
|
||||||
|
version: 1.10.1
|
||||||
|
sha256: fc571b0223195b651edd22011963628bddd92861a4053526b31035bb3347f43e
|
||||||
|
requires_dist:
|
||||||
|
- biopython>=1.80
|
||||||
|
- matplotlib>=3.6.3
|
||||||
|
- numpy>=1.21
|
||||||
|
- pandas>=1.3.5
|
||||||
|
- ipympl>=0.9.7 ; extra == 'tooltip'
|
||||||
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl
|
||||||
name: pycparser
|
name: pycparser
|
||||||
version: '3.0'
|
version: '3.0'
|
||||||
|
|
@ -7213,10 +7226,10 @@ packages:
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- typing-extensions>=4.14.1
|
- typing-extensions>=4.14.1
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.9'
|
||||||
- pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/b0/1a/dd1b9d7e627486cf8e7523d09b70010e05a4bc41414f4ae6ce184cf0afb6/pydantic_settings-2.13.0-py3-none-any.whl
|
||||||
name: pydantic-settings
|
name: pydantic-settings
|
||||||
version: 2.12.0
|
version: 2.13.0
|
||||||
sha256: fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809
|
sha256: d67b576fff39cd086b595441bf9c75d4193ca9c0ed643b90360694d0f1240246
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- pydantic>=2.7.0
|
- pydantic>=2.7.0
|
||||||
- python-dotenv>=0.21.0
|
- python-dotenv>=0.21.0
|
||||||
|
|
@ -7506,10 +7519,10 @@ packages:
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- click>=5.0 ; extra == 'cli'
|
- click>=5.0 ; extra == 'cli'
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.9'
|
||||||
- pypi: https://files.pythonhosted.org/packages/22/da/e890190fd9b3bd465c796a341fb24cbb1b0f9d831f511d21db9faf056e32/python_fasthtml-0.12.41-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d8/83/9a9188aad05b3fe84d3f163e3978458e95d6db0991de614501a5473fe6c7/python_fasthtml-0.12.42-py3-none-any.whl
|
||||||
name: python-fasthtml
|
name: python-fasthtml
|
||||||
version: 0.12.41
|
version: 0.12.42
|
||||||
sha256: fc0a1b7735bfd591076b5dd7b6af8050e76ba1604fa5ad9d250aec6f5a69af93
|
sha256: d74742012a9696a9fcd0c5dfcaa20b39ef751d29b2e1fb119c83568f7a0c9234
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- fastcore>=1.10.0
|
- fastcore>=1.10.0
|
||||||
- python-dateutil
|
- python-dateutil
|
||||||
|
|
@ -8353,10 +8366,10 @@ packages:
|
||||||
- scipy>=1.7 ; extra == 'stats'
|
- scipy>=1.7 ; extra == 'stats'
|
||||||
- statsmodels>=0.12 ; extra == 'stats'
|
- statsmodels>=0.12 ; extra == 'stats'
|
||||||
requires_python: '>=3.8'
|
requires_python: '>=3.8'
|
||||||
- pypi: https://files.pythonhosted.org/packages/ca/63/2c6daf59d86b1c30600bff679d039f57fd1932af82c43c0bde1cbc55e8d4/sentry_sdk-2.52.0-py2.py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/47/d4/2fdf854bc3b9c7f55219678f812600a20a138af2dd847d99004994eada8f/sentry_sdk-2.53.0-py2.py3-none-any.whl
|
||||||
name: sentry-sdk
|
name: sentry-sdk
|
||||||
version: 2.52.0
|
version: 2.53.0
|
||||||
sha256: 931c8f86169fc6f2752cb5c4e6480f0d516112e78750c312e081ababecbaf2ed
|
sha256: 46e1ed8d84355ae54406c924f6b290c3d61f4048625989a723fd622aab838899
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- urllib3>=1.26.11
|
- urllib3>=1.26.11
|
||||||
- certifi
|
- certifi
|
||||||
|
|
@ -8940,10 +8953,10 @@ packages:
|
||||||
- packaging
|
- packaging
|
||||||
- protobuf>=3.20
|
- protobuf>=3.20
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.9'
|
||||||
- pypi: https://files.pythonhosted.org/packages/9c/78/96ddb99933e11d91bc6e05edae23d2687e44213066bcbaca338898c73c47/textual-7.5.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/d3/be/e191c2a15da20530fde03564564e3e4b4220eb9d687d4014957e5c6a5e85/textual-8.0.0-py3-none-any.whl
|
||||||
name: textual
|
name: textual
|
||||||
version: 7.5.0
|
version: 8.0.0
|
||||||
sha256: 849dfee9d705eab3b2d07b33152b7bd74fb1f5056e002873cc448bce500c6374
|
sha256: 8908f4ebe93a6b4f77ca7262197784a52162bc88b05f4ecf50ac93a92d49bb8f
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- markdown-it-py[linkify]>=2.1.0
|
- markdown-it-py[linkify]>=2.1.0
|
||||||
- mdit-py-plugins
|
- mdit-py-plugins
|
||||||
|
|
@ -9024,10 +9037,10 @@ packages:
|
||||||
- pkg:pypi/threadpoolctl?source=hash-mapping
|
- pkg:pypi/threadpoolctl?source=hash-mapping
|
||||||
size: 23869
|
size: 23869
|
||||||
timestamp: 1741878358548
|
timestamp: 1741878358548
|
||||||
- pypi: https://files.pythonhosted.org/packages/09/19/529b28ca338c5a88315e71e672badc85eef89460c248c4164f6ce058f8c7/tifffile-2026.1.28-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/48/06/a8e97165d82f866a40117f213d2f8a32f297c9c76ec9c16a1a2c680e0f59/tifffile-2026.2.16-py3-none-any.whl
|
||||||
name: tifffile
|
name: tifffile
|
||||||
version: 2026.1.28
|
version: 2026.2.16
|
||||||
sha256: 45b08a19cf603dd99952eff54a61519626a1912e4e2a4d355f05938fe4a6e9fd
|
sha256: ea76cb4d8aa290f7f164840dfe4e244d104bd90c84d5ee1e6de6d84fd4745a48
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- numpy
|
- numpy
|
||||||
- imagecodecs>=2025.11.11 ; extra == 'codecs'
|
- imagecodecs>=2025.11.11 ; extra == 'codecs'
|
||||||
|
|
@ -9823,23 +9836,23 @@ packages:
|
||||||
version: 0.0.11
|
version: 0.0.11
|
||||||
sha256: 25f88e8789072830348cb59b761d5ced70642ed5600673b4bf6a849af71eca8b
|
sha256: 25f88e8789072830348cb59b761d5ced70642ed5600673b4bf6a849af71eca8b
|
||||||
requires_python: '>=3.8'
|
requires_python: '>=3.8'
|
||||||
- pypi: https://files.pythonhosted.org/packages/7a/ed/d6fca788b51d0d4640c4bc82d0e85bad4b49809bca36bf4af01b4dcb66a7/typer-0.23.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/85/d0/4da85c2a45054bb661993c93524138ace4956cb075a7ae0c9d1deadc331b/typer-0.24.0-py3-none-any.whl
|
||||||
name: typer
|
name: typer
|
||||||
version: 0.23.0
|
version: 0.24.0
|
||||||
sha256: 79f4bc262b6c37872091072a3cb7cb6d7d79ee98c0c658b4364bdcde3c42c913
|
sha256: 5fc435a9c8356f6160ed6e85a6301fdd6e3d8b2851da502050d1f92c5e9eddc8
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- click>=8.0.0
|
- click>=8.2.1
|
||||||
- shellingham>=1.3.0
|
- shellingham>=1.3.0
|
||||||
- rich>=10.11.0
|
- rich>=12.3.0
|
||||||
- annotated-doc>=0.0.2
|
- annotated-doc>=0.0.2
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/07/3e/ba3a222c80ee070d9497ece3e1fe77253c142925dd4c90f04278aac0a9eb/typer_slim-0.23.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/a7/24/5480c20380dfd18cf33d14784096dca45a24eae6102e91d49a718d3b6855/typer_slim-0.24.0-py3-none-any.whl
|
||||||
name: typer-slim
|
name: typer-slim
|
||||||
version: 0.23.0
|
version: 0.24.0
|
||||||
sha256: 1d693daf22d998a7b1edab8413cdcb8af07254154ce3956c1664dc11b01e2f8b
|
sha256: d5d7ee1ee2834d5020c7c616ed5e0d0f29b9a4b1dd283bdebae198ec09778d0e
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- typer>=0.23.0
|
- typer>=0.24.0
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/e7/c1/56ef16bf5dcd255155cc736d276efa6ae0a5c26fd685e28f0412a4013c01/types_pytz-2025.2.0.20251108-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/e7/c1/56ef16bf5dcd255155cc736d276efa6ae0a5c26fd685e28f0412a4013c01/types_pytz-2025.2.0.20251108-py3-none-any.whl
|
||||||
name: types-pytz
|
name: types-pytz
|
||||||
version: 2025.2.0.20251108
|
version: 2025.2.0.20251108
|
||||||
|
|
@ -9924,15 +9937,31 @@ packages:
|
||||||
license: BSD-3-Clause
|
license: BSD-3-Clause
|
||||||
size: 508347
|
size: 508347
|
||||||
timestamp: 1765407086135
|
timestamp: 1765407086135
|
||||||
- pypi: https://files.pythonhosted.org/packages/d6/32/48209716f9715d77f1bce084ad74c5d3cfcf41fd78d0c7e7dbe4829cfa3a/ultraplot-1.72.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/36/48/33f00ffd1c62ca4e66f91024049107b7b372fda7bbe4d20e6a492a39ff02/ultraplot-2.0.1-py3-none-any.whl
|
||||||
name: ultraplot
|
name: ultraplot
|
||||||
version: 1.72.0
|
version: 2.0.1
|
||||||
sha256: dc276064791661018311923bb5bf3cd541b79399682e48de1b88d8556053ae2d
|
sha256: ba2f1ab04d3fea82165facf9434e43054f4b22cae101c36a8e4f0176017d4e09
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- numpy>=1.26.0
|
- numpy>=1.26.0
|
||||||
- matplotlib>=3.9,<3.11
|
- matplotlib>=3.9,<3.11
|
||||||
|
- pycirclize>=1.10.1
|
||||||
- typing-extensions ; python_full_version < '3.12'
|
- typing-extensions ; python_full_version < '3.12'
|
||||||
requires_python: '>=3.10,<3.14'
|
- jupyter ; extra == 'docs'
|
||||||
|
- jupytext ; extra == 'docs'
|
||||||
|
- lxml-html-clean ; extra == 'docs'
|
||||||
|
- m2r2 ; extra == 'docs'
|
||||||
|
- mpltern ; extra == 'docs'
|
||||||
|
- nbsphinx ; extra == 'docs'
|
||||||
|
- sphinx ; extra == 'docs'
|
||||||
|
- sphinx-autoapi ; extra == 'docs'
|
||||||
|
- sphinx-automodapi ; extra == 'docs'
|
||||||
|
- sphinx-copybutton ; extra == 'docs'
|
||||||
|
- sphinx-design ; extra == 'docs'
|
||||||
|
- sphinx-gallery ; extra == 'docs'
|
||||||
|
- shibuya ; extra == 'docs'
|
||||||
|
- sphinx-sitemap ; extra == 'docs'
|
||||||
|
- typing-extensions ; extra == 'docs'
|
||||||
|
requires_python: '>=3.10,<3.15'
|
||||||
- pypi: https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl
|
||||||
name: uritemplate
|
name: uritemplate
|
||||||
version: 4.2.0
|
version: 4.2.0
|
||||||
|
|
@ -9949,10 +9978,10 @@ packages:
|
||||||
- pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks'
|
- pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks'
|
||||||
- backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd'
|
- backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd'
|
||||||
requires_python: '>=3.9'
|
requires_python: '>=3.9'
|
||||||
- pypi: https://files.pythonhosted.org/packages/3d/d8/2083a1daa7439a66f3a48589a57d576aa117726762618f6bb09fe3798796/uvicorn-0.40.0-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/83/e4/d04a086285c20886c0daad0e026f250869201013d18f81d9ff5eada73a88/uvicorn-0.41.0-py3-none-any.whl
|
||||||
name: uvicorn
|
name: uvicorn
|
||||||
version: 0.40.0
|
version: 0.41.0
|
||||||
sha256: c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee
|
sha256: 29e35b1d2c36a04b9e180d4007ede3bcb32a85fbdfd6c6aeb3f26839de088187
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- click>=7.0
|
- click>=7.0
|
||||||
- h11>=0.8
|
- h11>=0.8
|
||||||
|
|
@ -9962,7 +9991,7 @@ packages:
|
||||||
- python-dotenv>=0.13 ; extra == 'standard'
|
- python-dotenv>=0.13 ; extra == 'standard'
|
||||||
- pyyaml>=5.1 ; extra == 'standard'
|
- pyyaml>=5.1 ; extra == 'standard'
|
||||||
- uvloop>=0.15.1 ; platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32' and extra == 'standard'
|
- uvloop>=0.15.1 ; platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32' and extra == 'standard'
|
||||||
- watchfiles>=0.13 ; extra == 'standard'
|
- watchfiles>=0.20 ; extra == 'standard'
|
||||||
- websockets>=10.4 ; extra == 'standard'
|
- websockets>=10.4 ; extra == 'standard'
|
||||||
requires_python: '>=3.10'
|
requires_python: '>=3.10'
|
||||||
- pypi: https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
||||||
|
|
@ -10034,17 +10063,16 @@ packages:
|
||||||
version: 1.9.0.post1
|
version: 1.9.0.post1
|
||||||
sha256: 3c1558fa0055e88c465bd3d71760cde9fa2c94a95f776a0ef9178252fd820b1f
|
sha256: 3c1558fa0055e88c465bd3d71760cde9fa2c94a95f776a0ef9178252fd820b1f
|
||||||
requires_python: '>=3.7'
|
requires_python: '>=3.7'
|
||||||
- pypi: https://files.pythonhosted.org/packages/70/c8/1b758bd903afee000f023cd03f335ff328a21b3914f9f9deda49b1e57723/wandb-0.24.2-py3-none-manylinux_2_28_x86_64.whl
|
- pypi: https://files.pythonhosted.org/packages/de/91/ec9465d014cfd199c5b2083d271d31b3c2aedeae66f3d8a0712f7f54bdf3/wandb-0.25.0-py3-none-manylinux_2_28_x86_64.whl
|
||||||
name: wandb
|
name: wandb
|
||||||
version: 0.24.2
|
version: 0.25.0
|
||||||
sha256: 38661c666e70d7e1f460fc0a0edab8a393eaaa5f8773c17be534961a7022779d
|
sha256: 6c4c38077836f9b7569a35b0e1dcf1f0c43616fcd936d182f475edbfea063665
|
||||||
requires_dist:
|
requires_dist:
|
||||||
- click>=8.0.1
|
- click>=8.0.1
|
||||||
- eval-type-backport ; python_full_version < '3.10'
|
- eval-type-backport ; python_full_version < '3.10'
|
||||||
- gitpython>=1.0.0,!=3.1.29
|
- gitpython>=1.0.0,!=3.1.29
|
||||||
- packaging
|
- packaging
|
||||||
- platformdirs
|
- platformdirs
|
||||||
- protobuf>=3.12.0,!=4.21.0,!=5.28.0,<7 ; python_full_version < '3.9' and sys_platform == 'linux'
|
|
||||||
- protobuf>=3.15.0,!=4.21.0,!=5.28.0,<7 ; python_full_version == '3.9.*' and sys_platform == 'linux'
|
- protobuf>=3.15.0,!=4.21.0,!=5.28.0,<7 ; python_full_version == '3.9.*' and sys_platform == 'linux'
|
||||||
- protobuf>=3.19.0,!=4.21.0,!=5.28.0,<7 ; python_full_version >= '3.10' and sys_platform == 'linux'
|
- protobuf>=3.19.0,!=4.21.0,!=5.28.0,<7 ; python_full_version >= '3.10' and sys_platform == 'linux'
|
||||||
- protobuf>=3.19.0,!=4.21.0,!=5.28.0,<7 ; sys_platform != 'linux'
|
- protobuf>=3.19.0,!=4.21.0,!=5.28.0,<7 ; sys_platform != 'linux'
|
||||||
|
|
@ -10103,7 +10131,7 @@ packages:
|
||||||
- orjson ; extra == 'perf'
|
- orjson ; extra == 'perf'
|
||||||
- sweeps>=0.2.0 ; extra == 'sweeps'
|
- sweeps>=0.2.0 ; extra == 'sweeps'
|
||||||
- wandb-workspaces ; extra == 'workspaces'
|
- wandb-workspaces ; extra == 'workspaces'
|
||||||
requires_python: '>=3.8'
|
requires_python: '>=3.9'
|
||||||
- pypi: https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl
|
- pypi: https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl
|
||||||
name: wasabi
|
name: wasabi
|
||||||
version: 1.1.3
|
version: 1.1.3
|
||||||
|
|
|
||||||
460
src/entropice/dashboard/plots/inference.py
Normal file
460
src/entropice/dashboard/plots/inference.py
Normal file
|
|
@ -0,0 +1,460 @@
|
||||||
|
"""Plots for visualizing model inference results."""
|
||||||
|
|
||||||
|
import geopandas as gpd
|
||||||
|
import matplotlib.colors as mcolors
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import pydeck as pdk
|
||||||
|
|
||||||
|
from entropice.dashboard.utils.colors import get_cmap, get_palette, hex_to_rgb
|
||||||
|
from entropice.dashboard.utils.geometry import fix_hex_geometry
|
||||||
|
from entropice.utils.types import Task
|
||||||
|
|
||||||
|
|
||||||
|
def create_inference_map(
|
||||||
|
predictions_gdf: gpd.GeoDataFrame,
|
||||||
|
task: Task,
|
||||||
|
make_3d_map: bool,
|
||||||
|
) -> pdk.Deck:
|
||||||
|
"""Create a spatial distribution map for model predictions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with columns ['cell_id', 'predicted', 'geometry']
|
||||||
|
task: Task type (binary, count_regimes, density_regimes, count, density)
|
||||||
|
make_3d_map: Whether to render the map in 3D (extruded) or 2D
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
pdk.Deck: A PyDeck map visualization of the predictions
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Subsample if too many cells for performance
|
||||||
|
n_cells = len(predictions_gdf)
|
||||||
|
if n_cells > 50000:
|
||||||
|
predictions_gdf = predictions_gdf.sample(n=50000, random_state=42)
|
||||||
|
|
||||||
|
# Create a copy to avoid modifying the original
|
||||||
|
gdf = predictions_gdf.copy()
|
||||||
|
|
||||||
|
# Convert to WGS84 for pydeck
|
||||||
|
if gdf.crs is not None:
|
||||||
|
gdf = gdf.to_crs("EPSG:4326")
|
||||||
|
|
||||||
|
# Fix antimeridian issues for hex cells
|
||||||
|
gdf["geometry"] = gdf["geometry"].apply(fix_hex_geometry)
|
||||||
|
|
||||||
|
# Determine if classification or regression
|
||||||
|
classification_tasks: list[Task] = ["binary", "count_regimes", "density_regimes"]
|
||||||
|
is_classification = task in classification_tasks
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
# Convert to categorical if needed
|
||||||
|
if gdf["predicted"].dtype != "category":
|
||||||
|
gdf["predicted"] = pd.Categorical(gdf["predicted"])
|
||||||
|
|
||||||
|
# Get categories and assign colors
|
||||||
|
categories = gdf["predicted"].cat.categories.tolist()
|
||||||
|
n_categories = len(categories)
|
||||||
|
colors = get_palette(task, n_categories + 2)[1:-1] # Avoid too light/dark colors
|
||||||
|
|
||||||
|
# Create category to color mapping
|
||||||
|
category_colors = {cat: colors[i] for i, cat in enumerate(categories)}
|
||||||
|
|
||||||
|
# Assign colors to each row based on predicted category
|
||||||
|
rgb_colors = []
|
||||||
|
for cat in gdf["predicted"]:
|
||||||
|
color = category_colors[cat]
|
||||||
|
rgb_colors.append(hex_to_rgb(mcolors.to_hex(color)))
|
||||||
|
gdf["fill_color"] = rgb_colors
|
||||||
|
|
||||||
|
# For elevation in 3D, use category index normalized
|
||||||
|
if n_categories > 1:
|
||||||
|
gdf["elevation"] = gdf["predicted"].cat.codes / (n_categories - 1)
|
||||||
|
else:
|
||||||
|
gdf["elevation"] = 0.5
|
||||||
|
|
||||||
|
# Display value is the category name
|
||||||
|
gdf["display_value"] = gdf["predicted"].astype(str)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Regression task - use continuous colormap
|
||||||
|
cmap = get_cmap(task)
|
||||||
|
|
||||||
|
# Get prediction values
|
||||||
|
values = gdf["predicted"].to_numpy()
|
||||||
|
|
||||||
|
# Normalize using percentiles to avoid outliers
|
||||||
|
vmin, vmax = np.nanpercentile(values, [2, 98])
|
||||||
|
if vmax > vmin:
|
||||||
|
normalized_values = (np.clip(values, vmin, vmax) - vmin) / (vmax - vmin)
|
||||||
|
else:
|
||||||
|
normalized_values = np.full_like(values, 0.5)
|
||||||
|
|
||||||
|
# Map normalized values to colors
|
||||||
|
colors = [cmap(val) for val in normalized_values]
|
||||||
|
rgb_colors = [hex_to_rgb(mcolors.to_hex(color)) for color in colors]
|
||||||
|
gdf["fill_color"] = rgb_colors
|
||||||
|
|
||||||
|
# Use normalized values for elevation
|
||||||
|
gdf["elevation"] = normalized_values
|
||||||
|
|
||||||
|
# Display value is the actual prediction (rounded)
|
||||||
|
gdf["display_value"] = gdf["predicted"].round(3).astype(str)
|
||||||
|
|
||||||
|
# Convert to GeoJSON format
|
||||||
|
geojson_data = []
|
||||||
|
for _, row in gdf.iterrows():
|
||||||
|
geojson_data.append(
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": row["geometry"].__geo_interface__,
|
||||||
|
"properties": {
|
||||||
|
"fill_color": row["fill_color"],
|
||||||
|
"elevation": row["elevation"],
|
||||||
|
"predicted": row["display_value"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create pydeck layer
|
||||||
|
layer = pdk.Layer(
|
||||||
|
"GeoJsonLayer",
|
||||||
|
geojson_data,
|
||||||
|
opacity=0.7,
|
||||||
|
stroked=True,
|
||||||
|
filled=True,
|
||||||
|
extruded=make_3d_map,
|
||||||
|
wireframe=False,
|
||||||
|
get_fill_color="properties.fill_color",
|
||||||
|
get_line_color=[80, 80, 80],
|
||||||
|
line_width_min_pixels=0.5,
|
||||||
|
get_elevation="properties.elevation" if make_3d_map else 0,
|
||||||
|
elevation_scale=500000,
|
||||||
|
pickable=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set initial view state
|
||||||
|
view_state = pdk.ViewState(
|
||||||
|
latitude=70,
|
||||||
|
longitude=0,
|
||||||
|
zoom=2 if not make_3d_map else 1.5,
|
||||||
|
pitch=0 if not make_3d_map else 45,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build tooltip HTML
|
||||||
|
tooltip_html = "<b>Predicted:</b> {predicted}"
|
||||||
|
|
||||||
|
# Create deck
|
||||||
|
deck = pdk.Deck(
|
||||||
|
layers=[layer],
|
||||||
|
initial_view_state=view_state,
|
||||||
|
tooltip={
|
||||||
|
"html": tooltip_html,
|
||||||
|
"style": {"backgroundColor": "steelblue", "color": "white"},
|
||||||
|
},
|
||||||
|
map_style="https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json",
|
||||||
|
)
|
||||||
|
|
||||||
|
return deck
|
||||||
|
|
||||||
|
|
||||||
|
def create_prediction_distribution_plot(
|
||||||
|
predictions_gdf: gpd.GeoDataFrame,
|
||||||
|
task: Task,
|
||||||
|
) -> go.Figure:
|
||||||
|
"""Create a distribution plot for predictions.
|
||||||
|
|
||||||
|
For classification tasks, shows a bar chart of class counts.
|
||||||
|
For regression tasks, shows a histogram of predicted values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with 'predicted' column
|
||||||
|
task: Task type
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Plotly Figure with distribution plot
|
||||||
|
|
||||||
|
"""
|
||||||
|
classification_tasks: list[Task] = ["binary", "count_regimes", "density_regimes"]
|
||||||
|
is_classification = task in classification_tasks
|
||||||
|
|
||||||
|
fig = go.Figure()
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
# Bar chart for classification
|
||||||
|
# Convert to categorical if needed
|
||||||
|
if predictions_gdf["predicted"].dtype != "category":
|
||||||
|
predictions_gdf["predicted"] = pd.Categorical(predictions_gdf["predicted"])
|
||||||
|
|
||||||
|
categories = predictions_gdf["predicted"].cat.categories.tolist()
|
||||||
|
counts = predictions_gdf["predicted"].value_counts().reindex(categories, fill_value=0)
|
||||||
|
|
||||||
|
# Get colors
|
||||||
|
n_categories = len(categories)
|
||||||
|
colors = get_palette(task, n_categories + 2)[1:-1]
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Bar(
|
||||||
|
x=categories,
|
||||||
|
y=counts.to_numpy(),
|
||||||
|
marker_color=colors,
|
||||||
|
text=counts.to_numpy(),
|
||||||
|
textposition="outside",
|
||||||
|
textfont={"size": 12},
|
||||||
|
hovertemplate="<b>%{x}</b><br>Count: %{y}<br>Percentage: %{customdata:.1%}<extra></extra>",
|
||||||
|
customdata=counts.to_numpy() / counts.sum(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
title=f"Predicted Class Distribution ({task.replace('_', ' ').title()})",
|
||||||
|
xaxis_title="Predicted Class",
|
||||||
|
yaxis_title="Count",
|
||||||
|
height=500,
|
||||||
|
showlegend=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_xaxes(tickangle=-45)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Histogram for regression
|
||||||
|
values = predictions_gdf["predicted"].to_numpy()
|
||||||
|
|
||||||
|
# Remove NaN values
|
||||||
|
values = values[~np.isnan(values)]
|
||||||
|
|
||||||
|
# Create histogram
|
||||||
|
fig.add_trace(
|
||||||
|
go.Histogram(
|
||||||
|
x=values,
|
||||||
|
nbinsx=50,
|
||||||
|
marker_color=mcolors.to_hex(get_cmap(task)(0.6)),
|
||||||
|
opacity=0.7,
|
||||||
|
hovertemplate="<b>Range:</b> %{x}<br><b>Count:</b> %{y}<extra></extra>",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add statistical lines
|
||||||
|
mean_val = np.mean(values)
|
||||||
|
median_val = np.median(values)
|
||||||
|
|
||||||
|
fig.add_vline(
|
||||||
|
x=mean_val,
|
||||||
|
line_dash="dash",
|
||||||
|
line_color="red",
|
||||||
|
annotation_text=f"Mean: {mean_val:.3f}",
|
||||||
|
annotation_position="top",
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_vline(
|
||||||
|
x=median_val,
|
||||||
|
line_dash="dot",
|
||||||
|
line_color="green",
|
||||||
|
annotation_text=f"Median: {median_val:.3f}",
|
||||||
|
annotation_position="bottom right",
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
title=f"Predicted Value Distribution ({task.replace('_', ' ').title()})",
|
||||||
|
xaxis_title=f"Predicted {task.capitalize()}",
|
||||||
|
yaxis_title="Count",
|
||||||
|
height=500,
|
||||||
|
showlegend=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
return fig
|
||||||
|
|
||||||
|
|
||||||
|
def create_prediction_statistics_plot(
|
||||||
|
predictions_gdf: gpd.GeoDataFrame,
|
||||||
|
task: Task,
|
||||||
|
) -> go.Figure:
|
||||||
|
"""Create a plot showing key statistics about the predictions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with 'predicted' column
|
||||||
|
task: Task type
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Plotly Figure with statistics
|
||||||
|
|
||||||
|
"""
|
||||||
|
classification_tasks: list[Task] = ["binary", "count_regimes", "density_regimes"]
|
||||||
|
is_classification = task in classification_tasks
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
# Classification statistics: class proportions
|
||||||
|
# Convert to categorical if needed
|
||||||
|
if predictions_gdf["predicted"].dtype != "category":
|
||||||
|
predictions_gdf["predicted"] = pd.Categorical(predictions_gdf["predicted"])
|
||||||
|
|
||||||
|
categories = predictions_gdf["predicted"].cat.categories.tolist()
|
||||||
|
counts = predictions_gdf["predicted"].value_counts().reindex(categories, fill_value=0)
|
||||||
|
proportions = counts / counts.sum()
|
||||||
|
|
||||||
|
# Get colors
|
||||||
|
n_categories = len(categories)
|
||||||
|
colors = get_palette(task, n_categories + 2)[1:-1]
|
||||||
|
|
||||||
|
fig = go.Figure()
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Bar(
|
||||||
|
x=categories,
|
||||||
|
y=proportions.to_numpy() * 100, # Convert to percentage
|
||||||
|
marker_color=colors,
|
||||||
|
text=[f"{p:.1%}" for p in proportions.to_numpy()],
|
||||||
|
textposition="outside",
|
||||||
|
hovertemplate="<b>%{x}</b><br>Proportion: %{y:.1f}%<extra></extra>",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
title="Predicted Class Proportions",
|
||||||
|
xaxis_title="Predicted Class",
|
||||||
|
yaxis_title="Proportion (%)",
|
||||||
|
height=400,
|
||||||
|
showlegend=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_xaxes(tickangle=-45)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Regression statistics: box plot with quartiles
|
||||||
|
values = predictions_gdf["predicted"].to_numpy()
|
||||||
|
values = values[~np.isnan(values)]
|
||||||
|
|
||||||
|
fig = go.Figure()
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Box(
|
||||||
|
y=values,
|
||||||
|
name="Predictions",
|
||||||
|
marker_color=mcolors.to_hex(get_cmap(task)(0.6)),
|
||||||
|
boxmean="sd", # Show mean and standard deviation
|
||||||
|
hovertemplate="<b>Value:</b> %{y:.3f}<extra></extra>",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Calculate statistics
|
||||||
|
stats = pd.Series(values).describe()
|
||||||
|
|
||||||
|
# Add annotation with statistics
|
||||||
|
stats_text = (
|
||||||
|
f"<b>Statistics</b><br>"
|
||||||
|
f"Count: {int(stats['count'])}<br>"
|
||||||
|
f"Mean: {stats['mean']:.3f}<br>"
|
||||||
|
f"Std: {stats['std']:.3f}<br>"
|
||||||
|
f"Min: {stats['min']:.3f}<br>"
|
||||||
|
f"25%: {stats['25%']:.3f}<br>"
|
||||||
|
f"50%: {stats['50%']:.3f}<br>"
|
||||||
|
f"75%: {stats['75%']:.3f}<br>"
|
||||||
|
f"Max: {stats['max']:.3f}"
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_annotation(
|
||||||
|
text=stats_text,
|
||||||
|
xref="paper",
|
||||||
|
yref="paper",
|
||||||
|
x=1.15,
|
||||||
|
y=0.5,
|
||||||
|
showarrow=False,
|
||||||
|
align="left",
|
||||||
|
bgcolor="rgba(255, 255, 255, 0.8)",
|
||||||
|
bordercolor="black",
|
||||||
|
borderwidth=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
title=f"Prediction Statistics ({task.replace('_', ' ').title()})",
|
||||||
|
yaxis_title=f"Predicted {task.capitalize()}",
|
||||||
|
height=500,
|
||||||
|
showlegend=False,
|
||||||
|
margin={"r": 200}, # Make room for stats annotation
|
||||||
|
)
|
||||||
|
|
||||||
|
return fig
|
||||||
|
|
||||||
|
|
||||||
|
def create_coverage_statistics_table(
|
||||||
|
predictions_gdf: gpd.GeoDataFrame, task: Task, grid_gdf: gpd.GeoDataFrame | None = None
|
||||||
|
) -> pd.DataFrame:
|
||||||
|
"""Create a summary table of prediction coverage statistics.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with predictions
|
||||||
|
task: Task type
|
||||||
|
grid_gdf: Optional GeoDataFrame with cell_id and land_area columns for RTS area calculations
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DataFrame with coverage statistics
|
||||||
|
|
||||||
|
"""
|
||||||
|
classification_tasks: list[Task] = ["binary", "count_regimes", "density_regimes"]
|
||||||
|
is_classification = task in classification_tasks
|
||||||
|
|
||||||
|
stats = {
|
||||||
|
"Total Cells": len(predictions_gdf),
|
||||||
|
"Non-null Predictions": predictions_gdf["predicted"].notna().sum(),
|
||||||
|
"Null Predictions": predictions_gdf["predicted"].isna().sum(),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Calculate RTS-affected area if grid_gdf is provided
|
||||||
|
if grid_gdf is not None:
|
||||||
|
# Merge with grid to get land areas
|
||||||
|
merged = predictions_gdf.merge(grid_gdf[["cell_id", "land_area"]], on="cell_id", how="left")
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
# Convert to categorical if needed
|
||||||
|
if merged["predicted"].dtype != "category":
|
||||||
|
merged["predicted"] = pd.Categorical(merged["predicted"])
|
||||||
|
|
||||||
|
categories = merged["predicted"].cat.categories.tolist()
|
||||||
|
|
||||||
|
# For classification: sum areas where RTS are expected (non-zero classes)
|
||||||
|
# Assuming first category is "no RTS" (0 or similar)
|
||||||
|
rts_mask = merged["predicted"].notna()
|
||||||
|
if len(categories) > 1:
|
||||||
|
# Exclude the first category (assumed to be "no RTS")
|
||||||
|
rts_mask = rts_mask & (merged["predicted"] != categories[0])
|
||||||
|
|
||||||
|
rts_area_km2 = merged.loc[rts_mask, "land_area"].sum() / 1e6 # Convert m² to km²
|
||||||
|
stats["RTS-Affected Area (km²)"] = f"{rts_area_km2:,.2f}"
|
||||||
|
|
||||||
|
elif task == "count":
|
||||||
|
# For count: sum areas where count > 0
|
||||||
|
rts_mask = (merged["predicted"].notna()) & (merged["predicted"] > 0)
|
||||||
|
rts_area_km2 = merged.loc[rts_mask, "land_area"].sum() / 1e6 # Convert m² to km²
|
||||||
|
stats["RTS-Affected Area (km²)"] = f"{rts_area_km2:,.2f}"
|
||||||
|
|
||||||
|
elif task == "density":
|
||||||
|
# For density: multiply predicted density by area
|
||||||
|
# Density is typically RTS/km², so multiply by area in km²
|
||||||
|
merged["rts_area"] = merged["predicted"] * merged["land_area"] / 1e6 # density * area_km2
|
||||||
|
total_rts_area = merged["rts_area"].sum()
|
||||||
|
stats["Total RTS Area (km²)"] = f"{total_rts_area:,.2f}"
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
# Add class counts
|
||||||
|
# Convert to categorical if needed
|
||||||
|
if predictions_gdf["predicted"].dtype != "category":
|
||||||
|
predictions_gdf["predicted"] = pd.Categorical(predictions_gdf["predicted"])
|
||||||
|
|
||||||
|
categories = predictions_gdf["predicted"].cat.categories.tolist()
|
||||||
|
for cat in categories:
|
||||||
|
count = (predictions_gdf["predicted"] == cat).sum()
|
||||||
|
stats[f"Class '{cat}' Count"] = count
|
||||||
|
stats[f"Class '{cat}' Proportion"] = f"{count / len(predictions_gdf):.2%}"
|
||||||
|
else:
|
||||||
|
# Add regression statistics
|
||||||
|
values = predictions_gdf["predicted"].dropna()
|
||||||
|
if len(values) > 0:
|
||||||
|
stats["Mean"] = f"{values.mean():.4f}"
|
||||||
|
stats["Median"] = f"{values.median():.4f}"
|
||||||
|
stats["Std Dev"] = f"{values.std():.4f}"
|
||||||
|
stats["Min"] = f"{values.min():.4f}"
|
||||||
|
stats["Max"] = f"{values.max():.4f}"
|
||||||
|
|
||||||
|
# Convert to DataFrame
|
||||||
|
df = pd.DataFrame(list(stats.items()), columns=["Statistic", "Value"])
|
||||||
|
return df
|
||||||
106
src/entropice/dashboard/sections/inference.py
Normal file
106
src/entropice/dashboard/sections/inference.py
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
"""Sections for the inference page."""
|
||||||
|
|
||||||
|
import geopandas as gpd
|
||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
from entropice.dashboard.plots.inference import (
|
||||||
|
create_coverage_statistics_table,
|
||||||
|
create_inference_map,
|
||||||
|
create_prediction_distribution_plot,
|
||||||
|
create_prediction_statistics_plot,
|
||||||
|
)
|
||||||
|
from entropice.utils.types import Task
|
||||||
|
|
||||||
|
|
||||||
|
def render_inference_map_section(predictions_gdf: gpd.GeoDataFrame, task: Task) -> None:
|
||||||
|
"""Render the inference map section.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with predictions and geometries
|
||||||
|
task: Task type
|
||||||
|
|
||||||
|
"""
|
||||||
|
st.subheader("📍 Spatial Prediction Map")
|
||||||
|
|
||||||
|
st.markdown(
|
||||||
|
"""
|
||||||
|
Interactive map showing model predictions across the Arctic region.
|
||||||
|
Toggle 3D mode to see predictions as elevated terrain.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3D toggle
|
||||||
|
col1, col2 = st.columns([1, 4])
|
||||||
|
with col1:
|
||||||
|
make_3d = st.checkbox("3D View", value=False, key="inference_map_3d")
|
||||||
|
|
||||||
|
with col2:
|
||||||
|
if make_3d:
|
||||||
|
st.info("🎨 Height represents prediction magnitude. Rotate and tilt the map to explore!")
|
||||||
|
|
||||||
|
# Create and display map
|
||||||
|
with st.spinner("Generating map..."):
|
||||||
|
deck = create_inference_map(predictions_gdf, task, make_3d)
|
||||||
|
st.pydeck_chart(deck)
|
||||||
|
|
||||||
|
|
||||||
|
def render_prediction_statistics_section(
|
||||||
|
predictions_gdf: gpd.GeoDataFrame, task: Task, grid_gdf: gpd.GeoDataFrame | None = None
|
||||||
|
) -> None:
|
||||||
|
"""Render the prediction statistics section.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with predictions
|
||||||
|
task: Task type
|
||||||
|
grid_gdf: Optional GeoDataFrame with cell_id and land_area for RTS area calculations
|
||||||
|
|
||||||
|
"""
|
||||||
|
st.subheader("📊 Prediction Statistics")
|
||||||
|
|
||||||
|
# Create two columns for statistics
|
||||||
|
col1, col2 = st.columns(2)
|
||||||
|
|
||||||
|
with col1:
|
||||||
|
st.markdown("#### Coverage Statistics")
|
||||||
|
# Create statistics table
|
||||||
|
stats_df = create_coverage_statistics_table(predictions_gdf, task, grid_gdf)
|
||||||
|
st.dataframe(stats_df, hide_index=True, width="stretch")
|
||||||
|
|
||||||
|
with col2:
|
||||||
|
st.markdown("#### Statistical Summary")
|
||||||
|
# Create statistics plot (box plot for regression, proportions for classification)
|
||||||
|
fig = create_prediction_statistics_plot(predictions_gdf, task)
|
||||||
|
st.plotly_chart(fig, width="stretch")
|
||||||
|
|
||||||
|
|
||||||
|
def render_prediction_distribution_section(predictions_gdf: gpd.GeoDataFrame, task: Task) -> None:
|
||||||
|
"""Render the prediction distribution section.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
predictions_gdf: GeoDataFrame with predictions
|
||||||
|
task: Task type
|
||||||
|
|
||||||
|
"""
|
||||||
|
classification_tasks: list[Task] = ["binary", "count_regimes", "density_regimes"]
|
||||||
|
is_classification = task in classification_tasks
|
||||||
|
|
||||||
|
if is_classification:
|
||||||
|
st.subheader("📈 Class Distribution")
|
||||||
|
st.markdown(
|
||||||
|
"""
|
||||||
|
Distribution of predicted classes across all grid cells.
|
||||||
|
Shows the count and proportion of each predicted class.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
st.subheader("📈 Value Distribution")
|
||||||
|
st.markdown(
|
||||||
|
"""
|
||||||
|
Distribution of predicted values across all grid cells.
|
||||||
|
Histogram shows the frequency of predictions in different value ranges.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create and display distribution plot
|
||||||
|
fig = create_prediction_distribution_plot(predictions_gdf, task)
|
||||||
|
st.plotly_chart(fig, width="stretch")
|
||||||
|
|
@ -1,8 +1,15 @@
|
||||||
"""Inference page: Visualization of model inference results across the study region."""
|
"""Inference page: Visualization of model inference results across the study region."""
|
||||||
|
|
||||||
|
import geopandas as gpd
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
from stopuhr import stopwatch
|
from stopuhr import stopwatch
|
||||||
|
|
||||||
|
import entropice.utils.paths
|
||||||
|
from entropice.dashboard.sections.inference import (
|
||||||
|
render_inference_map_section,
|
||||||
|
render_prediction_distribution_section,
|
||||||
|
render_prediction_statistics_section,
|
||||||
|
)
|
||||||
from entropice.dashboard.utils.loaders import TrainingResult, load_all_training_results
|
from entropice.dashboard.utils.loaders import TrainingResult, load_all_training_results
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -77,15 +84,27 @@ def render_inference_page():
|
||||||
# Main content area
|
# Main content area
|
||||||
# Load predictions
|
# Load predictions
|
||||||
with st.spinner("Loading inference results..."):
|
with st.spinner("Loading inference results..."):
|
||||||
# Columns: Index(['cell_id', 'predicted', 'geometry'], dtype='object')
|
# Columns: ['cell_id', 'predicted', 'geometry']
|
||||||
predictions_gdf = selected_result.run.predictions
|
predictions_gdf = selected_result.run.predictions
|
||||||
task = selected_result.run.task
|
task = selected_result.run.task
|
||||||
|
# Reading the data takes for the largest grids ~1.7s
|
||||||
|
gridfile = entropice.utils.paths.get_grid_file(
|
||||||
|
selected_result.run.dataset.grid, selected_result.run.dataset.level
|
||||||
|
)
|
||||||
|
grid_gdf = gpd.read_parquet(gridfile, columns=["cell_id", "land_area", "geometry"])
|
||||||
|
|
||||||
# TODO: Implement the sections
|
# Section 1: Spatial Map
|
||||||
# Map, optionally 3D
|
render_inference_map_section(predictions_gdf, task)
|
||||||
# Some statistics about the predictions
|
|
||||||
# Class Distribution for classification tasks
|
|
||||||
# Distribution of predicted values for regression tasks
|
|
||||||
|
|
||||||
st.balloons()
|
st.divider()
|
||||||
|
|
||||||
|
# Section 2: Prediction Statistics
|
||||||
|
render_prediction_statistics_section(predictions_gdf, task, grid_gdf)
|
||||||
|
|
||||||
|
st.divider()
|
||||||
|
|
||||||
|
# Section 3: Distribution Analysis
|
||||||
|
render_prediction_distribution_section(predictions_gdf, task)
|
||||||
|
|
||||||
|
st.success("✅ Inference visualization complete!")
|
||||||
stopwatch.summary()
|
stopwatch.summary()
|
||||||
|
|
|
||||||
|
|
@ -11,30 +11,186 @@ from entropice.ml.dataset import DatasetEnsemble
|
||||||
from entropice.ml.hpsearchcv import RunSettings as HPOCVRunSettings
|
from entropice.ml.hpsearchcv import RunSettings as HPOCVRunSettings
|
||||||
from entropice.ml.hpsearchcv import hpsearch_cv
|
from entropice.ml.hpsearchcv import hpsearch_cv
|
||||||
from entropice.utils.paths import RESULTS_DIR
|
from entropice.utils.paths import RESULTS_DIR
|
||||||
from entropice.utils.types import Grid, Model, TargetDataset, Task
|
from entropice.utils.types import Grid, L2SourceDataset, Model, TargetDataset, Task
|
||||||
|
|
||||||
cli = cyclopts.App("entropice-feature-importance")
|
cli = cyclopts.App("entropice-feature-importance")
|
||||||
|
|
||||||
DEV = False
|
|
||||||
|
|
||||||
EXPERIMENT_NAME = "feature_importance_era5-shoulder_arcticdem-v2"
|
EXPERIMENT_NAME = "feature_importance_era5-shoulder_arcticdem-v2"
|
||||||
if DEV:
|
|
||||||
EXPERIMENT_NAME = "tobis-final-tests"
|
all_features = None
|
||||||
|
univariate_features = [
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"era5_freezing_days_AMJ",
|
||||||
|
"era5_freezing_days_JAS",
|
||||||
|
"era5_freezing_days_trend_JAS",
|
||||||
|
"era5_freezing_degree_days_AMJ",
|
||||||
|
"era5_freezing_degree_days_JAS",
|
||||||
|
"era5_freezing_degree_days_JFM",
|
||||||
|
"era5_freezing_degree_days_trend_JAS",
|
||||||
|
"era5_freezing_degree_days_trend_JFM",
|
||||||
|
"era5_freezing_degree_days_trend_OND",
|
||||||
|
"era5_precipitation_occurrences_AMJ",
|
||||||
|
"era5_precipitation_occurrences_OND",
|
||||||
|
"era5_sf_JAS",
|
||||||
|
"era5_snowc_mean_trend_JAS",
|
||||||
|
"era5_snowfall_occurrences_JAS",
|
||||||
|
"era5_snowfall_occurrences_trend_JAS",
|
||||||
|
"era5_sshf_JFM",
|
||||||
|
"era5_sshf_OND",
|
||||||
|
"era5_t2m_avg_AMJ",
|
||||||
|
"era5_t2m_avg_JAS",
|
||||||
|
"era5_t2m_avg_JFM",
|
||||||
|
"era5_t2m_avg_trend_JFM",
|
||||||
|
"era5_t2m_avg_trend_OND",
|
||||||
|
"era5_t2m_max_AMJ",
|
||||||
|
"era5_t2m_max_JAS",
|
||||||
|
"era5_t2m_max_JFM",
|
||||||
|
"era5_t2m_max_OND",
|
||||||
|
"era5_t2m_max_trend_OND",
|
||||||
|
"era5_t2m_mean_AMJ",
|
||||||
|
"era5_t2m_mean_JAS",
|
||||||
|
"era5_t2m_mean_JFM",
|
||||||
|
"era5_t2m_mean_trend_JFM",
|
||||||
|
"era5_t2m_mean_trend_OND",
|
||||||
|
"era5_t2m_min_AMJ",
|
||||||
|
"era5_t2m_min_trend_JAS",
|
||||||
|
"era5_t2m_min_trend_JFM",
|
||||||
|
"era5_t2m_range_AMJ",
|
||||||
|
"era5_t2m_range_JAS",
|
||||||
|
"era5_t2m_skew_JAS",
|
||||||
|
"era5_thawing_days_AMJ",
|
||||||
|
"era5_thawing_days_JAS",
|
||||||
|
"era5_thawing_days_trend_JAS",
|
||||||
|
"era5_thawing_degree_days_AMJ",
|
||||||
|
"era5_thawing_degree_days_JAS",
|
||||||
|
"era5_tp_AMJ",
|
||||||
|
"era5_tp_JAS",
|
||||||
|
]
|
||||||
|
cluster_features = [
|
||||||
|
"cell_area",
|
||||||
|
"water_area",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"arcticdem_aspect_median",
|
||||||
|
"arcticdem_curvature_median",
|
||||||
|
"arcticdem_dem_median",
|
||||||
|
"arcticdem_slope_median",
|
||||||
|
"era5_effective_snow_depth_trend_AMJ",
|
||||||
|
"era5_effective_snow_depth_trend_JAS",
|
||||||
|
"era5_effective_snow_depth_trend_JFM",
|
||||||
|
"era5_effective_snow_depth_trend_OND",
|
||||||
|
"era5_freezing_days_AMJ",
|
||||||
|
"era5_freezing_days_JAS",
|
||||||
|
"era5_freezing_days_JFM",
|
||||||
|
"era5_freezing_days_OND",
|
||||||
|
"era5_freezing_days_trend_AMJ",
|
||||||
|
"era5_freezing_days_trend_OND",
|
||||||
|
"era5_freezing_degree_days_trend_AMJ",
|
||||||
|
"era5_freezing_degree_days_trend_JFM",
|
||||||
|
"era5_freezing_degree_days_trend_OND",
|
||||||
|
"era5_lblt_max_JAS",
|
||||||
|
"era5_lblt_max_trend_AMJ",
|
||||||
|
"era5_lblt_max_trend_JAS",
|
||||||
|
"era5_lblt_max_trend_JFM",
|
||||||
|
"era5_lblt_max_trend_OND",
|
||||||
|
"era5_precipitation_occurrences_AMJ",
|
||||||
|
"era5_precipitation_occurrences_JFM",
|
||||||
|
"era5_precipitation_occurrences_trend_AMJ",
|
||||||
|
"era5_precipitation_occurrences_trend_JAS",
|
||||||
|
"era5_precipitation_occurrences_trend_JFM",
|
||||||
|
"era5_precipitation_occurrences_trend_OND",
|
||||||
|
"era5_sf_AMJ",
|
||||||
|
"era5_sf_trend_AMJ",
|
||||||
|
"era5_sf_trend_JAS",
|
||||||
|
"era5_snowc_mean_JFM",
|
||||||
|
"era5_snowc_mean_trend_AMJ",
|
||||||
|
"era5_snowc_mean_trend_OND",
|
||||||
|
"era5_sshf_AMJ",
|
||||||
|
"era5_sshf_JFM",
|
||||||
|
"era5_sshf_trend_AMJ",
|
||||||
|
"era5_sshf_trend_JFM",
|
||||||
|
"era5_t2m_avg_trend_AMJ",
|
||||||
|
"era5_t2m_avg_trend_JAS",
|
||||||
|
"era5_t2m_max_AMJ",
|
||||||
|
"era5_t2m_max_trend_JAS",
|
||||||
|
"era5_t2m_max_trend_JFM",
|
||||||
|
"era5_t2m_max_trend_OND",
|
||||||
|
"era5_t2m_min_JFM",
|
||||||
|
"era5_t2m_min_trend_OND",
|
||||||
|
"era5_t2m_range_JFM",
|
||||||
|
"era5_t2m_range_trend_AMJ",
|
||||||
|
"era5_t2m_range_trend_JFM",
|
||||||
|
"era5_t2m_skew_trend_AMJ",
|
||||||
|
"era5_t2m_skew_trend_JAS",
|
||||||
|
"era5_t2m_skew_trend_JFM",
|
||||||
|
"era5_t2m_skew_trend_OND",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@cli.default
|
@cli.default
|
||||||
def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster", "univariate"] = "none"):
|
def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster", "univariate"] = "none"):
|
||||||
"""Feature Importance Experiment."""
|
"""Feature Importance Experiment."""
|
||||||
|
experiment_name = EXPERIMENT_NAME
|
||||||
|
if selection != "none":
|
||||||
|
experiment_name += f"_{selection=}"
|
||||||
levels = [3, 4, 5, 6] if grid == "hex" else [6, 7, 8, 9, 10]
|
levels = [3, 4, 5, 6] if grid == "hex" else [6, 7, 8, 9, 10]
|
||||||
if DEV:
|
|
||||||
levels = [3, 6] if grid == "hex" else [6, 10]
|
|
||||||
for level in levels:
|
for level in levels:
|
||||||
print(f"Running feature importance experiment for {grid} grid at level {level}...")
|
print(f"Running feature importance experiment for {grid} grid at level {level}...")
|
||||||
|
members: list[L2SourceDataset] = ["ArcticDEM", "ERA5-shoulder"]
|
||||||
dimension_filters = {"ArcticDEM": {"aggregations": ["median"]}}
|
dimension_filters = {"ArcticDEM": {"aggregations": ["median"]}}
|
||||||
if (grid == "hex" and level in [3, 4]) or (grid == "healpix" and level in [6, 7]):
|
is_era5_median_grid = (grid == "hex" and level in [3, 4]) or (grid == "healpix" and level in [6, 7])
|
||||||
|
is_era5_mean_grid = (grid == "hex" and level in [5]) or (grid == "healpix" and level in [8, 9])
|
||||||
|
if is_era5_median_grid:
|
||||||
dimension_filters["ERA5-shoulder"] = {"aggregations": ["median"]}
|
dimension_filters["ERA5-shoulder"] = {"aggregations": ["median"]}
|
||||||
|
|
||||||
|
feature_filters = {
|
||||||
|
"none": all_features,
|
||||||
|
"cluster": cluster_features,
|
||||||
|
"univariate": univariate_features,
|
||||||
|
}[selection]
|
||||||
|
if feature_filters is not None:
|
||||||
|
if not any(f.startswith("arcticdem") for f in feature_filters):
|
||||||
|
dimension_filters.pop("ArcticDEM", None)
|
||||||
|
members.remove("ArcticDEM")
|
||||||
|
if not any(f.startswith("era5") for f in feature_filters):
|
||||||
|
dimension_filters.pop("ERA5-shoulder", None)
|
||||||
|
members.remove("ERA5-shoulder")
|
||||||
|
elif is_era5_median_grid:
|
||||||
|
|
||||||
|
def _add_median(feature: str) -> str:
|
||||||
|
if not feature.startswith("era5"):
|
||||||
|
return feature
|
||||||
|
return (
|
||||||
|
feature.replace("JAS", "median_JAS")
|
||||||
|
.replace("AMJ", "median_AMJ")
|
||||||
|
.replace("JFM", "median_JFM")
|
||||||
|
.replace("OND", "median_OND")
|
||||||
|
)
|
||||||
|
|
||||||
|
feature_filters = [_add_median(f) for f in feature_filters]
|
||||||
|
|
||||||
|
elif is_era5_mean_grid:
|
||||||
|
|
||||||
|
def _add_mean(feature: str) -> str:
|
||||||
|
if not feature.startswith("era5"):
|
||||||
|
return feature
|
||||||
|
return (
|
||||||
|
feature.replace("JAS", "mean_JAS")
|
||||||
|
.replace("AMJ", "mean_AMJ")
|
||||||
|
.replace("JFM", "mean_JFM")
|
||||||
|
.replace("OND", "mean_OND")
|
||||||
|
)
|
||||||
|
|
||||||
|
feature_filters = [_add_mean(f) for f in feature_filters]
|
||||||
|
|
||||||
dataset_ensemble = DatasetEnsemble(
|
dataset_ensemble = DatasetEnsemble(
|
||||||
grid=grid, level=level, members=["ArcticDEM", "ERA5-shoulder"], dimension_filters=dimension_filters
|
grid=grid,
|
||||||
|
level=level,
|
||||||
|
members=members,
|
||||||
|
dimension_filters=dimension_filters,
|
||||||
|
post_merge_filters=feature_filters,
|
||||||
)
|
)
|
||||||
|
|
||||||
for task in cast(list[Task], ["binary", "density"]):
|
for task in cast(list[Task], ["binary", "density"]):
|
||||||
|
|
@ -42,11 +198,7 @@ def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster"
|
||||||
|
|
||||||
# AutoGluon
|
# AutoGluon
|
||||||
time_limit = 30 * 60 # 30 minutes
|
time_limit = 30 * 60 # 30 minutes
|
||||||
if DEV:
|
|
||||||
time_limit = 2 * 60 # 2 minutes
|
|
||||||
presets = "extreme"
|
presets = "extreme"
|
||||||
if DEV:
|
|
||||||
presets = "medium"
|
|
||||||
settings = AutoGluonRunSettings(
|
settings = AutoGluonRunSettings(
|
||||||
time_limit=time_limit,
|
time_limit=time_limit,
|
||||||
presets=presets,
|
presets=presets,
|
||||||
|
|
@ -54,7 +206,7 @@ def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster"
|
||||||
task=task,
|
task=task,
|
||||||
target=target,
|
target=target,
|
||||||
)
|
)
|
||||||
train_autogluon(dataset_ensemble, settings, experiment=EXPERIMENT_NAME)
|
train_autogluon(dataset_ensemble, settings, experiment=experiment_name)
|
||||||
|
|
||||||
# HPOCV
|
# HPOCV
|
||||||
splitter = "stratified_shuffle" if task == "binary" else "kfold"
|
splitter = "stratified_shuffle" if task == "binary" else "kfold"
|
||||||
|
|
@ -69,10 +221,7 @@ def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster"
|
||||||
"rf": 100, # RF is slow, so we reduce the number of iterations
|
"rf": 100, # RF is slow, so we reduce the number of iterations
|
||||||
"knn": 40, # kNN hpspace is small, so we reduce the number of iterations
|
"knn": 40, # kNN hpspace is small, so we reduce the number of iterations
|
||||||
}[model]
|
}[model]
|
||||||
if DEV:
|
|
||||||
n_iter = 3
|
|
||||||
scaler = "standard" if model in ["espa", "knn"] else "none"
|
scaler = "standard" if model in ["espa", "knn"] else "none"
|
||||||
normalize = scaler != "none"
|
|
||||||
settings = HPOCVRunSettings(
|
settings = HPOCVRunSettings(
|
||||||
n_iter=n_iter,
|
n_iter=n_iter,
|
||||||
task=task,
|
task=task,
|
||||||
|
|
@ -80,13 +229,13 @@ def main(grid: Grid, target: TargetDataset, selection: Literal["none", "cluster"
|
||||||
splitter=splitter,
|
splitter=splitter,
|
||||||
model=model,
|
model=model,
|
||||||
scaler=scaler,
|
scaler=scaler,
|
||||||
normalize=normalize,
|
normalize=False,
|
||||||
)
|
)
|
||||||
hpsearch_cv(dataset_ensemble, settings, experiment=EXPERIMENT_NAME)
|
hpsearch_cv(dataset_ensemble, settings, experiment=experiment_name)
|
||||||
|
|
||||||
stopwatch.summary()
|
stopwatch.summary()
|
||||||
times = stopwatch.export()
|
times = stopwatch.export()
|
||||||
times.to_parquet(RESULTS_DIR / EXPERIMENT_NAME / f"training_times_{target}_{grid}.parquet")
|
times.to_parquet(RESULTS_DIR / experiment_name / f"training_times_{target}_{grid}.parquet")
|
||||||
print("Done.")
|
print("Done.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ from entropice.utils.types import Grid, Model, TargetDataset, Task
|
||||||
|
|
||||||
cli = cyclopts.App("entropice-feature-importance")
|
cli = cyclopts.App("entropice-feature-importance")
|
||||||
|
|
||||||
EXPERIMENT_NAME = "feature_importance_era5-shoulder_arcticdem-v2"
|
EXPERIMENT_NAME = "feature_importance_alphaearth"
|
||||||
|
|
||||||
|
|
||||||
@cli.default
|
@cli.default
|
||||||
|
|
|
||||||
1754
src/entropice/experiments/feature_importance_results.ipynb
Normal file
1754
src/entropice/experiments/feature_importance_results.ipynb
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,3 @@ external sources into the Entropice system:
|
||||||
- arcticdem: Terrain data from ArcticDEM
|
- arcticdem: Terrain data from ArcticDEM
|
||||||
- alphaearth: Satellite image embeddings from AlphaEarth/Google Earth Engine
|
- alphaearth: Satellite image embeddings from AlphaEarth/Google Earth Engine
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import alphaearth, arcticdem, darts, era5
|
|
||||||
|
|
||||||
__all__ = ["alphaearth", "arcticdem", "darts", "era5"]
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,3 @@ This package contains modules for machine learning workflows:
|
||||||
- training: Model training with eSPA, XGBoost, Random Forest, KNN
|
- training: Model training with eSPA, XGBoost, Random Forest, KNN
|
||||||
- inference: Batch prediction pipeline for trained classifiers
|
- inference: Batch prediction pipeline for trained classifiers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import autogluon, dataset, hpsearchcv, inference
|
|
||||||
|
|
||||||
__all__ = ["autogluon", "dataset", "hpsearchcv", "inference", "inference"]
|
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,7 @@ class DatasetEnsemble:
|
||||||
# ?: We can't use L2SourceDataset as types here because cyclopts can't handle Literals as dict keys
|
# ?: We can't use L2SourceDataset as types here because cyclopts can't handle Literals as dict keys
|
||||||
dimension_filters: dict[str, dict[str, list]] = field(default_factory=dict)
|
dimension_filters: dict[str, dict[str, list]] = field(default_factory=dict)
|
||||||
variable_filters: dict[str, list[str]] = field(default_factory=dict)
|
variable_filters: dict[str, list[str]] = field(default_factory=dict)
|
||||||
|
post_merge_filters: list[str] | None = None
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
# Validate filters
|
# Validate filters
|
||||||
|
|
@ -325,6 +326,15 @@ class DatasetEnsemble:
|
||||||
valid = {"x", "y", "cell_area", "land_area", "water_area", "land_ratio"}
|
valid = {"x", "y", "cell_area", "land_area", "water_area", "land_ratio"}
|
||||||
assert len(filtered - valid) == 0
|
assert len(filtered - valid) == 0
|
||||||
|
|
||||||
|
if self.post_merge_filters is not None:
|
||||||
|
assert len(self.post_merge_filters) >= 1, "Post-merge filters must be a list with one or more entries."
|
||||||
|
assert "geometry" not in self.post_merge_filters, "Filtering on 'geometry' is not supported."
|
||||||
|
assert "cell_id" not in self.post_merge_filters, "Filtering on 'cell_id' is not supported."
|
||||||
|
print(
|
||||||
|
"Warning: Post-merge filters are not checked for validity!"
|
||||||
|
" Please ensure that they are valid columns in the final merged dataset."
|
||||||
|
)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return int(self.id(), 16)
|
return int(self.id(), 16)
|
||||||
|
|
||||||
|
|
@ -349,10 +359,20 @@ class DatasetEnsemble:
|
||||||
@cache
|
@cache
|
||||||
def read_grid(self) -> gpd.GeoDataFrame:
|
def read_grid(self) -> gpd.GeoDataFrame:
|
||||||
"""Load the grid dataframe and enrich it with lat-lon information."""
|
"""Load the grid dataframe and enrich it with lat-lon information."""
|
||||||
|
# Define required columns that must always be included
|
||||||
|
required_columns = ["cell_id", "geometry"]
|
||||||
|
|
||||||
|
# Determine columns to load based on variable filters
|
||||||
if "Grid" in self.variable_filters:
|
if "Grid" in self.variable_filters:
|
||||||
columns_to_load = self.variable_filters["Grid"] + ["cell_id", "geometry"]
|
columns_to_load = list(set(self.variable_filters["Grid"] + required_columns))
|
||||||
else:
|
else:
|
||||||
columns_to_load = ["cell_id", "geometry", "cell_area", "land_area", "water_area", "land_ratio", "x", "y"]
|
default_grid_columns = ["cell_area", "land_area", "water_area", "land_ratio", "x", "y"]
|
||||||
|
columns_to_load = required_columns + default_grid_columns
|
||||||
|
|
||||||
|
# Apply post-merge filters if specified
|
||||||
|
if self.post_merge_filters is not None:
|
||||||
|
allowed_columns = set(self.post_merge_filters + required_columns)
|
||||||
|
columns_to_load = list(set(columns_to_load) & allowed_columns)
|
||||||
|
|
||||||
# Reading the data takes for the largest grids ~1.7s
|
# Reading the data takes for the largest grids ~1.7s
|
||||||
gridfile = entropice.utils.paths.get_grid_file(self.grid, self.level)
|
gridfile = entropice.utils.paths.get_grid_file(self.grid, self.level)
|
||||||
|
|
@ -557,6 +577,10 @@ class DatasetEnsemble:
|
||||||
raise NotImplementedError(f"Member {member} not implemented.")
|
raise NotImplementedError(f"Member {member} not implemented.")
|
||||||
with stopwatch("Joining datasets"):
|
with stopwatch("Joining datasets"):
|
||||||
dataset = dataset.join(member_dfs)
|
dataset = dataset.join(member_dfs)
|
||||||
|
|
||||||
|
if self.post_merge_filters is not None:
|
||||||
|
dataset = dataset[list(set(self.post_merge_filters) & set(dataset.columns))]
|
||||||
|
|
||||||
print(f"Prepared dataset with {len(dataset)} samples and {len(dataset.columns)} features.")
|
print(f"Prepared dataset with {len(dataset)} samples and {len(dataset.columns)} features.")
|
||||||
|
|
||||||
if cache_mode in ["read", "overwrite"]:
|
if cache_mode in ["read", "overwrite"]:
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,7 @@ def _compute_shap_explanation(model: Model, best_estimator: Pipeline, training_d
|
||||||
feature_names=training_data.feature_names,
|
feature_names=training_data.feature_names,
|
||||||
output_names=training_data.target_labels,
|
output_names=training_data.target_labels,
|
||||||
)
|
)
|
||||||
|
explain_kwargs = {}
|
||||||
case "rf":
|
case "rf":
|
||||||
masker = shap.maskers.Independent(data=training_data.X.as_numpy().train)
|
masker = shap.maskers.Independent(data=training_data.X.as_numpy().train)
|
||||||
explainer = TreeExplainer(
|
explainer = TreeExplainer(
|
||||||
|
|
@ -273,8 +274,10 @@ def _compute_shap_explanation(model: Model, best_estimator: Pipeline, training_d
|
||||||
data=masker,
|
data=masker,
|
||||||
feature_names=training_data.feature_names,
|
feature_names=training_data.feature_names,
|
||||||
)
|
)
|
||||||
|
explain_kwargs = {"check_additivity": False} # Additivity does not hold for RF, see
|
||||||
case "xgboost":
|
case "xgboost":
|
||||||
explainer = TreeExplainer(best_estimator.named_steps["model"], feature_names=training_data.feature_names)
|
explainer = TreeExplainer(best_estimator.named_steps["model"], feature_names=training_data.feature_names)
|
||||||
|
explain_kwargs = {"check_additivity": False} # Additivity does not hold for XGBoost, see
|
||||||
case _:
|
case _:
|
||||||
raise ValueError(f"Unknown model: {model}")
|
raise ValueError(f"Unknown model: {model}")
|
||||||
|
|
||||||
|
|
@ -288,7 +291,7 @@ def _compute_shap_explanation(model: Model, best_estimator: Pipeline, training_d
|
||||||
samples = best_estimator.named_steps["scaler"].transform(samples)
|
samples = best_estimator.named_steps["scaler"].transform(samples)
|
||||||
if "normalizer" in best_estimator.named_steps:
|
if "normalizer" in best_estimator.named_steps:
|
||||||
samples = best_estimator.named_steps["normalizer"].transform(samples)
|
samples = best_estimator.named_steps["normalizer"].transform(samples)
|
||||||
explanation = explainer(samples)
|
explanation = explainer(samples, **explain_kwargs)
|
||||||
return explanation
|
return explanation
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,3 @@ This package contains modules for spatial data processing and grid-based operati
|
||||||
- watermask: Ocean masking utilities
|
- watermask: Ocean masking utilities
|
||||||
- xvec: Extended vector operations for xarray
|
- xvec: Extended vector operations for xarray
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import aggregators, grids, watermask, xvec
|
|
||||||
|
|
||||||
__all__ = ["aggregators", "grids", "watermask", "xvec"]
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,3 @@ This package contains utility modules used across the Entropice system:
|
||||||
- paths: Centralized path management and configuration
|
- paths: Centralized path management and configuration
|
||||||
- codecs: Custom codecs for data serialization
|
- codecs: Custom codecs for data serialization
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import codecs, paths
|
|
||||||
|
|
||||||
__all__ = ["codecs", "paths"]
|
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,44 @@ class Training:
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def to_record(self) -> dict[str, Any]:
|
||||||
|
"""Convert the training run to a dictionary record for easy creation of DataFrames."""
|
||||||
|
train_metrics = {f"train_{k}": v for k, v in self.get_metrics_from_split("train").items()}
|
||||||
|
test_metrics = {f"test_{k}": v for k, v in self.get_metrics_from_split("test").items()}
|
||||||
|
complete_metrics = {f"complete_{k}": v for k, v in self.get_metrics_from_split("complete").items()}
|
||||||
|
return {
|
||||||
|
"path": self.path,
|
||||||
|
"dataset": f"{self.dataset.grid}-{self.dataset.level}{self.dataset.members}",
|
||||||
|
"grid": self.dataset.grid,
|
||||||
|
"level": self.dataset.level,
|
||||||
|
"members": self.dataset.members,
|
||||||
|
"method": type(self.method).__name__,
|
||||||
|
"task": self.task,
|
||||||
|
"target": self.target,
|
||||||
|
"model_type": self.model_type,
|
||||||
|
"run": self,
|
||||||
|
**train_metrics,
|
||||||
|
**test_metrics,
|
||||||
|
**complete_metrics,
|
||||||
|
}
|
||||||
|
|
||||||
def get_metrics_from_split(self, split: Literal["train", "test", "complete"]) -> dict[str, float]:
|
def get_metrics_from_split(self, split: Literal["train", "test", "complete"]) -> dict[str, float]:
|
||||||
"""Get a dictionary of metric names and values for the specified split."""
|
"""Get a dictionary of metric names and values for the specified split."""
|
||||||
return self.metrics[self.metrics["split"] == split].set_index("metric")["score"].to_dict() # ty:ignore[invalid-return-type]
|
metrics_df = self.metrics[self.metrics["split"] == split].copy()
|
||||||
|
# If regression task and HPOCV: remove all "neg_" from the metric names
|
||||||
|
# If regression task and AutoML: negate all pot. neg metrics to be consistent with HPOCV
|
||||||
|
if self.task not in ["binary", "count_regimes", "density_regimes"]:
|
||||||
|
if self.method_type == "HPOCV":
|
||||||
|
metrics_df["metric"] = metrics_df["metric"].str.replace("neg_", "", regex=False)
|
||||||
|
elif self.method_type == "AutoML":
|
||||||
|
neg_metrics = [
|
||||||
|
"root_mean_squared_error",
|
||||||
|
"mean_squared_error",
|
||||||
|
"mean_absolute_error",
|
||||||
|
"median_absolute_error",
|
||||||
|
]
|
||||||
|
metrics_df.loc[metrics_df["metric"].isin(neg_metrics), "score"] *= -1
|
||||||
|
return metrics_df.set_index("metric")["score"].to_dict() # ty:ignore[invalid-return-type]
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""Save the training results to the specified path."""
|
"""Save the training results to the specified path."""
|
||||||
|
|
@ -221,6 +256,10 @@ class Training:
|
||||||
target = config["target"]
|
target = config["target"]
|
||||||
model_type = config["model_type"]
|
model_type = config["model_type"]
|
||||||
|
|
||||||
|
# Legacy support for old config files
|
||||||
|
if "add_lonlat" in config["dataset"].keys():
|
||||||
|
config["dataset"].pop("add_lonlat")
|
||||||
|
|
||||||
dataset = DatasetEnsemble(**config["dataset"])
|
dataset = DatasetEnsemble(**config["dataset"])
|
||||||
|
|
||||||
method_type = config["method_type"]
|
method_type = config["method_type"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue