diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 07a53170b7..071686d373 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -14,9 +14,11 @@ build: jobs: pre_create_environment: # update mamba just in case - - mamba update --yes --quiet --name=base mamba + - mamba update --yes --quiet --name=base mamba 'zstd=1.5.2' - mamba --version + - mamba list --name=base post_create_environment: + - conda run -n ${CONDA_DEFAULT_ENV} mamba list # use conda run executable wrapper to have all env variables - conda run -n ${CONDA_DEFAULT_ENV} mamba --version - conda run -n ${CONDA_DEFAULT_ENV} pip install . --no-deps diff --git a/.zenodo.json b/.zenodo.json index 083fa51356..43d9d2638a 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -86,6 +86,11 @@ "name": "Bock, Lisa", "orcid": "0000-0001-7058-5938" }, + { + "affiliation": "DLR, Germany", + "name": "Bonnet, Pauline", + "orcid": "0000-0003-3780-0784" + }, { "affiliation": "BSC, Spain", "name": "Caron, Louis-Philippe", @@ -176,6 +181,11 @@ "name": "Hassler, Birgit", "orcid": "0000-0003-2724-709X" }, + { + "affiliation": "DLR, Germany", + "name": "Heuer, Helge", + "orcid": "0000-0003-2411-7150" + }, { "affiliation": "BSC, Spain", "name": "Hunter, Alasdair", @@ -194,6 +204,10 @@ "affiliation": "MPI for Biogeochemistry, Germany", "name": "Koirala, Sujan" }, + { + "affiliation": "DLR, Germany", + "name": "Kuehbacher, Birgit" + }, { "affiliation": "BSC, Spain", "name": "Lledó, Llorenç" @@ -263,6 +277,10 @@ "affiliation": "CICERO, Norway", "name": "Sandstad, Marit" }, + { + "affiliation": "DLR, Germany", + "name": "Sarauer, Ellen" + }, { "affiliation": "MetOffice, UK", "name": "Sellar, Alistair" @@ -338,6 +356,15 @@ "affiliation": "DLR, Germany", "name": "Kazeroni, Rémi", "orcid": "0000-0001-7205-9528" + }, + { + "affiliation": "DLR, Germany", + "name": "Kraft, Jeremy" + }, + { + "affiliation": "University of Bremen, Germany", + "name": "Ruhe, Lukas", + "orcid": "0000-0001-6349-9118" } ], "description": "ESMValTool: A community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP.", diff --git a/CITATION.cff b/CITATION.cff index 49226a7fda..b6f6d45f77 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -181,6 +181,11 @@ authors: family-names: Hassler given-names: Birgit orcid: "https://orcid.org/0000-0003-2724-709X" + - + affiliation: "DLR, Germany" + family-names: Heuer + given-names: Helge + orcid: "https://orcid.org/0000-0003-2411-7150" - affiliation: "BSC, Spain" family-names: Hunter @@ -199,6 +204,10 @@ authors: affiliation: "MPI for Biogeochemistry, Germany" family-names: Koirala given-names: Sujan + - + affiliation: "DLR, Germany" + family-names: Kuehbacher + given-names: Birgit - affiliation: "BSC, Spain" family-names: Lledó @@ -300,6 +309,10 @@ authors: family-names: Weigel given-names: Katja orcid: "https://orcid.org/0000-0001-6133-7801" + - + affiliation: "DLR, Germany" + family-names: Sarauer + given-names: Ellen - affiliation: "University of Reading, UK" family-names: Roberts @@ -354,6 +367,20 @@ authors: family-names: Beucher given-names: Romain orcid: "https://orcid.org/0000-0003-3891-5444" + - + affiliation: "DLR, Germany" + family-names: Kraft + given-names: Jeremy + - + affiliation: "University of Bremen, Germany" + family-names: Ruhe + given-names: Lukas + orcid: "https://orcid.org/0000-0001-6349-9118" + - + affiliation: "DLR, Germany" + family-names: Bonnet + given-names: Pauline + orcid: "https://orcid.org/0000-0003-3780-0784" cff-version: 1.2.0 date-released: 2023-07-06 diff --git a/conda-linux-64.lock b/conda-linux-64.lock index c7e91c6a20..128ace6209 100644 --- a/conda-linux-64.lock +++ b/conda-linux-64.lock @@ -13,35 +13,32 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-hab24e00_0.tar.bz2#19410c3df09dfb12d1206132a1d357c5 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-2.6.32-he073ed8_16.conda#7ca122655873935e02c91279c5b03c8c https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda#7aca3059a1729aa76c597603f10b0dd3 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-devel_linux-64-13.1.0-he3cc6c4_0.conda#5ec50dcd74ba7461709c4ac9c4cc4190 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.1.0-h15d22d2_0.conda#afb656a334c409dd9805508af1c89c7a -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-devel_linux-64-13.1.0-he3cc6c4_0.conda#e703914ad2288ab24cf5ac94d812fc11 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.1.0-hfd8a6a1_0.conda#067bcc23164642f4c226da631f2a2e1d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-devel_linux-64-13.2.0-ha9c7c90_2.conda#401c5cf212e568dab47e0677a000d2a7 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-devel_linux-64-13.2.0-ha9c7c90_2.conda#a0bf59008336aa76ad2a097a652c60bd +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_2.conda#9172c297304f2a20134fc56c97fbe229 https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda#d8d7293c5b37f39b2ac32940621c6592 -https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-3_cp311.conda#c2e2630ddb68cf52eec74dc7dfab20b5 +https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda#d786502c97404c94d7d58d258a445a65 https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda#939e3e74d8be4dac89ce83b20de2492a https://conda.anaconda.org/conda-forge/linux-64/xorg-imake-1.0.7-0.tar.bz2#23acfc5a339a6a34cc2241f64e4111be https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.1.0-h69a702a_0.conda#506dc07710dd5b0ba63cbf134897fc10 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.1.0-he5830b7_0.conda#56ca14d57ac29a75d23a39eb3ee0ddeb +https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_2.conda#e2042154faafe61969556f28bade94b9 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.12-he073ed8_16.conda#071ea8dceff4d30ac511f4a2f8437cd1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.40-hf600244_0.conda#33084421a8c0af6aef1b439707f7662a https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.1.0-he5830b7_0.conda#cd93f779ff018dd85c7544c015c9db3c +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_2.conda#c28003b0be0494f9a7664389146716ff https://conda.anaconda.org/conda-forge/linux-64/aom-3.5.0-h27087fc_0.tar.bz2#a08150fd2298460cd1fcccf626305642 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h7f98852_4.tar.bz2#a1fd65c7ccbf10880423d82bca54eb54 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.19.1-hd590300_0.conda#e8c18d865be43e2fb3f7a145b6adf1f5 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 -https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hc118613_108.conda#6fa90698000b05dfe8ce6515794fe71a https://conda.anaconda.org/conda-forge/linux-64/freexl-1.0.6-h166bdaf_1.tar.bz2#897e772a157faf3330d72dd291486f62 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2#ac7bc6a654f8f41b352b38f4051135f8 https://conda.anaconda.org/conda-forge/linux-64/geos-3.11.2-hcb278e6_0.conda#3b8e364995e3575e57960d29c1e5ab14 https://conda.anaconda.org/conda-forge/linux-64/gettext-0.21.1-h27087fc_0.tar.bz2#14947d8770185e5153fdd04d4673ed37 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-he1b5a44_1004.tar.bz2#cddaf2c63ea4a5901cf09524c490ecdc -https://conda.anaconda.org/conda-forge/linux-64/ghostscript-9.54.0-h27087fc_2.tar.bz2#c3b35ac18d09ffc8d46064fb09a696af +https://conda.anaconda.org/conda-forge/linux-64/ghostscript-10.02.0-h59595ed_0.conda#8ab9369b573e62ddf9456f1fe4dfc39d https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.1-h0b41bf4_3.conda#96f3b11872ef6fad973eac856cd2624f https://conda.anaconda.org/conda-forge/linux-64/gmp-6.2.1-h58526e2_0.tar.bz2#b94cf2db16066b242ebd26db2facbd56 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h58526e2_1001.tar.bz2#8c54672728e8ec6aa6db90cf2806d220 @@ -59,13 +56,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.18-h0b41bf4_0.conda https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-h516909a_1.tar.bz2#6f8720dff19e17ce5d48cfe7f3d2f0a3 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda#6305a3dd2752c76335295da4e581f2fd https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2#d645c6d2ac96843a2bfaccd2d62b3ac3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-ha4646dd_2.conda#78fdab09d9138851dde2b5fe2a11019e https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-h166bdaf_0.tar.bz2#b62b52da46c39ee2bc3c162ac7f1804d -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-2.1.5.1-h0b41bf4_0.conda#1edd9e67bdb90d78cea97733ff6b54e6 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-2.1.5.1-hd590300_1.conda#323e90742f0f48fc22bea908735f55e6 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.0-h7f98852_0.tar.bz2#39b1328babf85c7c3a61636d9cd50206 https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.16-h0b41bf4_1.conda#28bfe2cb11357ccc5be21101a6b7ce86 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.23-pthreads_h80387f5_0.conda#9c5ea51ccb8ffae7d06c645869d24ce6 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-ilp64-0.3.23-pthreads_h5c82d6a_0.conda#14e3fb938a49ea46df201eb105bb9068 -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.1.0-hfd8a6a1_0.conda#7594fd17fb4d1b8b0e47a6b306fe01ae +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.2.0-h7e041cc_2.conda#aa27066e2dcef56db7bc674f2230b6c9 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2#c3788462a6fbddafdb413a9f9053e58d https://conda.anaconda.org/conda-forge/linux-64/libtool-2.4.7-h27087fc_0.conda#f204c8ba400ec475452737094fb81d52 https://conda.anaconda.org/conda-forge/linux-64/libunwind-1.6.2-h9c3ff4c_0.tar.bz2#a730b2badd586580c5752cc73842e068 @@ -78,19 +74,18 @@ https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318 https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2#bb14fcb13341b81d5eb386423b9d2bac https://conda.anaconda.org/conda-forge/linux-64/make-4.3-hd18ef5c_1.tar.bz2#4049ebfd3190b580dffe76daed26155a https://conda.anaconda.org/conda-forge/linux-64/mbedtls-3.3.0-hcb278e6_0.conda#cc1213f464c357b647cc5dde5cfca881 -https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.1-h59595ed_0.conda#9c9e667050d3e258d321e63a0989ebb1 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.18.3.1-h12f7317_0.conda#c0041b39fc72c1d12139b45363c8a510 +https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.0-h59595ed_1007.conda#40ccb8318df2500f83bd868dd8fcd201 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.18.5.1-h6103f9b_1.conda#45a5f1a3859ca6547de507330afcf31a https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-hcb278e6_0.conda#681105bccc2a3f7f1a837d47d39c9179 https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda#da0ec11a6454ae19bff5b02ed881a2b1 https://conda.anaconda.org/conda-forge/linux-64/openlibm-0.8.1-h7f98852_0.tar.bz2#ba0c56761f2380babaa783b2a37b4d08 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.2-hd590300_0.conda#e5ac5227582d6c83ccf247288c0eb095 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.3-hd590300_0.conda#7bb88ce04c8deb9f7d763ae04a1da72f https://conda.anaconda.org/conda-forge/linux-64/p7zip-16.02-h9c3ff4c_1001.tar.bz2#941066943c0cac69d5aa52189451aa5f https://conda.anaconda.org/conda-forge/linux-64/pixman-0.40.0-h36c2ea0_0.tar.bz2#660e72c82f2e75a6b3fe6a6e75c79f19 https://conda.anaconda.org/conda-forge/linux-64/pkg-config-0.29.2-h36c2ea0_1008.tar.bz2#fbef41ff6a4c8140c30057466a1cdd47 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2#22dad4df6e8630e8dff2428f6f6a7036 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e -https://conda.anaconda.org/conda-forge/linux-64/rocm-smi-5.6.0-h59595ed_1.conda#2980fb3b7777f495dacd46d5cc5d74bb https://conda.anaconda.org/conda-forge/linux-64/sed-4.8-he412f7d_0.tar.bz2#7362f0042e95681f5d371c46c83ebd08 https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-h9fff704_0.conda#e6d228cd0bb74a51dd18f5bfce0b4115 https://conda.anaconda.org/conda-forge/linux-64/tzcode-2023c-h0b41bf4_0.conda#0c0533894f21c3d35697cb8378d390e2 @@ -103,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-makedepend-1.0.8-h59595ed_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h7f98852_1002.tar.bz2#06feff3d2634e3097ce2fe681474b534 https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda#bce9f945da8ad2ae9b1d7165a64d0f87 https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2#b4a4381d54784606820704f7b5f05a15 -https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.1-h0b41bf4_0.conda#e9c3bcf0e0c719431abec8ca447eee27 +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.2-hd590300_0.conda#f08fb5c89edfc4aadee1c81d4cfb1fa1 https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2#2161070d867d1b1204ea749c8eec4ef0 https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2#4cb3ad778ec2d5a7acbdf254eb1c42ae https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.0-h27087fc_3.tar.bz2#0428af0510c3fafedf1c66b43102a34b @@ -113,73 +108,71 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab7 https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda#8b9b5aca60558d02ddaa09d599e55920 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.1.0-hc4be1a9_0.conda#99d1a8a8ee1665ee9435f8d160df69fe +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.2.0-h338b0a0_2.conda#b4f2ab4faf22658cca303570fd9a7662 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h501b40f_6.conda#c3e9338e15d90106f467377017352b97 https://conda.anaconda.org/conda-forge/linux-64/libavif-0.11.1-h8182462_2.conda#41c399ed4c439e37b844c24ab5621b5a -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-17_linux64_openblas.conda#57fb44770b1bc832fb2dbefa1bd502de https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2#4d331e44109e3f0e19b4cb8f9b82f3e1 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_2.conda#e75a75a6eaf6f318dae2631158c46575 https://conda.anaconda.org/conda-forge/linux-64/libllvm14-14.0.6-hcd5def8_4.conda#73301c133ded2bf71906aa2104edae8b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.52.0-h61bc06f_0.conda#613955a50485812985c059e7b269f42e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.39-h753d276_0.conda#e1c890aebdebbfbf87e2c917187b4416 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.23.3-hd1fb520_0.conda#c8da7f04073ed0fabcb60885a4c1a722 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.23.3-hd1fb520_1.conda#78c10e8637a6f8d377f9989327d0267d https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h0d5128d_13.conda#e1d6139ff0500977a760567a4bec1ce9 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.42.0-h2797004_0.conda#fdaae20a1cf7cd62130a0973190a31b7 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.43.0-h2797004_0.conda#903fa782a9067d5934210df6d79220f6 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda#1f5a58e686b13bcfde88b93f547d23fe https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda#33277193f5b92bad9fdd230eb700929c -https://conda.anaconda.org/conda-forge/linux-64/libxgboost-1.7.6-cuda112h7a395e5_0.conda#8f5e1a6eb68812ed72cb7992f1db537d +https://conda.anaconda.org/conda-forge/linux-64/libxgboost-1.7.6-cuda112h7a395e5_2.conda#3eb1d878491539ab11baf3c911316f85 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.11.5-h0d562d8_0.conda#558ab736404275d7df61c473c1af35aa -https://conda.anaconda.org/conda-forge/linux-64/libzip-1.9.2-hc929e4a_1.tar.bz2#5b122b50e738c4be5c3f2899f010d7cf +https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda#ac79812548e7e8cf61f7b0abdef01d3b https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.0-hb012696_0.conda#14d87bdff2cbd3b1179a29fb316ed743 -https://conda.anaconda.org/conda-forge/linux-64/openblas-ilp64-0.3.23-pthreads_h3d04fff_0.conda#9787e8492f0a51a6b0498dc86f3864f9 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.40-hc3806b6_0.tar.bz2#69e2c796349cd9b273890bee0febfe1b https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-4_hd590300_perl5.conda#3e785bff761095eb7f8676f4694bd1b1 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda#47d31b792659ce70f470b5c82fdfb7a4 https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d96a0b655c8f8aacc36473a2dbb04 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.12-h27826a3_0.tar.bz2#5b8c42eb62e9fc961af70bdd6a26e168 -https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h4a2ce2d_2.conda#9ad153019bdfd939b235825eddea53bc +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda#39aa3b356d10d7e5add0c540945a0944 +https://conda.anaconda.org/conda-forge/linux-64/udunits2-2.2.28-h40f5838_1.conda#85552d64cb49f12781668779efc738ec https://conda.anaconda.org/conda-forge/linux-64/xorg-fixesproto-5.0-h7f98852_1002.tar.bz2#65ad6e1eb4aed2b0611855aff05e04f6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.4-h7391055_0.conda#93ee23f12bc2e684548181256edd2cf6 https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.4-h9c3ff4c_1.tar.bz2#21743a8d2ea0c8cfbbf8fe489b0347df https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda#68c34ec6149623be41a1933ab996a209 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.2-hfc55251_7.conda#32ae18eb2a687912fc9e92a501c0a11b +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda#04b88013080254850d6c01ed54810589 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.28-h3870b5a_0.conda#b775667301ab249f94ad2bea91fc4223 -https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.4-h0f2a231_0.conda#876286b5941933a0f558777e57d883cc +https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.5-h0f2a231_0.conda#009521b7ed97cca25f8f997f9e745976 https://conda.anaconda.org/conda-forge/linux-64/boost-cpp-1.78.0-h6582d0a_3.conda#d3c3c7698d0b878aab1b86db95407c8e https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/bwidget-1.9.14-ha770c72_1.tar.bz2#5746d6202ba2abad4a4707f2a2462795 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.10.0-hb4ffafa_0.conda#63b397207c1e039b3373dd45af045d8b -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-hca18f0e_1.conda#e1232042de76d24539a436d37597eb06 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-13.1.0-hd511a9b_0.conda#e0dead77d88f1bcc59c0e0c2f8975af1 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-13.1.0-hc4be1a9_0.conda#e6591b3c81fc5fb83e342b20a2506e80 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.10.2-hb4ffafa_0.conda#1a88c95afde6f13403492cac91352568 +https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hc118613_108.conda#6fa90698000b05dfe8ce6515794fe71a +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda#9ae35c3d96db2c94ce0cef86efdfa2cb +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-13.2.0-h76e1118_2.conda#4983e17132a8fac913475db6e7aba288 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-13.2.0-h338b0a0_2.conda#f595817f3270325ea833ef1d48d362ce https://conda.anaconda.org/conda-forge/linux-64/hdfeos2-2.20-hebf79cf_1003.conda#23bb57b64a629bc3b33379beece7f0d7 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.20.1-h81ceb04_0.conda#89a41adce7106749573d883b2f657d78 https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.6.2-h039dbb9_1.conda#29cf970521d30d113f3425b84cb250f6 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-17_linux64_openblas.conda#7ef0969b00fe3d6eef56a8151d3afb29 https://conda.anaconda.org/conda-forge/linux-64/libgit2-1.5.1-h1f77430_0.conda#16802fd0c80290248ea79a570bd83b95 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.76.4-hebfc3b9_0.conda#c6f951789c888f7bbd2dd6858eab69de -https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.0-hac7e632_1002.conda#4c4dce87e96b321308f81ba2c10d2897 -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.56.2-h3905398_0.conda#a87e780f3d9cc7cf432e47ced83a67ce -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.9.2-nocuda_h7313eea_1008.conda#3b4cad0666b5a8ec5eaf2de0ef41d6c9 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-17_linux64_openblas.conda#a2103882c46492e26500fcb56c03de8b +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.0-hebfc3b9_0.conda#e618003da3547216310088478e475945 +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.56.2-h3905398_1.conda#0b01e6ff8002994bd4ddbffcdbec7856 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.9.2-default_h554bfaf_1009.conda#9369f407667517fe52b0e8ed6965ffeb +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.24-pthreads_h413a1c8_0.conda#6e4ef6ca28655124dcde9bd500e44c32 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-ilp64-0.3.24-pthreads_h384dd9e_0.conda#a7b84e5b923e139d37e63097bd8a747e https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.5.1-h8b53f26_0.conda#8ad377fb60abab446a9f02c62b3c2190 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.5.1-h8b53f26_1.conda#5b09e13d732dda1a2bc9adc711164f4d https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.37-h0054252_1.conda#f27960e8873abb5476e96ef33bdbdccd -https://conda.anaconda.org/conda-forge/linux-64/nss-3.89-he45b914_0.conda#2745719a58eeaab6657256a3f142f099 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.92-h1d7d5a4_0.conda#22c89a3d87828fe925b310b9cdf0f574 https://conda.anaconda.org/conda-forge/linux-64/orc-1.9.0-h385abfd_1.conda#2cd5aac7ef1b4c6ac51bf521251a89b3 https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.3-h32600fe_0.conda#8287aeb8462e2d4b235eff788e75919d -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.4-hab00c5b_0_cpython.conda#1c628861a2a126b9fc9363ca1b7d014e -https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.42.0-h2c6b66d_0.conda#1192f6ec654a5bc4ee1d64bdc4a3e5cc -https://conda.anaconda.org/conda-forge/linux-64/tktable-2.10-hb7b940f_3.tar.bz2#ea4d0879e40211fa26f38d8986db1bbe -https://conda.anaconda.org/conda-forge/linux-64/udunits2-2.2.28-hc3e0081_0.tar.bz2#d4c341e0379c31e9e781d4f204726867 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.5-hab00c5b_0_cpython.conda#f0288cb82594b1cbc71111d1cd3c5422 +https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.43.0-h2c6b66d_0.conda#713f9eac95d051abe14c3774376854fe +https://conda.anaconda.org/conda-forge/linux-64/tktable-2.10-h0c5db8f_3.conda#f3936dae9fc1423662ffacd0429e2cc9 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.6-h8ee46fc_0.conda#7590b76c3d11d21caa44f3fc38ac584a https://conda.anaconda.org/conda-forge/noarch/affine-2.4.0-pyhd8ed1ab_0.conda#ae5f4ad87126c55ba3f690ef07f81d64 https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda#06006184e203b61d3525f90de394471e https://conda.anaconda.org/conda-forge/linux-64/antlr-python-runtime-4.7.2-py311h38be061_1003.tar.bz2#0ab8f8f0cae99343907fe68cda11baea -https://conda.anaconda.org/conda-forge/linux-64/arpack-3.7.0-hdefa2d7_2.tar.bz2#8763fe86163198ef1778d1d8d22bb078 https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2#c0481c9de49f040272556e2cedf42816 https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2#6c72ec3e660a51736913ef6ea68c454b https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda#3edfead7cedd1ab4400a6c588f3e75f8 @@ -191,43 +184,43 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b7 https://conda.anaconda.org/conda-forge/noarch/certifi-2023.7.22-pyhd8ed1ab_0.conda#7f3dbc9179b4dde7da98dfb151d0ad22 https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2#ebb5f5f7dc4f1a3780ef7ea7738db08c https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.2.0-pyhd8ed1ab_0.conda#313516e9a4b08b12dfb1e1cd390a96e3 -https://conda.anaconda.org/conda-forge/noarch/click-8.1.6-unix_pyh707e725_0.conda#64dbb3b205546691a61204d1cfb208e3 +https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda#f3ad426304898027fc619827ff428eca https://conda.anaconda.org/conda-forge/noarch/cloudpickle-2.2.1-pyhd8ed1ab_0.conda#b325bfc4cff7d7f8a868f1f7ecc4ed16 https://conda.anaconda.org/conda-forge/noarch/codespell-2.2.5-pyhd8ed1ab_0.conda#c73551c990f6e7e9c83cdb8bdbafdeb8 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2#3faab06a954c2a04039983f2c4a50d99 https://conda.anaconda.org/conda-forge/noarch/config-0.5.1-pyhd8ed1ab_0.tar.bz2#97275d4898af65967b1ad57923cef770 https://conda.anaconda.org/conda-forge/noarch/configargparse-1.7-pyhd8ed1ab_0.conda#0d07dc29b1c1cc973f76b74beb44915f https://conda.anaconda.org/conda-forge/noarch/cycler-0.11.0-pyhd8ed1ab_0.tar.bz2#a50559fad0affdbb33729a68669ca1cb -https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.0-py311hb755f60_0.conda#257dfede48699e2e6372528d08399e5a +https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.2-py311hb755f60_0.conda#81d4eacf7eb2d40beee33aa71e8f94ad https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/dill-0.3.7-pyhd8ed1ab_0.conda#5e4f3466526c52bc9af2d2353a1460bd https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.7-pyhd8ed1ab_0.conda#12d8aae6994f342618443a8f05c652a0 -https://conda.anaconda.org/conda-forge/linux-64/docutils-0.20.1-py311h38be061_0.conda#207175b7d514d42f977ec505800d6824 +https://conda.anaconda.org/conda-forge/linux-64/docutils-0.20.1-py311h38be061_1.conda#ff1b48b5b802afe76597197113b8e64d https://conda.anaconda.org/conda-forge/noarch/dodgy-0.2.1-py_0.tar.bz2#62a69d073f7446c90f417b0787122f5b https://conda.anaconda.org/conda-forge/noarch/ecmwf-api-client-1.6.3-pyhd8ed1ab_0.tar.bz2#15621abf59053e184114d3e1d4f9d01e https://conda.anaconda.org/conda-forge/noarch/entrypoints-0.4-pyhd8ed1ab_0.tar.bz2#3cf04868fee0a029769bd41f4b2fbf2d https://conda.anaconda.org/conda-forge/noarch/et_xmlfile-1.1.0-pyhd8ed1ab_0.conda#a2f2138597905eaa72e561d8efb42cf3 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.1.2-pyhd8ed1ab_0.conda#de4cb3384374e1411f0454edcf546cdb +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.1.3-pyhd8ed1ab_0.conda#e6518222753f519e911e83136d2158d9 https://conda.anaconda.org/conda-forge/noarch/execnet-2.0.2-pyhd8ed1ab_0.conda#67de0d8241e1060a479e3c37793e26f9 https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2#348e27e78a5e39090031448c72f66d5e -https://conda.anaconda.org/conda-forge/noarch/filelock-3.12.2-pyhd8ed1ab_0.conda#53522ec72e6adae42bd373ef58357230 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.12.4-pyhd8ed1ab_0.conda#5173d4b8267a0699a43d73231e0b6596 https://conda.anaconda.org/conda-forge/noarch/findlibs-0.0.5-pyhd8ed1ab_0.conda#8f325f63020af6f7acbe2c4cb4c920db https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda#0f69b688f52ff6da70bccb7ff7001d1d https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.0-py311h459d7ec_0.conda#54bd8f0776418b17a8eccd6f10181f95 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2023.6.0-pyh1a96a4e_0.conda#50ea2067ec92dfcc38b4f07992d7e235 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2023.9.1-pyh1a96a4e_0.conda#d69753ff6ee3c84a6638921dd95db662 https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.10-h6b639ba_2.conda#ee8220db21db8094998005990418fe5b https://conda.anaconda.org/conda-forge/noarch/geographiclib-1.52-pyhd8ed1ab_0.tar.bz2#6880e7100ebae550a33ce26663316d85 -https://conda.anaconda.org/conda-forge/linux-64/gsl-2.7-he838d99_0.tar.bz2#fec079ba39c9cca093bf4c00001825de https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda#4d8df0b0db060d33c9a702ada998a8fe https://conda.anaconda.org/conda-forge/linux-64/humanfriendly-10.0-py311h38be061_4.tar.bz2#5c4f38a9e482f00a7bf23fe479c8ca29 https://conda.anaconda.org/conda-forge/noarch/idna-3.4-pyhd8ed1ab_0.tar.bz2#34272b248891bddccc64479f9a7fffed https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda#f800d2da156d08e289b14e87e43c1ae5 https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2#3c3de74912f11d2b590184f03c7cd09b -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.4-py311h4dd048b_1.tar.bz2#46d451f575392c01dc193069bd89766d +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py311h9547e67_0.conda#f53903649188b99e6b44c560c69f5b23 https://conda.anaconda.org/conda-forge/linux-64/lazy-object-proxy-1.9.0-py311h2582759_0.conda#07745544b144855ed4514a4cf0aadd74 -https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.2-pyhd8ed1ab_0.conda#d060d017720c9882c4eca0544a4a0592 +https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.3-pyhd8ed1ab_0.conda#69ea1d0fa7ab33b48c88394ad1dead65 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.15-haa2dc70_1.conda#980d8aca0bc23ca73fa8caa3e7c84c28 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-18_linux64_openblas.conda#bcddbb497582ece559465b9cd11042e7 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.1.2-h409715c_0.conda#50c873c9660ed116707ae15b663928d8 https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-h37653c0_1015.tar.bz2#37d3747dd24d604f63d2610910576e63 https://conda.anaconda.org/conda-forge/linux-64/libpq-15.3-hbcd7760_1.conda#8afb2a97d256ffde95b91a6283bc598c @@ -238,7 +231,7 @@ https://conda.anaconda.org/conda-forge/linux-64/lxml-4.9.3-py311h1a07684_0.conda https://conda.anaconda.org/conda-forge/linux-64/lz4-4.3.2-py311h9f220a4_0.conda#b8aad2507303e04037e8d02d8ac54217 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.3-py311h459d7ec_0.conda#9904dc4adb5d547cb21e136f98cb24b0 https://conda.anaconda.org/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_0.tar.bz2#34fc335fc50eef0b5ea708f2b5f54e0c -https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.0-pyhd8ed1ab_0.conda#c7d0ea64c37752ecbe6da458aee662d2 +https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.1-pyhd8ed1ab_0.conda#1dad8397c94e4de97a70de552a7dcf49 https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.0.5-py311ha3edf6b_0.conda#7415f24f8c44e44152623d93c5015000 https://conda.anaconda.org/conda-forge/linux-64/multidict-6.0.4-py311h2582759_0.conda#8f581c14b50f2df47a2c6bd8d230a579 https://conda.anaconda.org/conda-forge/noarch/munch-4.0.0-pyhd8ed1ab_0.conda#376b32e8f9d3eacbd625f37d39bd507d @@ -246,68 +239,68 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda#4eccaeba205f0aed9ac3a9ea58568ca3 https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhd8ed1ab_0.conda#70959cd1db3cf77b2a27a0836cfd08a7 https://conda.anaconda.org/conda-forge/noarch/networkx-3.1-pyhd8ed1ab_0.conda#254f787d5068bc89f578bf63893ce8b4 -https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.4-py311h64a7726_0.conda#5a03d7c75dd4a9ae9a58850860eca468 +https://conda.anaconda.org/conda-forge/linux-64/openblas-ilp64-0.3.24-pthreads_h3d04fff_0.conda#8bd1b1f2faa8c80e6bb88b3916398c68 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-hfec8fc6_2.conda#5ce6a42505c6e9e6151c54c3ec8d68ea https://conda.anaconda.org/conda-forge/noarch/packaging-23.1-pyhd8ed1ab_0.conda#91cda59e66e1e4afe9476f8ef98f5c30 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/noarch/pathspec-0.11.2-pyhd8ed1ab_0.conda#e41debb259e68490e3ab81e46b639ab6 -https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_0.tar.bz2#89e3c7cdde7d3aaa2aee933b604dd07f -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.2.0-pyhd8ed1ab_0.conda#7263924c642d22e311d9e59b839f1b33 +https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda#405678b942f2481cecdb3e010f4925d9 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.3.0-pyhd8ed1ab_0.conda#2390bd10bed1f3fdc7a537fb5a447d8d https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.5-py311h2582759_0.conda#a90f8e278c1cd7064b2713e6b7db87e6 https://conda.anaconda.org/conda-forge/noarch/py-1.11.0-pyh6c4a22f_0.tar.bz2#b4613d7e7a493916d867842a6a148054 https://conda.anaconda.org/conda-forge/noarch/pycodestyle-2.9.1-pyhd8ed1ab_0.tar.bz2#0191dd7efe1a94262812770183b68892 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2#076becd9e05608f8dc72757d5f3a91ff https://conda.anaconda.org/conda-forge/noarch/pyflakes-2.5.0-pyhd8ed1ab_0.tar.bz2#1b3bef4313288ae8d35b1dfba4cd84a3 https://conda.anaconda.org/conda-forge/noarch/pygments-2.16.1-pyhd8ed1ab_0.conda#40e5cb18165466773619e5c963f00a7b -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.0.9-pyhd8ed1ab_0.tar.bz2#e8fbc1b54b25f4b08281467bc13b70cc +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.1-pyhd8ed1ab_0.conda#176f7d56f0cfe9008bdf1bccd7de02fb https://conda.anaconda.org/conda-forge/noarch/pyshp-2.3.1-pyhd8ed1ab_0.tar.bz2#92a889dc236a5197612bc85bee6d7174 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2#2a7de29fb590ca14b5243c4c812c8025 https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.18.0-pyhd8ed1ab_0.conda#3be9466311564f80f8056c0851fc5bb7 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2023.3-pyhd8ed1ab_0.conda#2590495f608a63625e165915fb4e2e34 -https://conda.anaconda.org/conda-forge/linux-64/python-xxhash-3.2.0-py311h2582759_0.conda#dfcc3e6e30d6ec2b2bb416fcd8ff4dc1 -https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3-pyhd8ed1ab_0.conda#d3076b483092a435832603243567bc31 -https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0-py311hd4cff14_5.tar.bz2#da8769492e423103c59f469f4f17f8d9 +https://conda.anaconda.org/conda-forge/linux-64/python-xxhash-3.3.0-py311h459d7ec_0.conda#87b306459b81b7a7aaad37222d537a4f +https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda#c93346b446cd08c169d843ae5fc0da97 +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_0.conda#30eaaf31141e785a445bf1ede6235fe3 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-25.1.1-py311h75c88c4_0.conda#af6d43afe0d179ac83b7e0c16b2caaad -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.9.2-py311h46250e7_0.conda#bcf66b5abaec47198b42cdd0bb968540 +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.10.3-py311h46250e7_0.conda#da1b2b57ac17853cfeb4197d0595db45 https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.7-py311h2582759_1.conda#5e997292429a22ad50c11af0a2cb0f08 https://conda.anaconda.org/conda-forge/noarch/semver-3.0.1-pyhd8ed1ab_0.conda#ed90854ae56fb6edae1f13b4663b21b0 https://conda.anaconda.org/conda-forge/noarch/setoptconf-tmp-0.3.1-pyhd8ed1ab_0.tar.bz2#af3e36d4effb85b9b9f93cd1db0963df -https://conda.anaconda.org/conda-forge/noarch/setuptools-68.0.0-pyhd8ed1ab_0.conda#5a7739d0f57ee64133c9d32e6507c46d +https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda#fc2166155db840c634a1291a5c35a709 https://conda.anaconda.org/conda-forge/linux-64/simplejson-3.19.1-py311h2582759_0.conda#c58e325a8500b8755e95cf0622665840 https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2#e5f25f8dbc060e9a8d912e432202afc2 https://conda.anaconda.org/conda-forge/noarch/smmap-3.0.5-pyh44b312d_0.tar.bz2#3a8dc70789709aa315325d5df06fb7e4 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2#4d22a9315e78c6827f806065957d566e https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2#6d6552722448103793743dabfbda532d -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.3.2.post1-pyhd8ed1ab_0.tar.bz2#146f4541d643d48fc8a75cacf69f03ae +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda#3f144b2c34f8cb5a9abd9ed23a39c561 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda#da1d979339e2714c30a8e806a33ec087 https://conda.anaconda.org/conda-forge/noarch/sqlparse-0.4.4-pyhd8ed1ab_0.conda#2e2f31b3b1c866c29636377e14f8c4c6 https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.10.0-h00ab1b0_0.conda#9c82b1b389e46b64ec685ec487043e70 -https://conda.anaconda.org/conda-forge/noarch/tblib-1.7.0-pyhd8ed1ab_0.tar.bz2#3d4afc31302aa7be471feb6be048ed76 -https://conda.anaconda.org/conda-forge/noarch/tenacity-8.2.2-pyhd8ed1ab_0.conda#7b39e842b52966a99e229739cd4dc36e +https://conda.anaconda.org/conda-forge/noarch/tblib-2.0.0-pyhd8ed1ab_0.conda#f5580336fe091d46f9a2ea97da044550 +https://conda.anaconda.org/conda-forge/noarch/tenacity-8.2.3-pyhd8ed1ab_0.conda#1482e77f87c6a702a7e05ef22c9b197b https://conda.anaconda.org/conda-forge/noarch/termcolor-2.3.0-pyhd8ed1ab_0.conda#440d508f025b1692168caaf436504af3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2#f832c45a477c78bebd107098db465095 https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2#5844808ffab9ebdb694585b50ba02a96 https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.1-pyha770c72_0.conda#62f5b331c53d73e2f6c4c130b53518a0 https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.0-pyhd8ed1ab_0.tar.bz2#92facfec94bc02d6ccf42e7173831a36 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.3.2-py311h459d7ec_0.conda#12b1c374ee90a1aa11ea921858394dc8 -https://conda.anaconda.org/conda-forge/noarch/traitlets-5.9.0-pyhd8ed1ab_0.conda#d0b4f5c87cd35ac3fb3d47b223263a64 -https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2023.8.7-pyhd8ed1ab_0.conda#347293fe36843c704818dcec8364409a -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.7.1-pyha770c72_0.conda#c39d6a09fe819de4951c2642629d9115 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.3.3-py311h459d7ec_0.conda#7d9a31416c18704f55946ff7cf8da5dc +https://conda.anaconda.org/conda-forge/noarch/traitlets-5.10.0-pyhd8ed1ab_0.conda#efd3f63a93621367d4fa6e274c511696 +https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2023.9.19-pyhd8ed1ab_0.conda#258560909111d84bdff089e0b2d50e43 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.8.0-pyha770c72_0.conda#5b1be40a26d10a06f6d4f1f9e19fa0c7 https://conda.anaconda.org/conda-forge/linux-64/ujson-5.7.0-py311hcafe171_0.conda#ec3960b6d13bb60aad9c67f42a801720 https://conda.anaconda.org/conda-forge/noarch/untokenize-0.1.1-py_0.tar.bz2#1447ead40f2a01733a9c8dfc32988375 -https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-py_1.tar.bz2#3563be4c5611a44210d9ba0c16113136 +https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda#daf5160ff9cde3a468556965329085b9 https://conda.anaconda.org/conda-forge/noarch/webob-1.8.7-pyhd8ed1ab_0.tar.bz2#a8192f3585f341ea66c60c189580ac67 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.41.1-pyhd8ed1ab_0.conda#8f467ba2db2b5470d297953d9c1f9c7d +https://conda.anaconda.org/conda-forge/noarch/wheel-0.41.2-pyhd8ed1ab_0.conda#1ccd092478b3e0ee10d7a891adbf8a4f https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.15.0-py311h2582759_0.conda#15565d8602a78c6a994e4d9fcb391920 -https://conda.anaconda.org/conda-forge/noarch/xlsxwriter-3.1.2-pyhd8ed1ab_0.conda#e0593431fd5e9c12824b9bfa989c9ed0 +https://conda.anaconda.org/conda-forge/noarch/xlsxwriter-3.1.4-pyhd8ed1ab_0.conda#d50bb904b23f6590f8c02fe24c0650ee https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda#82b6df12252e6f32402b96dacc656fec https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-5.0.3-h7f98852_1004.tar.bz2#e9a21aa4d5e3e5f1aed71e8cefd46b6a https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.11-hd590300_0.conda#ed67c36f215b310412b2af935bf3e530 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.0-hd590300_1.conda#ae92aab42726eb29d16488924f7312cb https://conda.anaconda.org/conda-forge/noarch/xyzservices-2023.7.0-pyhd8ed1ab_0.conda#aacae3c0eaba0204dc6c5497c93c7992 https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda#cf30c2c15b82aacb07f9c09e28ff2275 -https://conda.anaconda.org/conda-forge/noarch/zipp-3.16.2-pyhd8ed1ab_0.conda#2da0451b54c4563c32490cb1b7cf68a1 +https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda#2e4d6bc0b14e10f895fc6791a7d9b26a https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.4-pyhd8ed1ab_0.conda#46a2e6e3dfa718ce3492018d5a110dd6 https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2#d1e1eb7e21a9e2c74279d87dafb68156 https://conda.anaconda.org/conda-forge/noarch/asgiref-3.7.2-pyhd8ed1ab_0.conda#596932155bf88bb6837141550cb721b0 @@ -322,20 +315,16 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.16.0-hbbf8b49_1016.conda https://conda.anaconda.org/conda-forge/noarch/cattrs-23.1.2-pyhd8ed1ab_0.conda#e554f60477143949704bf470f66a81e7 https://conda.anaconda.org/conda-forge/linux-64/cffi-1.15.1-py311h409f033_3.conda#9025d0786dbbe4bc91fd8e85502decce https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.2.0-hd9d235c_0.conda#8c57a9adbafd87f5eff842abde599cb4 -https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.2-py311h4c7f6c3_1.tar.bz2#c7e54004ffd03f8db0a58ab949f2a00b https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2#4fd2c6b53934bd7d96d1f3fdaf99b79f https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_1.tar.bz2#a29b7c141d6b2de4bb67788a5f107734 -https://conda.anaconda.org/conda-forge/noarch/colorspacious-1.1.2-pyh24bf2e0_0.tar.bz2#b73afa0d009a51cabd3ec99c4d2ef4f3 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.1.0-py311h9547e67_0.conda#daf3f23397ab2265d0cdfa339f3627ba -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.2.7-py311h459d7ec_0.conda#3c2c65575c28b23afc5e4ff721a2fc9f +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.3.1-py311h459d7ec_0.conda#d23df37f3a595e8ffca99642ab6df3eb https://conda.anaconda.org/conda-forge/linux-64/curl-8.1.2-h409715c_0.conda#9f88cfb15b7d08b25880b138f91e0eb4 https://conda.anaconda.org/conda-forge/linux-64/cytoolz-0.12.2-py311h459d7ec_0.conda#5c416db47b7816e437eaf0d46e5c3a3d https://conda.anaconda.org/conda-forge/noarch/docformatter-1.7.5-pyhd8ed1ab_0.conda#3a941b6083e945aa87e739a9b85c82e9 https://conda.anaconda.org/conda-forge/noarch/docrep-0.3.2-pyh44b312d_0.tar.bz2#235523955bc1bfb019d7ec8a2bb58f9a -https://conda.anaconda.org/conda-forge/noarch/eofs-1.4.0-py_0.tar.bz2#6e166cd37cfeadefcfca1ffe00f222bb https://conda.anaconda.org/conda-forge/noarch/fire-0.5.0-pyhd8ed1ab_0.conda#9fd22aae8d2f319e80f68b295ab91d64 -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.42.0-py311h459d7ec_0.conda#8c1ac2c00995248898220c4c1a9d81ab -https://conda.anaconda.org/conda-forge/noarch/geopy-2.3.0-pyhd8ed1ab_0.tar.bz2#529faeecd6eee3a3b782566ddf05ce92 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.42.1-py311h459d7ec_0.conda#fc327c0ea015db3b6484eabb37d44e60 +https://conda.anaconda.org/conda-forge/noarch/geopy-2.4.0-pyhd8ed1ab_0.conda#90faaa7eaeba3cc877074c0916efe30c https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.10-pyhd8ed1ab_0.conda#3706d2f3d7cb5dae600c833345a76132 https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.0-nompi_hb72d44e_103.conda#975973a4350ab45ff1981fe535a12af5 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-6.8.0-pyha770c72_0.conda#4e9f59a060c3be52bc4ddc46ee9b6946 @@ -346,39 +335,34 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2# https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.2-pyhd8ed1ab_0.conda#4da50d410f553db77e62ab62ffaa1abc https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.2.2-pyhd8ed1ab_0.tar.bz2#243f63592c8e449f40cd42eb5cf32f40 https://conda.anaconda.org/conda-forge/noarch/latexcodec-2.0.1-pyh9f0ad1d_0.tar.bz2#8d67904973263afd2985ba56aa2d6bb4 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-18_linux64_openblas.conda#93dd9ab275ad888ed8113953769af78c https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-hfa28ad5_6.conda#ef06bee47510a7f5db3c2297a51d6ce2 +https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.0-hac7e632_1003.conda#50c389a09b6b7babaef531eb7cb5e0ca https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-h840a212_1.conda#03c225a73835f5aa68c13e62eb360406 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-18_linux64_openblas.conda#a1244707531e5b143c420c70573c8ec5 https://conda.anaconda.org/conda-forge/noarch/logilab-common-1.7.3-py_0.tar.bz2#6eafcdf39a7eb90b6d951cfff59e8d3b -https://conda.anaconda.org/conda-forge/noarch/magics-python-1.5.8-pyhd8ed1ab_1.conda#3fd7e3db129f12362642108f23fde521 https://conda.anaconda.org/conda-forge/noarch/nested-lookup-0.2.25-pyhd8ed1ab_1.tar.bz2#2f59daeb14581d41b1e2dda0895933b2 https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda#2a75b296096adabbabadd5e9782e5fcc -https://conda.anaconda.org/conda-forge/linux-64/numba-0.57.1-py311h96b013e_0.conda#618010d18c4a38073a7f51d9dd3fd8a8 -https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.11.0-py311hcafe171_1.conda#ecdaf0772e524ed51218f6d52ef74424 https://conda.anaconda.org/conda-forge/linux-64/openpyxl-3.1.2-py311h459d7ec_0.conda#3fd48307e8596409a2a55d516fa3ad1f -https://conda.anaconda.org/conda-forge/noarch/partd-1.4.0-pyhd8ed1ab_0.conda#721dab5803ea92ce02ddc4ee50aa0c48 +https://conda.anaconda.org/conda-forge/noarch/partd-1.4.0-pyhd8ed1ab_1.conda#6ceb4e000cbe0b56b290180aea8520e8 https://conda.anaconda.org/conda-forge/linux-64/pillow-10.0.0-py311h0b84326_0.conda#4b24acdc1fbbae9da03147e7d2cf8c8a https://conda.anaconda.org/conda-forge/noarch/pip-23.2.1-pyhd8ed1ab_0.conda#e2783aa3f9235225eec92f9081c5b801 -https://conda.anaconda.org/conda-forge/noarch/plotly-5.15.0-pyhd8ed1ab_0.conda#48573e7cca7860509648522a3b8507d7 +https://conda.anaconda.org/conda-forge/noarch/plotly-5.17.0-pyhd8ed1ab_0.conda#76a0b213abcd3ffc1e8fa78804b69dc0 https://conda.anaconda.org/conda-forge/linux-64/postgresql-15.3-hd458b1d_1.conda#4a4b5dede4d2e075e9aa5a44a9fd9f20 https://conda.anaconda.org/conda-forge/linux-64/proj-9.2.1-ha643af7_0.conda#e992387307f4403ba0ec07d009032550 https://conda.anaconda.org/conda-forge/noarch/pydocstyle-6.3.0-pyhd8ed1ab_0.conda#7e23a61a7fbaedfef6eb0e1ac775c8e5 https://conda.anaconda.org/conda-forge/noarch/pyproject_hooks-1.0.0-pyhd8ed1ab_0.conda#21de50391d584eb7f4441b9de1ad773f -https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.0-pyhd8ed1ab_0.conda#3cfe9b9e958e7238a386933c75d190db +https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.2-pyhd8ed1ab_0.conda#6dd662ff5ac9a783e5c940ce9f3fe649 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2#dd999d1cc9f79e67dbb855c8924c7984 https://conda.anaconda.org/conda-forge/noarch/python-utils-3.7.0-pyhd8ed1ab_1.conda#d3e9c0f7bf300ddc51a363a8183b3abd -https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.4.1-py311hcb2cf0a_0.conda#272ca0c28df344037ba2c4982d4e4791 https://conda.anaconda.org/conda-forge/noarch/referencing-0.30.2-pyhd8ed1ab_0.conda#a33161b983172ba6ef69d5fc850650cd https://conda.anaconda.org/conda-forge/noarch/retrying-1.3.3-py_2.tar.bz2#a11f356d6f93b74b4a84e9501afd48b4 https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.17.32-py311h459d7ec_0.conda#628868dc17f9bd39a2eb77846e35980c -https://conda.anaconda.org/conda-forge/noarch/seawater-3.3.4-py_1.tar.bz2#a9e101e1601faf5e5a119ab2bd7617a4 -https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.1-py311h54d622a_1.conda#a894c65b48676c4973e9ee8b59bceb9e -https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2#cb83a3d6ecf73f50117635192414426a -https://conda.anaconda.org/conda-forge/linux-64/suitesparse-5.10.1-h9e50725_1.tar.bz2#a3a685b5f9aeb890ed874502fe56accf https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.2.1-pyhd8ed1ab_0.tar.bz2#7234c9eefff659501cd2fe0d2ede4d48 https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.1-pyhd8ed1ab_0.conda#03c97908b976498dcae97eb4e4f3149c -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.7.1-hd8ed1ab_0.conda#f96688577f1faa58096d06a45136afa2 +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.8.0-hd8ed1ab_0.conda#384462e63262a527bda564fa2d9126c0 https://conda.anaconda.org/conda-forge/noarch/url-normalize-1.4.3-pyhd8ed1ab_0.tar.bz2#7c4076e494f0efe76705154ac9302ba6 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.0.4-pyhd8ed1ab_0.conda#18badd8fa3648d1beb1fcc7f2e0f756e +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.0.5-pyhd8ed1ab_0.conda#3bda70bbeb2920f44db5375af2e5fe38 https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.4-h8d71039_2.conda#6d5edbe22b07abae2ea0a9065ef6be12 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.7.10-h7f98852_0.tar.bz2#e77615e5141cad5a2acaa043d1cf0ca5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxmu-1.1.3-h7f98852_0.tar.bz2#3cdb89236358326adfce12be820a8af3 @@ -386,110 +370,124 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxpm-3.5.16-hd590300_0.co https://conda.anaconda.org/conda-forge/noarch/yamale-4.0.4-pyh6c4a22f_0.tar.bz2#cc9f59f147740d88679bf1bd94dbe588 https://conda.anaconda.org/conda-forge/noarch/yamllint-1.32.0-pyhd8ed1ab_0.conda#6d2425548b0293a225ca4febd80feaa3 https://conda.anaconda.org/conda-forge/linux-64/yarl-1.9.2-py311h459d7ec_0.conda#4d738187d20e0a3be66973860f134e0a -https://conda.anaconda.org/conda-forge/noarch/async-timeout-4.0.2-pyhd8ed1ab_0.tar.bz2#25e79f9a1133556671becbd65a170c78 +https://conda.anaconda.org/conda-forge/linux-64/arpack-3.7.0-hdefa2d7_2.tar.bz2#8763fe86163198ef1778d1d8d22bb078 +https://conda.anaconda.org/conda-forge/noarch/async-timeout-4.0.3-pyhd8ed1ab_0.conda#3ce482ec3066e6d809dbbb1d1679f215 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.13-heb0bb06_2.conda#c0866da05d5e7bb3a3f6b68bcbf7537b -https://conda.anaconda.org/conda-forge/linux-64/cf-units-3.2.0-py311h1f0f07a_0.conda#43a71a823583d75308eaf3a06c8f150b -https://conda.anaconda.org/conda-forge/linux-64/cryptography-41.0.3-py311h63ff55d_0.conda#cc8ad641cab65dfe59caddbc23a1aeca -https://conda.anaconda.org/conda-forge/noarch/django-4.2.3-pyhd8ed1ab_0.conda#00a369ccfec9deaa325eabd749bfae28 +https://conda.anaconda.org/conda-forge/linux-64/cryptography-41.0.4-py311h63ff55d_0.conda#2b14cd05541532521196b0d2e0291ecf +https://conda.anaconda.org/conda-forge/noarch/django-4.2.5-pyhd8ed1ab_0.conda#5af47510c844ef54896d6b3ea424b82b https://conda.anaconda.org/conda-forge/noarch/flake8-5.0.4-pyhd8ed1ab_0.tar.bz2#8079ea7dec0a917dd0cb6c257f7ea9ea https://conda.anaconda.org/conda-forge/linux-64/freeglut-3.2.2-hac7e632_2.conda#6e553df297f6e64668efb54302e0f139 https://conda.anaconda.org/conda-forge/noarch/funcargparse-0.2.5-pyhd8ed1ab_0.tar.bz2#e557b70d736251fa0bbb7c4497852a92 https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.1-h22adcc9_11.conda#514167b60f598eaed3f7a60e1dceb9ee -https://conda.anaconda.org/conda-forge/linux-64/git-2.41.0-pl5321h86e50cf_0.conda#14f8341e26b274362b026bbdc72b14fb -https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.32-pyhd8ed1ab_0.conda#5809a12901d57388444c3293c975d0bb +https://conda.anaconda.org/conda-forge/linux-64/git-2.42.0-pl5321h86e50cf_0.conda#96ad24c67e0056d171385859c43218a2 +https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.36-pyhd8ed1ab_0.conda#a7c99acc18eea3d70224dd95dadcfd31 +https://conda.anaconda.org/conda-forge/linux-64/gsl-2.7-he838d99_0.tar.bz2#fec079ba39c9cca093bf4c00001825de https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-7.3.0-hdb3a94d_0.conda#765bc76c0dfaf24ff9d8a2935b2510df https://conda.anaconda.org/conda-forge/linux-64/hdfeos5-5.1.16-h8b5b2df_13.conda#29a96d50cb53638a5b4806b5ca6e4b1d -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2023.7.10-py311h67b54e4_2.conda#ac734963735ededab90c6991d1d4edff -https://conda.anaconda.org/conda-forge/noarch/imageio-2.31.1-pyh24c5eb1_0.conda#1051cc0376612ba101d4f59e954a1ff4 https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-6.8.0-hd8ed1ab_0.conda#b279b07ce18058034e5b3606ba103a8b https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.7.1-pyhd8ed1ab_0.conda#7c27ea1bdbe520bb830dcadd59f55cbf https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.1-h3845be2_3.conda#f38e5e47f62d6633166040192ad420a1 https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h0f3d0bb_105.conda#b5d412441b84305460e9df8a016a3392 https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.0.1-hca56755_27.conda#918a735059cab21b96fc13a8d04fbcd8 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.7.2-py311h54ef318_0.conda#2631a9e423855fb586c05f8a5ee8b177 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.0.3-py311h320fe9a_1.conda#5f92f46bd33917832a99d1660b4075ac +https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.4-py311h64a7726_0.conda#5a03d7c75dd4a9ae9a58850860eca468 https://conda.anaconda.org/conda-forge/noarch/platformdirs-3.10.0-pyhd8ed1ab_0.conda#0809187ef9b89a3d94a5c24d13936236 https://conda.anaconda.org/conda-forge/linux-64/poppler-23.05.0-hd18248d_1.conda#09e0de1aa7330fe697eed76eaeef666d https://conda.anaconda.org/conda-forge/noarch/progressbar2-4.2.0-pyhd8ed1ab_0.tar.bz2#d883564cf1e9ba190f6b285036c5f949 https://conda.anaconda.org/conda-forge/noarch/pybtex-0.24.0-pyhd8ed1ab_2.tar.bz2#2099b86a7399c44c0c61cdb6de6915ba -https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.6.0-py311ha169711_1.conda#92633556d37e88ce45193374d408072c +https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.6.1-py311ha169711_0.conda#ad4b6e9be79a89959bb6d7d308027ff2 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-4.1.0-pyhd8ed1ab_0.conda#06eb685a3a0b146347a58dda979485da -https://conda.anaconda.org/conda-forge/noarch/pytest-env-0.8.2-pyhd8ed1ab_0.conda#cd20b56ff31042aad74d45e3f47eb5b2 +https://conda.anaconda.org/conda-forge/noarch/pytest-env-1.0.1-pyhd8ed1ab_0.conda#9da651d84c73bac482cae51613a4d4d6 https://conda.anaconda.org/conda-forge/noarch/pytest-metadata-3.0.0-pyhd8ed1ab_1.conda#8bdcc0f401561213821bf67513abeeff https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.11.1-pyhd8ed1ab_0.conda#fcd2531bc3e492657aeb042349aeaf8a https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.3.1-pyhd8ed1ab_0.conda#816073bb54ef59f33f0f26c14f88311b -https://conda.anaconda.org/conda-forge/noarch/python-build-0.10.0-pyhd8ed1ab_1.conda#0ab47ce574f6a8bcb9f2076436e7fedb +https://conda.anaconda.org/conda-forge/noarch/python-build-1.0.3-pyhd8ed1ab_0.conda#d9ccabf228cb98419ca3d5694b25e1a2 https://conda.anaconda.org/conda-forge/noarch/rdflib-7.0.0-pyhd8ed1ab_0.conda#44d14ef95495b3d4438f28998e0296a9 https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda#a30144e4156cdbb236f99ebb49828f8b https://conda.anaconda.org/conda-forge/noarch/requirements-detector-1.2.2-pyhd8ed1ab_0.conda#6626918380d99292df110f3c91b6e5ec +https://conda.anaconda.org/conda-forge/linux-64/suitesparse-5.10.1-h9e50725_1.tar.bz2#a3a685b5f9aeb890ed874502fe56accf https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.13.2-hd532e3d_0.conda#6d97164f19dbd27575ef1899b02dc1e0 https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py311h4dd048b_3.tar.bz2#dbfea4376856bf7bd2121e719cf816e5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxaw-1.0.14-h7f98852_1.tar.bz2#45b68dc2fc7549c16044d533ceaf340e -https://conda.anaconda.org/conda-forge/noarch/zarr-2.16.0-pyhd8ed1ab_0.conda#40a116bf021c83da8b1cf226de0dabe4 https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.8.5-py311h459d7ec_0.conda#82a817c46ac339c0166f043f56492f33 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.3-he9c0e7f_4.conda#7695770e1d722ce9029a2ea30c060a3d -https://conda.anaconda.org/conda-forge/noarch/bokeh-3.2.1-pyhd8ed1ab_0.conda#1f6a50747c4e69d181f3a2ca739d1fe3 -https://conda.anaconda.org/conda-forge/linux-64/cartopy-0.22.0-py311h320fe9a_0.conda#1271b2375735e2aaa6d6770dbe2ad087 https://conda.anaconda.org/conda-forge/noarch/cdsapi-0.6.1-pyhd8ed1ab_0.conda#454ed214cec806066097ae245a409171 +https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.2-py311h4c7f6c3_1.tar.bz2#c7e54004ffd03f8db0a58ab949f2a00b https://conda.anaconda.org/conda-forge/noarch/chart-studio-1.1.0-pyh9f0ad1d_0.tar.bz2#acd9a12a35e5a0221bdf39eb6e4811dc -https://conda.anaconda.org/conda-forge/noarch/cmocean-3.0.3-pyhd8ed1ab_0.conda#eec7df83d725696d32c7bf99aff21d82 -https://conda.anaconda.org/conda-forge/noarch/dask-core-2023.8.0-pyhd8ed1ab_0.conda#160a92928fc4a0ca40a64b586a2cf671 +https://conda.anaconda.org/conda-forge/noarch/colorspacious-1.1.2-pyh24bf2e0_0.tar.bz2#b73afa0d009a51cabd3ec99c4d2ef4f3 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.1.1-py311h9547e67_0.conda#db5b3b0093d0d4565e5c89578108402e +https://conda.anaconda.org/conda-forge/noarch/dask-core-2023.9.2-pyhd8ed1ab_0.conda#cce7eeb7eda0124af186a5e9ce9b0fca +https://conda.anaconda.org/conda-forge/noarch/eofs-1.4.0-py_0.tar.bz2#6e166cd37cfeadefcfca1ffe00f222bb https://conda.anaconda.org/conda-forge/noarch/flake8-polyfill-1.0.2-py_0.tar.bz2#a53db35e3d07f0af2eccd59c2a00bffe -https://conda.anaconda.org/conda-forge/noarch/identify-2.5.26-pyhd8ed1ab_0.conda#1ca86f154e13f4aa20b48e20d6bbf924 +https://conda.anaconda.org/conda-forge/noarch/identify-2.5.29-pyhd8ed1ab_0.conda#5bdbb1cb692649720b60f261b41760cd +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2023.8.12-py311h67b54e4_0.conda#363e5c2f2c67ff69d717aba54422b03d +https://conda.anaconda.org/conda-forge/noarch/imageio-2.31.1-pyh24c5eb1_0.conda#1051cc0376612ba101d4f59e954a1ff4 https://conda.anaconda.org/conda-forge/linux-64/jasper-4.0.0-h32699f2_1.conda#fdde5424ecef5f7ad310b4242229291c -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.19.0-pyhd8ed1ab_0.conda#989d1df249e1fce06fa1435548eef68a +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.19.1-pyhd8ed1ab_0.conda#78aff5d2af74e6537c1ca73017f01f4f https://conda.anaconda.org/conda-forge/linux-64/julia-1.8.5-h783901f_0.conda#98c05ba7ca9c15d22216f730499e167a https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.3.1-py311h38be061_0.conda#0cf8259b01ede82c76007996f73f89ed https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.7.0-h5418a03_2.conda#30ddbe080c260fb36da8509e3fd6c45f -https://conda.anaconda.org/conda-forge/noarch/nc-time-axis-1.4.1-pyhd8ed1ab_0.tar.bz2#281b58948bf60a2582de9e548bcc5369 +https://conda.anaconda.org/conda-forge/noarch/magics-python-1.5.8-pyhd8ed1ab_1.conda#3fd7e3db129f12362642108f23fde521 https://conda.anaconda.org/conda-forge/linux-64/netcdf-fortran-4.6.1-nompi_h4f3791c_100.conda#405c5b3ad4ef53eb0d93043b54206dd7 -https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.4-nompi_py311h4d7c953_100.conda#c03492d0342e512e58aa2d6c5fdaaa91 +https://conda.anaconda.org/conda-forge/linux-64/numba-0.57.1-py311h96b013e_0.conda#618010d18c4a38073a7f51d9dd3fd8a8 +https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.11.0-py311hcafe171_1.conda#ecdaf0772e524ed51218f6d52ef74424 +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.1.1-py311h320fe9a_0.conda#1692362ba82f0556099f0143f7842de3 https://conda.anaconda.org/conda-forge/linux-64/pango-1.50.14-heaa33ce_1.conda#cde553e0e32389e26595db4eacf859eb https://conda.anaconda.org/conda-forge/noarch/pooch-1.7.0-pyha770c72_3.conda#5936894aade8240c867d292aa0d980c6 https://conda.anaconda.org/conda-forge/noarch/pylint-2.17.5-pyhd8ed1ab_0.conda#30dc94b05de470e3b579d73d64127656 https://conda.anaconda.org/conda-forge/noarch/pyopenssl-23.2.0-pyhd8ed1ab_1.conda#34f7d568bf59d18e3fef8c405cbece21 https://conda.anaconda.org/conda-forge/noarch/pyroma-4.2-pyhd8ed1ab_0.conda#fe2aca9a5d4cb08105aefc451ef96950 https://conda.anaconda.org/conda-forge/noarch/pytest-html-3.2.0-pyhd8ed1ab_1.tar.bz2#d5c7a941dfbceaab4b172a56d7918eb0 +https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.4.1-py311hcb2cf0a_0.conda#272ca0c28df344037ba2c4982d4e4791 https://conda.anaconda.org/conda-forge/noarch/requests-cache-1.1.0-pyhd8ed1ab_0.conda#57b89064c125bb9d0e533e018c3eb17a +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.11.2-py311h64a7726_1.conda#58af16843fc4469770bdbaf45d3a19de +https://conda.anaconda.org/conda-forge/noarch/seawater-3.3.4-py_1.tar.bz2#a9e101e1601faf5e5a119ab2bd7617a4 +https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.1-py311h54d622a_1.conda#a894c65b48676c4973e9ee8b59bceb9e +https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2#cb83a3d6ecf73f50117635192414426a https://conda.anaconda.org/conda-forge/linux-64/tempest-remap-2.2.0-h43474b4_0.conda#fd815765a86daf44db1e15c6f6edf5e6 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2023.7.18-pyhd8ed1ab_0.conda#34c210cbc9b4c4458d4eba5ee7726fcd -https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.24.2-pyhd8ed1ab_0.conda#a218f3be8ab6185a475c8168a86e18ae -https://conda.anaconda.org/conda-forge/noarch/xarray-2023.7.0-pyhd8ed1ab_0.conda#2f18700699e1ea19aa1634ed57711677 +https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.24.4-pyhd8ed1ab_0.conda#c3feaf947264a59a125e8c26e98c3c5a https://conda.anaconda.org/conda-forge/noarch/yapf-0.40.1-pyhd8ed1ab_0.conda#f269942e802d5e148632143d4c37acc9 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-hbc2ea52_17.conda#452c7b08c21eea2ef01f4fd364d6affc -https://conda.anaconda.org/conda-forge/noarch/cf_xarray-0.8.4-pyhd8ed1ab_0.conda#18472f8f9452f962fe0bcb1b8134b494 -https://conda.anaconda.org/conda-forge/noarch/distributed-2023.8.0-pyhd8ed1ab_0.conda#974b4a00b0e100e341cd9f179b05f574 +https://conda.anaconda.org/conda-forge/noarch/bokeh-3.2.2-pyhd8ed1ab_0.conda#30488151f591379db656250b3f5fc0c6 +https://conda.anaconda.org/conda-forge/linux-64/cf-units-3.2.0-py311h1f0f07a_0.conda#43a71a823583d75308eaf3a06c8f150b +https://conda.anaconda.org/conda-forge/noarch/distributed-2023.9.2-pyhd8ed1ab_0.conda#ddb4fd6105b4005b312625cef210ba67 https://conda.anaconda.org/conda-forge/linux-64/eccodes-2.30.2-h1f30a5c_0.conda#21ee8444a7f629924ea8cfe52a622cbd https://conda.anaconda.org/conda-forge/linux-64/esmf-8.4.2-nompi_h20110ff_0.conda#11f5169aeff54ad7277476be8ba19ff7 https://conda.anaconda.org/conda-forge/linux-64/gdal-3.7.0-py311h281082f_2.conda#fde4fad3c517cc80f32995696f45198d https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h90689f9_2.tar.bz2#957a0255ab58aaf394a91725d73ab422 -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.3.0-pyhd8ed1ab_0.conda#1d018ee4ab13217e2544f795eb0a6798 +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.3.1-pyhd8ed1ab_0.conda#b7cc0981484fcb6390e6d341e55618b3 https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.56.3-h98fae49_0.conda#620e754f4344f4c27259ff460a2b9c50 -https://conda.anaconda.org/conda-forge/noarch/mapgenerator-1.0.7-pyhd8ed1ab_0.conda#d18db96ef2a920b0ecefe30282b0aecf +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.8.0-py311h54ef318_0.conda#b67672c2f39ef2912a1814e29e42c7ca https://conda.anaconda.org/conda-forge/noarch/myproxyclient-2.1.0-pyhd8ed1ab_2.tar.bz2#363b0816e411feb0df925d4f224f026a https://conda.anaconda.org/conda-forge/noarch/nbformat-5.9.2-pyhd8ed1ab_0.conda#61ba076de6530d9301a0053b02f093d2 +https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.4-nompi_py311h4d7c953_100.conda#c03492d0342e512e58aa2d6c5fdaaa91 +https://conda.anaconda.org/conda-forge/noarch/patsy-0.5.3-pyhd8ed1ab_0.tar.bz2#50ef6b29b1fb0768ca82c5aeb4fb2d96 https://conda.anaconda.org/conda-forge/noarch/pep8-naming-0.10.0-pyh9f0ad1d_0.tar.bz2#b3c5536e4f9f58a4b16adb6f1e11732d -https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.3.3-pyha770c72_0.conda#dd64a0e440754ed97610b3e6b502b6b1 -https://conda.anaconda.org/conda-forge/linux-64/psyplot-1.4.3-py311h38be061_1.tar.bz2#f0c9a1067c03e8f05e53ef0c5ad5fab3 +https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.4.0-pyha770c72_1.conda#3fb5ba328a77c9fd71197a46e7f2469a https://conda.anaconda.org/conda-forge/noarch/pylint-plugin-utils-0.7-pyhd8ed1ab_0.tar.bz2#1657976383aee04dbb3ae3bdf654bb58 https://conda.anaconda.org/conda-forge/linux-64/python-stratify-0.3.0-py311h1f0f07a_0.conda#3a00b1b08d8c01b1a3bfa686b9152df2 https://conda.anaconda.org/conda-forge/linux-64/r-base-4.1.3-hfabd6f2_9.conda#0ab4cf54fbddc0cc9ff260c6f77f8c84 https://conda.anaconda.org/conda-forge/linux-64/rasterio-1.3.8-py311h41e4db2_0.conda#b35deb26af1d7e0d98438c8ac5c6b7b2 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.11.1-py311h64a7726_0.conda#356da36102fc1eeb8a81e6d79e53bc7e +https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.3.0-py311hc009520_0.conda#847797c4a9c0c3363ffcfe7571dedfee +https://conda.anaconda.org/conda-forge/noarch/sparse-0.14.0-pyhd8ed1ab_0.conda#ee01b310177a0612554b9d20e537fdbe +https://conda.anaconda.org/conda-forge/noarch/tifffile-2023.9.18-pyhd8ed1ab_0.conda#c24d705dfe38f0a7a5cfa51b40c3d906 +https://conda.anaconda.org/conda-forge/noarch/xarray-2023.8.0-pyhd8ed1ab_0.conda#a8104cede521616573e228c27f9edc97 +https://conda.anaconda.org/conda-forge/noarch/zarr-2.16.1-pyhd8ed1ab_0.conda#59ec835edbee50266b7bdbadab7ba335 +https://conda.anaconda.org/conda-forge/linux-64/cartopy-0.22.0-py311h320fe9a_0.conda#1271b2375735e2aaa6d6770dbe2ad087 +https://conda.anaconda.org/conda-forge/noarch/cf_xarray-0.8.4-pyhd8ed1ab_0.conda#18472f8f9452f962fe0bcb1b8134b494 +https://conda.anaconda.org/conda-forge/noarch/cmocean-3.0.3-pyhd8ed1ab_0.conda#eec7df83d725696d32c7bf99aff21d82 https://conda.anaconda.org/conda-forge/noarch/dask-jobqueue-0.8.2-pyhd8ed1ab_0.conda#cc344a296a41369bcb05f7216661cec8 https://conda.anaconda.org/conda-forge/noarch/esgf-pyclient-0.3.1-pyh1a96a4e_2.tar.bz2#64068564a9c2932bf30e9b4ec567927d -https://conda.anaconda.org/conda-forge/noarch/esmpy-8.4.2-pyhc1e730c_1.conda#4067029ad6872d49f6d43c05dd1f51a9 +https://conda.anaconda.org/conda-forge/noarch/esmpy-8.4.2-pyhc1e730c_4.conda#ddcf387719b2e44df0cc4dd467643951 https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.4-py311hbac4ec9_0.conda#1d3445f5f7fa002a1c149c405376f012 https://conda.anaconda.org/conda-forge/linux-64/graphviz-8.1.0-h28d9a01_0.conda#33628e0e3de7afd2c8172f76439894cb -https://conda.anaconda.org/conda-forge/noarch/iris-3.6.1-pyha770c72_0.conda#36d615b339058273520990fc78239116 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.1-h657c46f_7_cpu.conda#4de6e12428b7018f1f8a1e8dda555243 https://conda.anaconda.org/conda-forge/linux-64/magics-4.14.2-hd3d5bb6_0.conda#3c571b994b6ce2b4d2c7b98be77a8ebe https://conda.anaconda.org/conda-forge/noarch/nbclient-0.8.0-pyhd8ed1ab_0.conda#e78da91cf428faaf05701ce8cc8f2f9b +https://conda.anaconda.org/conda-forge/noarch/nc-time-axis-1.4.1-pyhd8ed1ab_0.tar.bz2#281b58948bf60a2582de9e548bcc5369 https://conda.anaconda.org/conda-forge/linux-64/ncl-6.6.2-hf70af60_47.conda#ee27133164cb9f5e74681bdb8839688f https://conda.anaconda.org/conda-forge/linux-64/nco-5.1.6-hd62b316_0.conda#af7780f76ee37325d264327e21a478f5 -https://conda.anaconda.org/conda-forge/noarch/patsy-0.5.3-pyhd8ed1ab_0.tar.bz2#50ef6b29b1fb0768ca82c5aeb4fb2d96 -https://conda.anaconda.org/conda-forge/linux-64/psy-simple-1.4.1-py311h38be061_2.tar.bz2#4c9101d329f6bc09c2617a80e3eb9c89 -https://conda.anaconda.org/conda-forge/noarch/py-cordex-0.6.2-pyhd8ed1ab_0.conda#457fae5edf0703054b78f6bfb200e855 +https://conda.anaconda.org/conda-forge/linux-64/psyplot-1.4.3-py311h38be061_1.tar.bz2#f0c9a1067c03e8f05e53ef0c5ad5fab3 +https://conda.anaconda.org/conda-forge/linux-64/py-xgboost-1.7.6-cuda112py311h2344cce_2.conda#cca8982f2b80ffe50124d5cdbbcfdda8 https://conda.anaconda.org/conda-forge/noarch/pylint-celery-0.3-py_1.tar.bz2#e29456a611a62d3f26105a2f9c68f759 https://conda.anaconda.org/conda-forge/noarch/pylint-django-2.5.3-pyhd8ed1ab_0.tar.bz2#00d8853fb1f87195722ea6a582cc9b56 https://conda.anaconda.org/conda-forge/noarch/pylint-flask-0.6-py_0.tar.bz2#5a9afd3d0a61b08d59eed70fab859c1b @@ -557,16 +555,17 @@ https://conda.anaconda.org/conda-forge/linux-64/r-xfun-0.39-r41ha503ecb_0.conda# https://conda.anaconda.org/conda-forge/noarch/r-xmlparsedata-1.0.5-r41hc72bb7e_1.tar.bz2#921c0ef7104d8df0ab506f1bb81a062c https://conda.anaconda.org/conda-forge/linux-64/r-yaml-2.3.7-r41h133d619_0.conda#4af88071a607237aa73a3cbd51788a39 https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.21.0-py311hb755f60_0.conda#0a8cbf18f7e57e43b8e106630a0ca7df -https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.3.0-py311hc009520_0.conda#847797c4a9c0c3363ffcfe7571dedfee https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.2-pyhd8ed1ab_0.conda#cf88f3a1c11536bc3c10c14ad00ccc42 -https://conda.anaconda.org/conda-forge/noarch/sparse-0.14.0-pyhd8ed1ab_0.conda#ee01b310177a0612554b9d20e537fdbe +https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.0-py311h1f0f07a_1.conda#a1daa39fa0bfed4d91a3640c2274034a https://conda.anaconda.org/conda-forge/linux-64/cdo-2.2.0-he026af2_4.conda#6c00b0a21b3de8a149eee137e83465d3 https://conda.anaconda.org/conda-forge/linux-64/imagemagick-7.1.1_15-pl5321hf48ede7_0.conda#53c9f7169b61e615d5f41c8d70a72c00 +https://conda.anaconda.org/conda-forge/noarch/iris-3.7.0-pyha770c72_0.conda#dccc1f660bf455c239adaabf56b91dc9 https://conda.anaconda.org/conda-forge/noarch/lime-0.2.0.1-pyhd8ed1ab_1.tar.bz2#789ce01416721a5533fb74aa4361fd13 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.7.3-pyhd8ed1ab_0.conda#063c1fda5480050b8d989478c97a4c55 +https://conda.anaconda.org/conda-forge/noarch/mapgenerator-1.0.7-pyhd8ed1ab_0.conda#d18db96ef2a920b0ecefe30282b0aecf +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.8.0-pyhd8ed1ab_0.conda#62345c9e24f898bf492979be84a6eb0a https://conda.anaconda.org/conda-forge/noarch/prospector-1.10.2-pyhd8ed1ab_0.conda#2c536985982f7e531df8d640f554008a -https://conda.anaconda.org/conda-forge/noarch/psy-maps-1.4.2-pyhd8ed1ab_0.tar.bz2#3ed13103dfd46f71dc870d188bd0b276 -https://conda.anaconda.org/conda-forge/linux-64/py-xgboost-1.7.6-cuda112py311h2344cce_0.conda#262d5d7254fd6e10e63170c4eb8d6ac0 +https://conda.anaconda.org/conda-forge/linux-64/psy-simple-1.4.1-py311h38be061_2.tar.bz2#4c9101d329f6bc09c2617a80e3eb9c89 +https://conda.anaconda.org/conda-forge/noarch/py-cordex-0.6.3-pyhd8ed1ab_0.conda#de9f9392273a1e6095930a21561a37e9 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.1-py311h39c9aba_7_cpu.conda#d513ab8d10ec5f3ee45b419c836195ec https://conda.anaconda.org/conda-forge/linux-64/pydot-1.4.2-py311h38be061_3.tar.bz2#64a77de29fde80aef5013ddf5e62a564 https://conda.anaconda.org/conda-forge/linux-64/r-askpass-1.1-r41h06615bd_3.tar.bz2#c8ec8683302ad9a2345cb31ab28e6c6b @@ -595,11 +594,13 @@ https://conda.anaconda.org/conda-forge/linux-64/r-spam-2.9_1-r41hb20cf53_1.conda https://conda.anaconda.org/conda-forge/linux-64/r-timechange-0.2.0-r41h38f115c_0.conda#04a4229419d779a1e27395d70d493571 https://conda.anaconda.org/conda-forge/linux-64/r-xml2-1.3.4-r41h1ad5fc0_1.conda#82c1446591783493d65273a158e8ce28 https://conda.anaconda.org/conda-forge/linux-64/r-zoo-1.8_12-r41h133d619_0.conda#1d432d2eba171727afd03507faa5e2f6 -https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.0-py311h1f0f07a_1.conda#a1daa39fa0bfed4d91a3640c2274034a -https://conda.anaconda.org/conda-forge/noarch/xesmf-0.7.1-pyhd8ed1ab_0.conda#3a9cc63d7bcbc8d738a0e92faf8b6c07 -https://conda.anaconda.org/conda-forge/noarch/dask-2023.8.0-pyhd8ed1ab_0.conda#0cd5f8a91edc681f4b87e8a0ce33a591 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.7.3-pyhd8ed1ab_0.conda#f44109e52a40b8149156f5ddd9c11b26 +https://conda.anaconda.org/conda-forge/noarch/seaborn-0.12.2-hd8ed1ab_0.conda#50847a47c07812f88581081c620f5160 +https://conda.anaconda.org/conda-forge/noarch/xesmf-0.8.2-pyhd8ed1ab_0.conda#8e765a0eca0ce1cfa889cd9af82a23a8 +https://conda.anaconda.org/conda-forge/linux-64/xgboost-1.7.6-cuda112py311h2344cce_2.conda#97cd4e1589b8ea11e0f78d2f0c7cc217 +https://conda.anaconda.org/conda-forge/noarch/dask-2023.9.2-pyhd8ed1ab_0.conda#29e33df59c9eac1a599b9cd18d54b4d3 +https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.8.0-pyhd8ed1ab_0.conda#1dba1a577df2625a24667612a069e91c https://conda.anaconda.org/conda-forge/noarch/prov-2.0.0-pyhd3deb0d_0.tar.bz2#aa9b3ad140f6c0668c646f32e20ccf82 +https://conda.anaconda.org/conda-forge/noarch/psy-maps-1.4.2-pyhd8ed1ab_0.tar.bz2#3ed13103dfd46f71dc870d188bd0b276 https://conda.anaconda.org/conda-forge/linux-64/psy-reg-1.4.0-py311h38be061_3.conda#6f7871722c07922028043144e8873b37 https://conda.anaconda.org/conda-forge/noarch/python-cdo-1.6.0-pyhd8ed1ab_0.conda#3fd1a0b063c1fbbe4b7bd5a5a7601e84 https://conda.anaconda.org/conda-forge/linux-64/r-akima-0.6_2.3-r41h92ddd45_0.tar.bz2#bac0b7627ef744c98f4bc48885f52e72 @@ -619,10 +620,8 @@ https://conda.anaconda.org/conda-forge/noarch/r-scales-1.2.1-r41hc72bb7e_1.tar.b https://conda.anaconda.org/conda-forge/linux-64/r-specsverification-0.5_3-r41ha503ecb_3.conda#2bc51f0d44b98092ba57cf2f8671b490 https://conda.anaconda.org/conda-forge/linux-64/r-splancs-2.01_43-r41h8da6f51_1.tar.bz2#3a6aad0706541141d10e3b514467a080 https://conda.anaconda.org/conda-forge/linux-64/r-vctrs-0.6.2-r41ha503ecb_0.conda#1f7610a1863648cab254a9f85bd29dcd -https://conda.anaconda.org/conda-forge/noarch/seaborn-0.12.2-hd8ed1ab_0.conda#50847a47c07812f88581081c620f5160 -https://conda.anaconda.org/conda-forge/linux-64/xgboost-1.7.6-cuda112py311h2344cce_0.conda#bfa2be4c1df9bf875896b40b1735e6c2 -https://conda.anaconda.org/conda-forge/noarch/iris-esmf-regrid-0.7.0-pyhd8ed1ab_0.conda#de82eb8d09362babacafe6b7e27752ac -https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.7.3-pyhd8ed1ab_0.conda#f53d92ecd7d8563b006107f6a33e55c6 +https://conda.anaconda.org/conda-forge/noarch/iris-esmf-regrid-0.8.0-pyhd8ed1ab_0.conda#56e85460d22fa7d4fb06300f785dd1e1 +https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.8.0-pyhd8ed1ab_0.conda#43bce95e8c474dd21d7ed5de8b4806f7 https://conda.anaconda.org/conda-forge/noarch/r-cyclocomp-1.1.0-r41hc72bb7e_1005.tar.bz2#800e1da5bf774be48934b8865dd78d33 https://conda.anaconda.org/conda-forge/noarch/r-gridextra-2.3-r41hc72bb7e_1004.tar.bz2#71ebed7e976df735ff3443bb88bd154f https://conda.anaconda.org/conda-forge/noarch/r-httr-1.4.6-r41hc72bb7e_0.conda#53dbb769c96782db54bf2d414fc9b239 @@ -648,11 +647,11 @@ https://conda.anaconda.org/conda-forge/linux-64/r-geomap-2.5_0-r41h06615bd_1.tar https://conda.anaconda.org/conda-forge/noarch/r-lintr-3.0.2-r41hc72bb7e_0.tar.bz2#769c2305486b74fd61d85bfef2296f27 https://conda.anaconda.org/conda-forge/noarch/r-s2dverification-2.10.3-r41hc72bb7e_1.tar.bz2#2253f130c8dab435824d6ddb10a41c73 https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.6-pyhd8ed1ab_0.tar.bz2#4409dd7e06a62c3b2aa9e96782c49c6d -https://conda.anaconda.org/conda-forge/noarch/nbsphinx-0.9.2-pyhd8ed1ab_0.conda#d1212b423fdd10d2da59601385561ff7 -https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.13.3-pyhd8ed1ab_0.conda#07aca5f2dea315dcc16680d6891e9056 -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.6-pyhd8ed1ab_0.conda#5bba7b5823474cb3fcd4e4cbf942da61 -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-1.0.4-pyhd8ed1ab_0.conda#73dcd0eb2252cbd1530fd1e6e3cbbb03 -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.0.3-pyhd8ed1ab_0.conda#fb4d6329a57e20e03d7aecd18c7ca918 -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.5-pyhd8ed1ab_0.conda#85466265b76473cc1d02420056cbc4e3 -https://conda.anaconda.org/conda-forge/noarch/sphinx-7.1.2-pyhd8ed1ab_0.conda#d02bfa35cd4f2cd624289f64911cae9d -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.7-pyhd8ed1ab_0.conda#01e35beea8aff61cdb445b90a7adf7d4 +https://conda.anaconda.org/conda-forge/noarch/nbsphinx-0.9.3-pyhd8ed1ab_0.conda#0dbaa7d08d3d79b2a1a4dd6a02cc4581 +https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.14.1-pyhd8ed1ab_0.conda#78153addf629c51fab775ef360012ca3 +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.7-pyhd8ed1ab_0.conda#aebfabcb60c33a89c1f9290cab49bc93 +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-1.0.5-pyhd8ed1ab_0.conda#ebf08f5184d8eaa486697bc060031953 +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.0.4-pyhd8ed1ab_0.conda#a9a89000dfd19656ad004b937eeb6828 +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.6-pyhd8ed1ab_0.conda#cf5c9649272c677a964a7313279e3a9b +https://conda.anaconda.org/conda-forge/noarch/sphinx-7.2.6-pyhd8ed1ab_0.conda#bbfd1120d1824d2d073bc65935f0e4c0 +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.9-pyhd8ed1ab_0.conda#0612e497d7860728f2cda421ea2aec09 diff --git a/doc/sphinx/source/recipes/figures/monitor/hovmoeller_time_vs_lat_with_ref.png b/doc/sphinx/source/recipes/figures/monitor/hovmoeller_time_vs_lat_with_ref.png new file mode 100644 index 0000000000..4abd6df04f Binary files /dev/null and b/doc/sphinx/source/recipes/figures/monitor/hovmoeller_time_vs_lat_with_ref.png differ diff --git a/doc/sphinx/source/recipes/figures/monitor/hovmoeller_z_vs_time_with_ref.png b/doc/sphinx/source/recipes/figures/monitor/hovmoeller_z_vs_time_with_ref.png new file mode 100755 index 0000000000..734913c60b Binary files /dev/null and b/doc/sphinx/source/recipes/figures/monitor/hovmoeller_z_vs_time_with_ref.png differ diff --git a/doc/sphinx/source/recipes/figures/monitor/variable_vs_lat_with_ref.png b/doc/sphinx/source/recipes/figures/monitor/variable_vs_lat_with_ref.png new file mode 100644 index 0000000000..31cb81135d Binary files /dev/null and b/doc/sphinx/source/recipes/figures/monitor/variable_vs_lat_with_ref.png differ diff --git a/doc/sphinx/source/recipes/recipe_monitor.rst b/doc/sphinx/source/recipes/recipe_monitor.rst index 0358ec36a7..9bdfd5d40b 100644 --- a/doc/sphinx/source/recipes/recipe_monitor.rst +++ b/doc/sphinx/source/recipes/recipe_monitor.rst @@ -210,3 +210,24 @@ Zonal mean profile of ta including a reference dataset. :width: 14cm 1D profile of ta including a reference dataset. + +.. _fig_variable_vs_lat_with_ref: +.. figure:: /recipes/figures/monitor/variable_vs_lat_with_ref.png + :align: center + :width: 14cm + +Zonal mean pr including a reference dataset. + +.. _fig_hovmoeller_z_vs_time_with_ref: +.. figure:: /recipes/figures/monitor/hovmoeller_z_vs_time_with_ref.png + :align: center + :width: 14cm + +Hovmoeller plot (pressure vs. time) of ta including a reference dataset. + +.. _fig_hovmoeller_time_vs_lat_with_ref: +.. figure:: /recipes/figures/monitor/hovmoeller_time_vs_lat_with_ref.png + :align: center + :width: 14cm + +Hovmoeller plot (time vs. latitude) of tas including a reference dataset diff --git a/esmvaltool/config-references.yml b/esmvaltool/config-references.yml index baaaa44c96..cea1a0561b 100644 --- a/esmvaltool/config-references.yml +++ b/esmvaltool/config-references.yml @@ -124,6 +124,11 @@ authors: name: Bojovic, Dragana institute: BSC, Spain orcid: https://orcid.org/0000-0001-7354-1885 + bonnet_pauline: + name: Bonnet, Pauline + institute: DLR, Germany + orcid: https://orcid.org/0000-0003-3780-0784 + github: Paulinebonnet111 brunner_lukas: name: Brunner, Lukas institute: ETH Zurich, Switzerland @@ -252,6 +257,11 @@ authors: name: Hempelmann, Nils institute: IPSL, France orcid: + heuer_helge: + name: Heuer, Helge + institute: DLR, Germany + email: helge.heuer@dlr.de + orcid: https://orcid.org/0000-0003-2411-7150 hogan_emma: name: Hogan, Emma institute: MetOffice, UK @@ -288,10 +298,20 @@ authors: name: Koirala, Sujan institute: MPI-BGC, Germany orcid: https://orcid.org/0000-0001-5681-1986 + kraft_jeremy: + name: Kraft, Jeremy + institute: DLR, Germany + orcid: + github: jeremykraftdlr krasting_john: name: Krasting, John institute: NOAA, USA orcid: https://orcid.org/0000-0002-4650-9844 + kuehbacher_birgit: + name: Kuehbacher, Birgit + institute: DLR, Germany + email: birgit.kuehbacher@dlr.de + orcid: lejeune_quentin: name: Lejeune, Quentin institute: Climate Analytics, Germany @@ -446,6 +466,11 @@ authors: name: Sandstad, Marit institute: Cicero, Norway orcid: + sarauer_ellen: + name: Sarauer, Ellen + institute: DLR, Germany + orcid: + github: ellensarauer serva_federico: name: Serva, Federico institute: CNR, Italy diff --git a/esmvaltool/diag_scripts/monitor/multi_datasets.py b/esmvaltool/diag_scripts/monitor/multi_datasets.py index 6ac399652b..4299e2538c 100644 --- a/esmvaltool/diag_scripts/monitor/multi_datasets.py +++ b/esmvaltool/diag_scripts/monitor/multi_datasets.py @@ -31,7 +31,7 @@ datasets need to be given on the same horizontal and vertical grid (you can use the preprocessors :func:`esmvalcore.preprocessor.regrid` and :func:`esmvalcore.preprocessor.extract_levels` for this). Input data - needs to be 2D with dimensions `latitude`, `height`/`air_pressure`. + needs to be 2D with dimensions `latitude`, `altitude`/`air_pressure`. .. warning:: @@ -42,7 +42,28 @@ - 1D profiles (plot type ``1d_profile``): for each variable separately, all datasets are plotted in one single figure. Input data needs to be 1D with - single dimension `height` / `air_pressure` + single dimension `altitude` / `air_pressure` + - Variable vs. latitude plot (plot type ``variable_vs_lat``): + for each variable separately, all datasets are plotted in one + single figure. Input data needs to be 1D with single + dimension `latitude`. + - Hovmoeller Z vs. time (plot type ``hovmoeller_z_vs_time``): for each + variable and dataset, an individual figure is plotted. If a reference + dataset is defined, also include this dataset and a bias plot into the + figure. Note that if a reference dataset is defined, all input datasets + need to be given on the same temporal and vertical grid (you can use + the preprocessors :func:`esmvalcore.preprocessor.regrid_time` and + :func:`esmvalcore.preprocessor.extract_levels` for this). Input data + needs to be 2D with dimensions `time`, `altitude`/`air_pressure`. + - Hovmoeller time vs. latitude or longitude (plot type + ``hovmoeller_time_vs_lat_or_lon``): for each variable and dataset, an + individual figure is plotted. If a reference dataset is defined, also + include this dataset and a bias plot into the figure. Note that if a + reference dataset is defined, all input datasets need to be given on the + same temporal and horizontal grid (you can use the preprocessors + :func:`esmvalcore.preprocessor.regrid_time` and + :func:`esmvalcore.preprocessor.regrid` for this). Input data + needs to be 2D with dimensions `time`, `latitude`/`longitude`. Author ------ @@ -60,12 +81,16 @@ figure_kwargs: dict, optional Optional keyword arguments for :func:`matplotlib.pyplot.figure`. By default, uses ``constrained_layout: true``. +group_variables_by: str, optional (default: 'short_name') + Facet which is used to create variable groups. For each variable group, an + individual plot is created. plots: dict, optional Plot types plotted by this diagnostic (see list above). Dictionary keys - must be ``timeseries``, ``annual_cycle``, ``map``, ``zonal_mean_profile`` - or ``1d_profile``. - Dictionary values are dictionaries used as options for the corresponding - plot. The allowed options for the different plot types are given below. + must be ``timeseries``, ``annual_cycle``, ``map``, ``zonal_mean_profile``, + ``1d_profile``, ``variable_vs_lat``, ``hovmoeller_z_vs_time``, + ``hovmoeller_time_vs_lat_or_lon``. Dictionary values are dictionaries used + as options for the corresponding plot. The allowed options for the + different plot types are given below. plot_filename: str, optional Filename pattern for the plots. Defaults to ``{plot_type}_{real_name}_{dataset}_{mip}_{exp}_{ensemble}``. @@ -119,6 +144,10 @@ ``{project}`` that vary between the different datasets will be transformed to something like ``ambiguous_project``. Examples: ``title: 'Awesome Plot of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``. +time_format: str, optional (default: None) + :func:`~datetime.datetime.strftime` format string that is used to format + the time axis using :class:`matplotlib.dates.DateFormatter`. If ``None``, + use the default formatting imposed by the iris plotting function. Configuration options for plot type ``annual_cycle`` ---------------------------------------------------- @@ -270,7 +299,7 @@ plot_func: str, optional (default: 'contourf') Plot function used to plot the profiles. Must be a function of :mod:`iris.plot` that supports plotting of 2D cubes with coordinates - latitude and height/air_pressure. + latitude and altitude/air_pressure. plot_kwargs: dict, optional Optional keyword arguments for the plot function defined by ``plot_func``. Dictionary keys are elements identified by ``facet_used_for_labels`` or @@ -352,6 +381,189 @@ show_y_minor_ticklabels: bool, optional (default: False) Show tick labels for the minor ticks on the Y axis. +Configuration options for plot type ``variable_vs_lat`` +------------------------------------------------------- +gridline_kwargs: dict, optional + Optional keyword arguments for grid lines. By default, ``color: lightgrey, + alpha: 0.5`` are used. Use ``gridline_kwargs: false`` to not show grid + lines. +legend_kwargs: dict, optional + Optional keyword arguments for :func:`matplotlib.pyplot.legend`. Use + ``legend_kwargs: false`` to not show legends. +plot_kwargs: dict, optional + Optional keyword arguments for :func:`iris.plot.plot`. Dictionary keys are + elements identified by ``facet_used_for_labels`` or ``default``, e.g., + ``CMIP6`` if ``facet_used_for_labels: project`` or ``historical`` if + ``facet_used_for_labels: exp``. Dictionary values are dictionaries used as + keyword arguments for :func:`iris.plot.plot`. String arguments can include + facets in curly brackets which will be derived from the corresponding + dataset, e.g., ``{project}``, ``{short_name}``, ``{exp}``. Examples: + ``default: {linestyle: '-', label: '{project}'}, CMIP6: {color: red, + linestyle: '--'}, OBS: {color: black}``. +pyplot_kwargs: dict, optional + Optional calls to functions of :mod:`matplotlib.pyplot`. Dictionary keys + are functions of :mod:`matplotlib.pyplot`. Dictionary values are used as + single argument for these functions. String arguments can include facets in + curly brackets which will be derived from the datasets plotted in the + corresponding plot, e.g., ``{short_name}``, ``{exp}``. Facets like + ``{project}`` that vary between the different datasets will be transformed + to something like ``ambiguous_project``. Examples: ``title: 'Awesome Plot + of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``. + +Configuration options for plot type ``hovmoeller_z_vs_time`` +------------------------------------------------------------ +cbar_label: str, optional (default: '{short_name} [{units}]') + Colorbar label. Can include facets in curly brackets which will be derived + from the corresponding dataset, e.g., ``{project}``, ``{short_name}``, + ``{exp}``. +cbar_label_bias: str, optional (default: 'Δ{short_name} [{units}]') + Colorbar label for plotting biases. Can include facets in curly brackets + which will be derived from the corresponding dataset, e.g., ``{project}``, + ``{short_name}``, ``{exp}``. This option has no effect if no reference + dataset is given. +cbar_kwargs: dict, optional + Optional keyword arguments for :func:`matplotlib.pyplot.colorbar`. By + default, uses ``orientation: vertical``. +cbar_kwargs_bias: dict, optional + Optional keyword arguments for :func:`matplotlib.pyplot.colorbar` for + plotting biases. These keyword arguments update (and potentially overwrite) + the ``cbar_kwargs`` for the bias plot. This option has no effect if no + reference dataset is given. +common_cbar: bool, optional (default: False) + Use a common colorbar for the top panels (i.e., plots of the dataset and + the corresponding reference dataset) when using a reference dataset. If + neither ``vmin`` and ``vmix`` nor ``levels`` is given in ``plot_kwargs``, + the colorbar bounds are inferred from the dataset in the top left panel, + which might lead to an inappropriate colorbar for the reference dataset + (top right panel). Thus, the use of the ``plot_kwargs`` ``vmin`` and + ``vmax`` or ``levels`` is highly recommend when using this ``common_cbar: + true``. This option has no effect if no reference dataset is given. +fontsize: int, optional (default: 10) + Fontsize used for ticks, labels and titles. For the latter, use the given + fontsize plus 2. Does not affect suptitles. +log_y: bool, optional (default: True) + Use logarithmic Y-axis. +plot_func: str, optional (default: 'contourf') + Plot function used to plot the profiles. Must be a function of + :mod:`iris.plot` that supports plotting of 2D cubes with coordinates + latitude and altitude/air_pressure. +plot_kwargs: dict, optional + Optional keyword arguments for the plot function defined by ``plot_func``. + Dictionary keys are elements identified by ``facet_used_for_labels`` or + ``default``, e.g., ``CMIP6`` if ``facet_used_for_labels: project`` or + ``historical`` if ``facet_used_for_labels: exp``. Dictionary values are + dictionaries used as keyword arguments for the plot function defined by + ``plot_func``. String arguments can include facets in curly brackets which + will be derived from the corresponding dataset, e.g., ``{project}``, + ``{short_name}``, ``{exp}``. Examples: ``default: {levels: 2}, CMIP6: + {vmin: 200, vmax: 250}``. +plot_kwargs_bias: dict, optional + Optional keyword arguments for the plot function defined by ``plot_func`` + for plotting biases. These keyword arguments update (and potentially + overwrite) the ``plot_kwargs`` for the bias plot. This option has no effect + if no reference dataset is given. See option ``plot_kwargs`` for more + details. By default, uses ``cmap: bwr``. +pyplot_kwargs: dict, optional + Optional calls to functions of :mod:`matplotlib.pyplot`. Dictionary keys + are functions of :mod:`matplotlib.pyplot`. Dictionary values are used as + single argument for these functions. String arguments can include facets in + curly brackets which will be derived from the corresponding dataset, e.g., + ``{project}``, ``{short_name}``, ``{exp}``. Examples: ``title: 'Awesome + Plot of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``. +rasterize: bool, optional (default: True) + If ``True``, use `rasterization + `_ for + profile plots to produce smaller files. This is only relevant for vector + graphics (e.g., ``output_file_type=pdf,svg,ps``). +show_stats: bool, optional (default: True) + Show basic statistics on the plots. +show_y_minor_ticklabels: bool, optional (default: False) + Show tick labels for the minor ticks on the Y axis. +x_pos_stats_avg: float, optional (default: 0.01) + Text x-position of average (shown on the left) in Axes coordinates. Can be + adjusted to avoid overlap with the figure. Only relevant if ``show_stats: + true``. +x_pos_stats_bias: float, optional (default: 0.7) + Text x-position of bias statistics (shown on the right) in Axes + coordinates. Can be adjusted to avoid overlap with the figure. Only + relevant if ``show_stats: true``. +time_format: str, optional (default: None) + :func:`~datetime.datetime.strftime` format string that is used to format + the time axis using :class:`matplotlib.dates.DateFormatter`. If ``None``, + use the default formatting imposed by the iris plotting function. + +Configuration options for plot type ``hovmoeller_time_vs_lat_or_lon`` +--------------------------------------------------------------------- +cbar_label: str, optional (default: '{short_name} [{units}]') + Colorbar label. Can include facets in curly brackets which will be derived + from the corresponding dataset, e.g., ``{project}``, ``{short_name}``, + ``{exp}``. +cbar_label_bias: str, optional (default: 'Δ{short_name} [{units}]') + Colorbar label for plotting biases. Can include facets in curly brackets + which will be derived from the corresponding dataset, e.g., ``{project}``, + ``{short_name}``, ``{exp}``. This option has no effect if no reference + dataset is given. +cbar_kwargs: dict, optional + Optional keyword arguments for :func:`matplotlib.pyplot.colorbar`. By + default, uses ``orientation: vertical``. +cbar_kwargs_bias: dict, optional + Optional keyword arguments for :func:`matplotlib.pyplot.colorbar` for + plotting biases. These keyword arguments update (and potentially overwrite) + the ``cbar_kwargs`` for the bias plot. This option has no effect if no + reference dataset is given. +common_cbar: bool, optional (default: False) + Use a common colorbar for the top panels (i.e., plots of the dataset and + the corresponding reference dataset) when using a reference dataset. If + neither ``vmin`` and ``vmix`` nor ``levels`` is given in ``plot_kwargs``, + the colorbar bounds are inferred from the dataset in the top left panel, + which might lead to an inappropriate colorbar for the reference dataset + (top right panel). Thus, the use of the ``plot_kwargs`` ``vmin`` and + ``vmax`` or ``levels`` is highly recommend when using this ``common_cbar: + true``. This option has no effect if no reference dataset is given. +fontsize: int, optional (default: 10) + Fontsize used for ticks, labels and titles. For the latter, use the given + fontsize plus 2. Does not affect suptitles. +plot_func: str, optional (default: 'contourf') + Plot function used to plot the profiles. Must be a function of + :mod:`iris.plot` that supports plotting of 2D cubes with coordinates + latitude and height/air_pressure. +plot_kwargs: dict, optional + Optional keyword arguments for the plot function defined by ``plot_func``. + Dictionary keys are elements identified by ``facet_used_for_labels`` or + ``default``, e.g., ``CMIP6`` if ``facet_used_for_labels: project`` or + ``historical`` if ``facet_used_for_labels: exp``. Dictionary values are + dictionaries used as keyword arguments for the plot function defined by + ``plot_func``. String arguments can include facets in curly brackets which + will be derived from the corresponding dataset, e.g., ``{project}``, + ``{short_name}``, ``{exp}``. Examples: ``default: {levels: 2}, CMIP6: + {vmin: 200, vmax: 250}``. +plot_kwargs_bias: dict, optional + Optional keyword arguments for the plot function defined by ``plot_func`` + for plotting biases. These keyword arguments update (and potentially + overwrite) the ``plot_kwargs`` for the bias plot. This option has no effect + if no reference dataset is given. See option ``plot_kwargs`` for more + details. By default, uses ``cmap: bwr``. +pyplot_kwargs: dict, optional + Optional calls to functions of :mod:`matplotlib.pyplot`. Dictionary keys + are functions of :mod:`matplotlib.pyplot`. Dictionary values are used as + single argument for these functions. String arguments can include facets in + curly brackets which will be derived from the corresponding dataset, e.g., + ``{project}``, ``{short_name}``, ``{exp}``. Examples: ``title: 'Awesome + Plot of {long_name}'``, ``xlabel: '{short_name}'``, ``xlim: [0, 5]``. +rasterize: bool, optional (default: False) + If ``True``, use `rasterization + `_ for + profile plots to produce smaller files. This is only relevant for vector + graphics (e.g., ``output_file_type=pdf,svg,ps``). +show_y_minor_ticks: bool, optional (default: True) + Show minor ticks for time on the Y axis. +show_x_minor_ticks: bool, optional (default: True) + Show minor ticks for latitude or longitude on the X axis. +time_format: str, optional (default: None) + :func:`~datetime.datetime.strftime` format string that is used to format + the time axis using :class:`matplotlib.dates.DateFormatter`. If ``None``, + use the default formatting imposed by the iris plotting function. + .. hint:: Extra arguments given to the recipe are ignored, so it is safe to use yaml @@ -367,6 +579,7 @@ import cartopy.crs as ccrs import iris import matplotlib as mpl +import matplotlib.dates as mdates import matplotlib.pyplot as plt import numpy as np import seaborn as sns @@ -374,7 +587,12 @@ from iris.coord_categorisation import add_year from iris.coords import AuxCoord from matplotlib.gridspec import GridSpec -from matplotlib.ticker import FormatStrFormatter, LogLocator, NullFormatter +from matplotlib.ticker import ( + AutoMinorLocator, + FormatStrFormatter, + LogLocator, + NullFormatter, +) from sklearn.metrics import r2_score import esmvaltool.diag_scripts.shared.iris_helpers as ih @@ -397,16 +615,19 @@ def __init__(self, config): """Initialize class member.""" super().__init__(config) - # Get default stettings + # Get default settings self.cfg = deepcopy(self.cfg) self.cfg.setdefault('facet_used_for_labels', 'dataset') self.cfg.setdefault('figure_kwargs', {'constrained_layout': True}) + self.cfg.setdefault('group_variables_by', 'short_name') self.cfg.setdefault('savefig_kwargs', { 'bbox_inches': 'tight', 'dpi': 300, 'orientation': 'landscape', }) self.cfg.setdefault('seaborn_settings', {'style': 'ticks'}) + logger.info("Using facet '%s' to group variables", + self.cfg['group_variables_by']) logger.info("Using facet '%s' to create labels", self.cfg['facet_used_for_labels']) @@ -414,7 +635,7 @@ def __init__(self, config): self.input_data = self._load_and_preprocess_data() self.grouped_input_data = group_metadata( self.input_data, - 'short_name', + self.cfg['group_variables_by'], sort=self.cfg['facet_used_for_labels'], ) @@ -436,7 +657,10 @@ def __init__(self, config): 'annual_cycle', 'map', 'zonal_mean_profile', - '1d_profile' + '1d_profile', + 'variable_vs_lat', + 'hovmoeller_z_vs_time', + 'hovmoeller_time_vs_lat_or_lon', ] for (plot_type, plot_options) in self.plots.items(): if plot_type not in self.supported_plot_types: @@ -453,14 +677,15 @@ def __init__(self, config): self.plots[plot_type].setdefault('legend_kwargs', {}) self.plots[plot_type].setdefault('plot_kwargs', {}) self.plots[plot_type].setdefault('pyplot_kwargs', {}) + self.plots[plot_type].setdefault('time_format', None) - if plot_type == 'annual_cycle': + elif plot_type == 'annual_cycle': self.plots[plot_type].setdefault('gridline_kwargs', {}) self.plots[plot_type].setdefault('legend_kwargs', {}) self.plots[plot_type].setdefault('plot_kwargs', {}) self.plots[plot_type].setdefault('pyplot_kwargs', {}) - if plot_type == 'map': + elif plot_type == 'map': self.plots[plot_type].setdefault( 'cbar_label', '{short_name} [{units}]') self.plots[plot_type].setdefault( @@ -491,7 +716,7 @@ def __init__(self, config): self.plots[plot_type].setdefault('x_pos_stats_avg', 0.0) self.plots[plot_type].setdefault('x_pos_stats_bias', 0.92) - if plot_type == 'zonal_mean_profile': + elif plot_type == 'zonal_mean_profile': self.plots[plot_type].setdefault( 'cbar_label', '{short_name} [{units}]') self.plots[plot_type].setdefault( @@ -518,7 +743,7 @@ def __init__(self, config): self.plots[plot_type].setdefault('x_pos_stats_avg', 0.01) self.plots[plot_type].setdefault('x_pos_stats_bias', 0.7) - if plot_type == '1d_profile': + elif plot_type == '1d_profile': self.plots[plot_type].setdefault('aspect_ratio', 1.5) self.plots[plot_type].setdefault('gridline_kwargs', {}) self.plots[plot_type].setdefault('legend_kwargs', {}) @@ -529,6 +754,63 @@ def __init__(self, config): self.plots[plot_type].setdefault( 'show_y_minor_ticklabels', False ) + elif plot_type == 'variable_vs_lat': + self.plots[plot_type].setdefault('gridline_kwargs', {}) + self.plots[plot_type].setdefault('legend_kwargs', {}) + self.plots[plot_type].setdefault('plot_kwargs', {}) + self.plots[plot_type].setdefault('pyplot_kwargs', {}) + + elif plot_type == 'hovmoeller_z_vs_time': + self.plots[plot_type].setdefault('cbar_label', + '{short_name} [{units}]') + self.plots[plot_type].setdefault('cbar_label_bias', + 'Δ{short_name} [{units}]') + self.plots[plot_type].setdefault('cbar_kwargs', + {'orientation': 'vertical'}) + self.plots[plot_type].setdefault('cbar_kwargs_bias', {}) + self.plots[plot_type].setdefault('common_cbar', False) + self.plots[plot_type].setdefault('fontsize', 10) + self.plots[plot_type].setdefault('log_y', True) + self.plots[plot_type].setdefault('plot_func', 'contourf') + self.plots[plot_type].setdefault('plot_kwargs', {}) + self.plots[plot_type].setdefault('plot_kwargs_bias', {}) + self.plots[plot_type]['plot_kwargs_bias'].setdefault( + 'cmap', 'bwr') + self.plots[plot_type].setdefault('pyplot_kwargs', {}) + self.plots[plot_type].setdefault('rasterize', True) + self.plots[plot_type].setdefault('show_stats', True) + self.plots[plot_type].setdefault('show_y_minor_ticklabels', + False) + self.plots[plot_type].setdefault('time_format', None) + self.plots[plot_type].setdefault('x_pos_stats_avg', 0.01) + self.plots[plot_type].setdefault('x_pos_stats_bias', 0.7) + + elif plot_type == 'hovmoeller_time_vs_lat_or_lon': + self.plots[plot_type].setdefault( + 'cbar_label', '{short_name} [{units}]') + self.plots[plot_type].setdefault( + 'cbar_label_bias', 'Δ{short_name} [{units}]') + self.plots[plot_type].setdefault( + 'cbar_kwargs', {'orientation': 'vertical'} + ) + self.plots[plot_type].setdefault('cbar_kwargs_bias', {}) + self.plots[plot_type].setdefault('common_cbar', False) + self.plots[plot_type].setdefault('fontsize', 10) + self.plots[plot_type].setdefault('plot_func', 'contourf') + self.plots[plot_type].setdefault('plot_kwargs', {}) + self.plots[plot_type].setdefault('plot_kwargs_bias', {}) + self.plots[plot_type]['plot_kwargs_bias'].setdefault( + 'cmap', 'bwr' + ) + self.plots[plot_type].setdefault('pyplot_kwargs', {}) + self.plots[plot_type].setdefault('rasterize', False) + self.plots[plot_type].setdefault( + 'show_y_minor_ticks', True + ) + self.plots[plot_type].setdefault( + 'show_x_minor_ticks', True + ) + self.plots[plot_type].setdefault('time_format', None) # Check that facet_used_for_labels is present for every dataset for dataset in self.input_data: @@ -587,10 +869,10 @@ def _add_stats(self, plot_type, axes, dim_coords, dataset, # Different options for the different plots types fontsize = 6.0 y_pos = 0.95 - if plot_type == 'map': - x_pos_bias = self.plots[plot_type]['x_pos_stats_bias'] - x_pos = self.plots[plot_type]['x_pos_stats_avg'] - elif plot_type in ['zonal_mean_profile']: + if all([ + 'x_pos_stats_avg' in self.plots[plot_type], + 'x_pos_stats_bias' in self.plots[plot_type], + ]): x_pos_bias = self.plots[plot_type]['x_pos_stats_bias'] x_pos = self.plots[plot_type]['x_pos_stats_avg'] else: @@ -757,7 +1039,8 @@ def _get_plot_kwargs(self, plot_type, dataset, bias=False): plot_kwargs[key] = val # Default settings for different plot types - if plot_type in ('timeseries', 'annual_cycle', '1d_profile'): + if plot_type in ('timeseries', 'annual_cycle', '1d_profile', + 'variable_vs_lat'): plot_kwargs.setdefault('label', label) return deepcopy(plot_kwargs) @@ -822,6 +1105,7 @@ def _plot_map_with_ref(self, plot_func, dataset, ref_dataset): axes_data.gridlines(**gridline_kwargs) axes_data.set_title(self._get_label(dataset), pad=3.0) self._add_stats(plot_type, axes_data, dim_coords_dat, dataset) + self._process_pyplot_kwargs(plot_type, dataset) # Plot reference dataset (top right) # Note: make sure to use the same vmin and vmax than the top left @@ -838,6 +1122,7 @@ def _plot_map_with_ref(self, plot_func, dataset, ref_dataset): axes_ref.gridlines(**gridline_kwargs) axes_ref.set_title(self._get_label(ref_dataset), pad=3.0) self._add_stats(plot_type, axes_ref, dim_coords_ref, ref_dataset) + self._process_pyplot_kwargs(plot_type, ref_dataset) # Add colorbar(s) self._add_colorbar(plot_type, plot_data, plot_ref, axes_data, @@ -981,6 +1266,7 @@ def _plot_zonal_mean_profile_with_ref(self, plot_func, dataset, else: axes_data.get_yaxis().set_minor_formatter(NullFormatter()) self._add_stats(plot_type, axes_data, dim_coords_dat, dataset) + self._process_pyplot_kwargs(plot_type, dataset) # Plot reference dataset (top right) # Note: make sure to use the same vmin and vmax than the top left @@ -995,6 +1281,7 @@ def _plot_zonal_mean_profile_with_ref(self, plot_func, dataset, axes_ref.set_title(self._get_label(ref_dataset), pad=3.0) plt.setp(axes_ref.get_yticklabels(), visible=False) self._add_stats(plot_type, axes_ref, dim_coords_ref, ref_dataset) + self._process_pyplot_kwargs(plot_type, ref_dataset) # Add colorbar(s) self._add_colorbar(plot_type, plot_data, plot_ref, axes_data, @@ -1105,50 +1392,402 @@ def _plot_zonal_mean_profile_without_ref(self, plot_func, dataset): return (plot_path, {netcdf_path: cube}) - def _process_pyplot_kwargs(self, plot_type, dataset): - """Process functions for :mod:`matplotlib.pyplot`.""" - pyplot_kwargs = self.plots[plot_type]['pyplot_kwargs'] - for (func, arg) in pyplot_kwargs.items(): - if isinstance(arg, str): - arg = self._fill_facet_placeholders( - arg, - dataset, - f"pyplot_kwargs of {plot_type} '{func}: {arg}'", - ) - if arg is None: - getattr(plt, func)() - else: - getattr(plt, func)(arg) - - @staticmethod - def _check_cube_dimensions(cube, plot_type): - """Check that cube has correct dimensional variables.""" - expected_dimensions_dict = { - 'annual_cycle': (['month_number'],), - 'map': (['latitude', 'longitude'],), - 'zonal_mean_profile': (['latitude', 'air_pressure'], - ['latitude', 'altitude']), - 'timeseries': (['time'],), - '1d_profile': (['air_pressure'], - ['altitude']), + def _plot_hovmoeller_z_vs_time_without_ref(self, plot_func, dataset): + """Plot Hovmoeller Z vs. time for single dataset without reference.""" + plot_type = 'hovmoeller_z_vs_time' + logger.info( + "Plotting Hovmoeller Z vs. time without reference dataset" + " for '%s'", self._get_label(dataset)) - } - if plot_type not in expected_dimensions_dict: - raise NotImplementedError(f"plot_type '{plot_type}' not supported") - expected_dimensions = expected_dimensions_dict[plot_type] - for dims in expected_dimensions: - cube_dims = [cube.coords(dim, dim_coords=True) for dim in dims] - if all(cube_dims) and cube.ndim == len(dims): - return dims - expected_dims_str = ' or '.join( - [str(dims) for dims in expected_dimensions] - ) - raise ValueError( - f"Expected cube that exactly has the dimensional coordinates " - f"{expected_dims_str}, got {cube.summary(shorten=True)}") + # Make sure that the data has the correct dimensions + cube = dataset['cube'] + dim_coords_dat = self._check_cube_dimensions(cube, plot_type) - @staticmethod - def _fill_facet_placeholders(string, dataset, description): + # Create plot with desired settings + with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)): + fig = plt.figure(**self.cfg['figure_kwargs']) + axes = fig.add_subplot() + plot_kwargs = self._get_plot_kwargs(plot_type, dataset) + plot_kwargs['axes'] = axes + plot_hovmoeller = plot_func(cube, **plot_kwargs) + + # Print statistics if desired + self._add_stats(plot_type, axes, dim_coords_dat, dataset) + + # Setup colorbar + fontsize = self.plots[plot_type]['fontsize'] + colorbar = fig.colorbar(plot_hovmoeller, + ax=axes, + **self._get_cbar_kwargs(plot_type)) + colorbar.set_label(self._get_cbar_label(plot_type, dataset), + fontsize=fontsize) + colorbar.ax.tick_params(labelsize=fontsize) + + # Customize plot + axes.set_title(self._get_label(dataset)) + fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-" + f"{dataset['end_year']})") + z_coord = cube.coord(axis='Z') + axes.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]') + if self.plots[plot_type]['log_y']: + axes.set_yscale('log') + axes.get_yaxis().set_major_formatter( + FormatStrFormatter('%.1f')) + if self.plots[plot_type]['show_y_minor_ticklabels']: + axes.get_yaxis().set_minor_formatter( + FormatStrFormatter('%.1f')) + else: + axes.get_yaxis().set_minor_formatter(NullFormatter()) + if self.plots[plot_type]['time_format'] is not None: + axes.get_xaxis().set_major_formatter( + mdates.DateFormatter(self.plots[plot_type]['time_format'])) + axes.set_xlabel('time') + self._process_pyplot_kwargs(plot_type, dataset) + + # Rasterization + if self.plots[plot_type]['rasterize']: + self._set_rasterized([axes]) + + # File paths + plot_path = self.get_plot_path(plot_type, dataset) + netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg) + + return (plot_path, {netcdf_path: cube}) + + def _plot_hovmoeller_z_vs_time_with_ref(self, plot_func, dataset, + ref_dataset): + """Plot Hovmoeller Z vs. time for single dataset with reference.""" + plot_type = 'hovmoeller_z_vs_time' + logger.info( + "Plotting Hovmoeller z vs. time with reference dataset" + " '%s' for '%s'", self._get_label(ref_dataset), + self._get_label(dataset)) + + # Make sure that the data has the correct dimensions + cube = dataset['cube'] + ref_cube = ref_dataset['cube'] + dim_coords_dat = self._check_cube_dimensions(cube, plot_type) + dim_coords_ref = self._check_cube_dimensions(ref_cube, plot_type) + + # Create single figure with multiple axes + with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)): + fig = plt.figure(**self.cfg['figure_kwargs']) + gridspec = GridSpec(5, + 4, + figure=fig, + height_ratios=[1.0, 1.0, 0.4, 1.0, 1.0]) + + # Options used for all subplots + plot_kwargs = self._get_plot_kwargs(plot_type, dataset) + fontsize = self.plots[plot_type]['fontsize'] + + # Plot dataset (top left) + axes_data = fig.add_subplot(gridspec[0:2, 0:2]) + plot_kwargs['axes'] = axes_data + plot_data = plot_func(cube, **plot_kwargs) + axes_data.set_title(self._get_label(dataset), pad=3.0) + z_coord = cube.coord(axis='Z') + axes_data.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]') + if self.plots[plot_type]['log_y']: + axes_data.set_yscale('log') + axes_data.get_yaxis().set_major_formatter( + FormatStrFormatter('%.1f')) + if self.plots[plot_type]['show_y_minor_ticklabels']: + axes_data.get_yaxis().set_minor_formatter( + FormatStrFormatter('%.1f')) + else: + axes_data.get_yaxis().set_minor_formatter(NullFormatter()) + if self.plots[plot_type]['time_format'] is not None: + axes_data.get_xaxis().set_major_formatter( + mdates.DateFormatter(self.plots[plot_type]['time_format'])) + self._add_stats(plot_type, axes_data, dim_coords_dat, dataset) + self._process_pyplot_kwargs(plot_type, dataset) + + # Plot reference dataset (top right) + # Note: make sure to use the same vmin and vmax than the top left + # plot if a common colorbar is desired + axes_ref = fig.add_subplot(gridspec[0:2, 2:4], + sharex=axes_data, + sharey=axes_data) + plot_kwargs['axes'] = axes_ref + if self.plots[plot_type]['common_cbar']: + plot_kwargs.setdefault('vmin', plot_data.get_clim()[0]) + plot_kwargs.setdefault('vmax', plot_data.get_clim()[1]) + plot_ref = plot_func(ref_cube, **plot_kwargs) + axes_ref.set_title(self._get_label(ref_dataset), pad=3.0) + plt.setp(axes_ref.get_yticklabels(), visible=False) + self._add_stats(plot_type, axes_ref, dim_coords_ref, ref_dataset) + self._process_pyplot_kwargs(plot_type, ref_dataset) + + # Add colorbar(s) + self._add_colorbar(plot_type, plot_data, plot_ref, axes_data, + axes_ref, dataset, ref_dataset) + + # Plot bias (bottom center) + bias_cube = cube - ref_cube + axes_bias = fig.add_subplot(gridspec[3:5, 1:3], + sharex=axes_data, + sharey=axes_data) + plot_kwargs_bias = self._get_plot_kwargs(plot_type, + dataset, + bias=True) + plot_kwargs_bias['axes'] = axes_bias + plot_bias = plot_func(bias_cube, **plot_kwargs_bias) + axes_bias.set_title( + f"{self._get_label(dataset)} - {self._get_label(ref_dataset)}", + pad=3.0, + ) + axes_bias.set_xlabel('time') + axes_bias.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]') + cbar_kwargs_bias = self._get_cbar_kwargs(plot_type, bias=True) + cbar_bias = fig.colorbar(plot_bias, + ax=axes_bias, + **cbar_kwargs_bias) + cbar_bias.set_label( + self._get_cbar_label(plot_type, dataset, bias=True), + fontsize=fontsize, + ) + cbar_bias.ax.tick_params(labelsize=fontsize) + self._add_stats(plot_type, axes_bias, dim_coords_dat, dataset, + ref_dataset) + + # Customize plot + fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-" + f"{dataset['end_year']})") + self._process_pyplot_kwargs(plot_type, dataset) + + # Rasterization + if self.plots[plot_type]['rasterize']: + self._set_rasterized([axes_data, axes_ref, axes_bias]) + + # File paths + plot_path = self.get_plot_path(plot_type, dataset) + netcdf_path = (get_diagnostic_filename( + Path(plot_path).stem + "_{pos}", self.cfg)) + netcdf_paths = { + netcdf_path.format(pos='top_left'): cube, + netcdf_path.format(pos='top_right'): ref_cube, + netcdf_path.format(pos='bottom'): bias_cube, + } + + return (plot_path, netcdf_paths) + + def _plot_hovmoeller_time_vs_lat_or_lon_with_ref(self, plot_func, dataset, + ref_dataset): + """Plot the hovmoeller profile for single dataset with reference.""" + plot_type = 'hovmoeller_time_vs_lat_or_lon' + logger.info("Plotting Hovmoeller plots with reference dataset" + " '%s' for '%s'", + self._get_label(ref_dataset), self._get_label(dataset)) + + # Make sure that the data has the correct dimensions + cube = dataset['cube'] + ref_cube = ref_dataset['cube'] + dim_coords_dat = self._check_cube_dimensions(cube, plot_type) + self._check_cube_dimensions(ref_cube, plot_type) + + # Create single figure with multiple axes + with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)): + fig = plt.figure(**self.cfg['figure_kwargs']) + gridspec = GridSpec(5, 4, figure=fig, + height_ratios=[1.0, 1.0, 0.4, 1.0, 1.0]) + + # Options used for all subplots + plot_kwargs = self._get_plot_kwargs(plot_type, dataset) + fontsize = self.plots[plot_type]['fontsize'] + + # Plot dataset (top left) + axes_data = fig.add_subplot(gridspec[0:2, 0:2]) + plot_kwargs['axes'] = axes_data + coord_names = [coord[0].name() for coord in cube.dim_coords] + if coord_names[0] == "time": + coord_names.reverse() + plot_kwargs['coords'] = coord_names + plot_data = plot_func(cube, **plot_kwargs) + axes_data.set_title(self._get_label(dataset), pad=3.0) + axes_data.set_ylabel('time') + if self.plots[plot_type]['time_format'] is not None: + axes_data.get_yaxis().set_major_formatter(mdates.DateFormatter( + self.plots[plot_type]['time_format'])) + if self.plots[plot_type]['show_y_minor_ticks']: + axes_data.get_yaxis().set_minor_locator(AutoMinorLocator()) + if self.plots[plot_type]['show_x_minor_ticks']: + axes_data.get_xaxis().set_minor_locator(AutoMinorLocator()) + self._process_pyplot_kwargs(plot_type, dataset) + + # Plot reference dataset (top right) + # Note: make sure to use the same vmin and vmax than the top left + # plot if a common colorbar is desired + axes_ref = fig.add_subplot(gridspec[0:2, 2:4], sharex=axes_data, + sharey=axes_data) + plot_kwargs['axes'] = axes_ref + if self.plots[plot_type]['common_cbar']: + plot_kwargs.setdefault('vmin', plot_data.get_clim()[0]) + plot_kwargs.setdefault('vmax', plot_data.get_clim()[1]) + plot_ref = plot_func(ref_cube, **plot_kwargs) + axes_ref.set_title(self._get_label(ref_dataset), pad=3.0) + plt.setp(axes_ref.get_yticklabels(), visible=False) + self._process_pyplot_kwargs(plot_type, ref_dataset) + + # Add colorbar(s) + self._add_colorbar(plot_type, plot_data, plot_ref, axes_data, + axes_ref, dataset, ref_dataset) + + # Plot bias (bottom center) + bias_cube = cube - ref_cube + axes_bias = fig.add_subplot(gridspec[3:5, 1:3], sharex=axes_data, + sharey=axes_data) + plot_kwargs_bias = self._get_plot_kwargs(plot_type, dataset, + bias=True) + plot_kwargs_bias['axes'] = axes_bias + plot_kwargs_bias['coords'] = coord_names + plot_bias = plot_func(bias_cube, **plot_kwargs_bias) + axes_bias.set_title( + f"{self._get_label(dataset)} - {self._get_label(ref_dataset)}", + pad=3.0, + ) + axes_bias.set_ylabel('time') + if 'latitude' in dim_coords_dat: + axes_bias.set_xlabel('latitude [°N]') + elif 'longitude' in dim_coords_dat: + axes_bias.set_xlabel('longitude [°E]') + cbar_kwargs_bias = self._get_cbar_kwargs(plot_type, bias=True) + cbar_bias = fig.colorbar(plot_bias, ax=axes_bias, + **cbar_kwargs_bias) + cbar_bias.set_label( + self._get_cbar_label(plot_type, dataset, bias=True), + fontsize=fontsize, + ) + cbar_bias.ax.tick_params(labelsize=fontsize) + + # Customize plot + fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-" + f"{dataset['end_year']})") + self._process_pyplot_kwargs(plot_type, dataset) + + # Rasterization + if self.plots[plot_type]['rasterize']: + self._set_rasterized([axes_data, axes_ref, axes_bias]) + + # File paths + plot_path = self.get_plot_path(plot_type, dataset) + netcdf_path = ( + get_diagnostic_filename(Path(plot_path).stem + "_{pos}", self.cfg) + ) + netcdf_paths = { + netcdf_path.format(pos='top_left'): cube, + netcdf_path.format(pos='top_right'): ref_cube, + netcdf_path.format(pos='bottom'): bias_cube, + } + + return (plot_path, netcdf_paths) + + def _plot_hovmoeller_time_vs_lat_or_lon_without_ref(self, plot_func, + dataset): + """Plot time vs zonal or meridional Hovmoeller without reference.""" + plot_type = 'hovmoeller_time_vs_lat_or_lon' + logger.info("Plotting Hovmoeller plots without reference dataset" + " for '%s'", self._get_label(dataset)) + + # Make sure that the data has the correct dimensions + cube = dataset['cube'] + dim_coords_dat = self._check_cube_dimensions(cube, plot_type) + + # Create plot with desired settings + with mpl.rc_context(self._get_custom_mpl_rc_params(plot_type)): + fig = plt.figure(**self.cfg['figure_kwargs']) + axes = fig.add_subplot() + plot_kwargs = self._get_plot_kwargs(plot_type, dataset) + plot_kwargs['axes'] = axes + + # Make sure time is on y-axis + plot_kwargs['coords'] = list(reversed(dim_coords_dat)) + plot_hovmoeller = plot_func(cube, **plot_kwargs) + + # Setup colorbar + fontsize = self.plots[plot_type]['fontsize'] + colorbar = fig.colorbar(plot_hovmoeller, ax=axes, + **self._get_cbar_kwargs(plot_type)) + colorbar.set_label(self._get_cbar_label(plot_type, dataset), + fontsize=fontsize) + colorbar.ax.tick_params(labelsize=fontsize) + + # Customize plot + axes.set_title(self._get_label(dataset)) + fig.suptitle(f"{dataset['long_name']} ({dataset['start_year']}-" + f"{dataset['end_year']})") + if 'latitude' in dim_coords_dat: + axes.set_xlabel('latitude [°N]') + elif 'longitude' in dim_coords_dat: + axes.set_xlabel('longitude [°E]') + axes.set_ylabel('time') + if self.plots[plot_type]['time_format'] is not None: + axes.get_yaxis().set_major_formatter(mdates.DateFormatter( + self.plots[plot_type]['time_format']) + ) + if self.plots[plot_type]['show_y_minor_ticks']: + axes.get_yaxis().set_minor_locator(AutoMinorLocator()) + if self.plots[plot_type]['show_x_minor_ticks']: + axes.get_xaxis().set_minor_locator(AutoMinorLocator()) + self._process_pyplot_kwargs(plot_type, dataset) + + # Rasterization + if self.plots[plot_type]['rasterize']: + self._set_rasterized([axes]) + + # File paths + plot_path = self.get_plot_path(plot_type, dataset) + netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg) + return (plot_path, {netcdf_path: cube}) + + def _process_pyplot_kwargs(self, plot_type, dataset): + """Process functions for :mod:`matplotlib.pyplot`.""" + pyplot_kwargs = self.plots[plot_type]['pyplot_kwargs'] + for (func, arg) in pyplot_kwargs.items(): + if isinstance(arg, str): + arg = self._fill_facet_placeholders( + arg, + dataset, + f"pyplot_kwargs of {plot_type} '{func}: {arg}'", + ) + if arg is None: + getattr(plt, func)() + else: + getattr(plt, func)(arg) + + @staticmethod + def _check_cube_dimensions(cube, plot_type): + """Check that cube has correct dimensional variables.""" + expected_dimensions_dict = { + 'annual_cycle': (['month_number'],), + 'map': (['latitude', 'longitude'],), + 'zonal_mean_profile': (['latitude', 'air_pressure'], + ['latitude', 'altitude']), + 'timeseries': (['time'],), + '1d_profile': (['air_pressure'], + ['altitude']), + 'variable_vs_lat': (['latitude'],), + 'hovmoeller_z_vs_time': (['time', 'air_pressure'], + ['time', 'altitude']), + 'hovmoeller_time_vs_lat_or_lon': (['time', 'latitude'], + ['time', 'longitude']), + } + if plot_type not in expected_dimensions_dict: + raise NotImplementedError(f"plot_type '{plot_type}' not supported") + expected_dimensions = expected_dimensions_dict[plot_type] + for dims in expected_dimensions: + cube_dims = [cube.coords(dim, dim_coords=True) for dim in dims] + if all(cube_dims) and cube.ndim == len(dims): + return dims + expected_dims_str = ' or '.join( + [str(dims) for dims in expected_dimensions] + ) + raise ValueError( + f"Expected cube that exactly has the dimensional coordinates " + f"{expected_dims_str}, got {cube.summary(shorten=True)}") + + @staticmethod + def _fill_facet_placeholders(string, dataset, description): """Fill facet placeholders.""" try: string = string.format(**dataset) @@ -1170,21 +1809,21 @@ def _get_multi_dataset_facets(datasets): multi_dataset_facets[key] = f'ambiguous_{key}' return multi_dataset_facets - @staticmethod - def _get_reference_dataset(datasets, short_name): + def _get_reference_dataset(self, datasets): """Extract reference dataset.""" + variable = datasets[0][self.cfg['group_variables_by']] ref_datasets = [d for d in datasets if d.get('reference_for_monitor_diags', False)] if len(ref_datasets) > 1: raise ValueError( f"Expected at most 1 reference dataset (with " f"'reference_for_monitor_diags: true' for variable " - f"'{short_name}', got {len(ref_datasets):d}") + f"'{variable}', got {len(ref_datasets):d}") if ref_datasets: return ref_datasets[0] return None - def create_timeseries_plot(self, datasets, short_name): + def create_timeseries_plot(self, datasets): """Create time series plot.""" plot_type = 'timeseries' if plot_type not in self.plots: @@ -1226,8 +1865,15 @@ def create_timeseries_plot(self, datasets, short_name): # Default plot appearance multi_dataset_facets = self._get_multi_dataset_facets(datasets) axes.set_title(multi_dataset_facets['long_name']) - axes.set_xlabel('Time') - axes.set_ylabel(f"{short_name} [{multi_dataset_facets['units']}]") + axes.set_xlabel('time') + # apply time formatting + if self.plots[plot_type]['time_format'] is not None: + axes.get_xaxis().set_major_formatter( + mdates.DateFormatter(self.plots[plot_type]['time_format'])) + axes.set_ylabel( + f"{multi_dataset_facets[self.cfg['group_variables_by']]} " + f"[{multi_dataset_facets['units']}]" + ) gridline_kwargs = self._get_gridline_kwargs(plot_type) if gridline_kwargs is not False: axes.grid(**gridline_kwargs) @@ -1267,7 +1913,7 @@ def create_timeseries_plot(self, datasets, short_name): provenance_logger.log(plot_path, provenance_record) provenance_logger.log(netcdf_path, provenance_record) - def create_annual_cycle_plot(self, datasets, short_name): + def create_annual_cycle_plot(self, datasets): """Create annual cycle plot.""" plot_type = 'annual_cycle' if plot_type not in self.plots: @@ -1298,7 +1944,10 @@ def create_annual_cycle_plot(self, datasets, short_name): multi_dataset_facets = self._get_multi_dataset_facets(datasets) axes.set_title(multi_dataset_facets['long_name']) axes.set_xlabel('Month') - axes.set_ylabel(f"{short_name} [{multi_dataset_facets['units']}]") + axes.set_ylabel( + f"{multi_dataset_facets[self.cfg['group_variables_by']]} " + f"[{multi_dataset_facets['units']}]" + ) axes.set_xticks(range(1, 13), [str(m) for m in range(1, 13)]) gridline_kwargs = self._get_gridline_kwargs(plot_type) if gridline_kwargs is not False: @@ -1339,7 +1988,7 @@ def create_annual_cycle_plot(self, datasets, short_name): provenance_logger.log(plot_path, provenance_record) provenance_logger.log(netcdf_path, provenance_record) - def create_map_plot(self, datasets, short_name): + def create_map_plot(self, datasets): """Create map plot.""" plot_type = 'map' if plot_type not in self.plots: @@ -1349,7 +1998,7 @@ def create_map_plot(self, datasets, short_name): raise ValueError(f"No input data to plot '{plot_type}' given") # Get reference dataset if possible - ref_dataset = self._get_reference_dataset(datasets, short_name) + ref_dataset = self._get_reference_dataset(datasets) if ref_dataset is None: logger.info("Plotting %s without reference dataset", plot_type) else: @@ -1415,7 +2064,7 @@ def create_map_plot(self, datasets, short_name): for netcdf_path in netcdf_paths: provenance_logger.log(netcdf_path, provenance_record) - def create_zonal_mean_profile_plot(self, datasets, short_name): + def create_zonal_mean_profile_plot(self, datasets): """Create zonal mean profile plot.""" plot_type = 'zonal_mean_profile' if plot_type not in self.plots: @@ -1425,7 +2074,7 @@ def create_zonal_mean_profile_plot(self, datasets, short_name): raise ValueError(f"No input data to plot '{plot_type}' given") # Get reference dataset if possible - ref_dataset = self._get_reference_dataset(datasets, short_name) + ref_dataset = self._get_reference_dataset(datasets) if ref_dataset is None: logger.info("Plotting %s without reference dataset", plot_type) else: @@ -1493,7 +2142,7 @@ def create_zonal_mean_profile_plot(self, datasets, short_name): for netcdf_path in netcdf_paths: provenance_logger.log(netcdf_path, provenance_record) - def create_1d_profile_plot(self, datasets, short_name): + def create_1d_profile_plot(self, datasets): """Create 1D profile plot.""" plot_type = '1d_profile' if plot_type not in self.plots: @@ -1525,7 +2174,10 @@ def create_1d_profile_plot(self, datasets, short_name): # Default plot appearance axes.set_title(multi_dataset_facets['long_name']) - axes.set_xlabel(f"{short_name} [{multi_dataset_facets['units']}]") + axes.set_xlabel( + f"{multi_dataset_facets[self.cfg['group_variables_by']]} " + f"[{multi_dataset_facets['units']}]" + ) z_coord = cube.coord(axis='Z') axes.set_ylabel(f'{z_coord.long_name} [{z_coord.units}]') @@ -1595,15 +2247,239 @@ def create_1d_profile_plot(self, datasets, short_name): provenance_logger.log(plot_path, provenance_record) provenance_logger.log(netcdf_path, provenance_record) + def create_variable_vs_lat_plot(self, datasets): + """Create Variable as a function of latitude.""" + plot_type = 'variable_vs_lat' + if plot_type not in self.plots: + return + if not datasets: + raise ValueError(f"No input data to plot '{plot_type}' given") + logger.info("Plotting %s", plot_type) + fig = plt.figure(**self.cfg['figure_kwargs']) + axes = fig.add_subplot() + + # Plot all datasets in one single figure + ancestors = [] + cubes = {} + for dataset in datasets: + ancestors.append(dataset['filename']) + cube = dataset['cube'] + cubes[self._get_label(dataset)] = cube + self._check_cube_dimensions(cube, plot_type) + + # Plot data + plot_kwargs = self._get_plot_kwargs(plot_type, dataset) + plot_kwargs['axes'] = axes + iris.plot.plot(cube, **plot_kwargs) + + # Default plot appearance + multi_dataset_facets = self._get_multi_dataset_facets(datasets) + axes.set_title(multi_dataset_facets['long_name']) + axes.set_xlabel('latitude [°N]') + axes.set_ylabel( + f"{multi_dataset_facets[self.cfg['group_variables_by']]} " + f"[{multi_dataset_facets['units']}]" + ) + gridline_kwargs = self._get_gridline_kwargs(plot_type) + if gridline_kwargs is not False: + axes.grid(**gridline_kwargs) + + # Legend + legend_kwargs = self.plots[plot_type]['legend_kwargs'] + if legend_kwargs is not False: + axes.legend(**legend_kwargs) + + # Customize plot appearance + self._process_pyplot_kwargs(plot_type, multi_dataset_facets) + + # Save plot + plot_path = self.get_plot_path(plot_type, multi_dataset_facets) + fig.savefig(plot_path, **self.cfg['savefig_kwargs']) + logger.info("Wrote %s", plot_path) + plt.close() + + # Save netCDF file + netcdf_path = get_diagnostic_filename(Path(plot_path).stem, self.cfg) + var_attrs = { + n: datasets[0][n] for n in ('short_name', 'long_name', 'units') + } + io.save_1d_data(cubes, netcdf_path, 'latitude', var_attrs) + + # Provenance tracking + caption = (f"{multi_dataset_facets['long_name']} vs. latitude for " + f"various datasets.") + provenance_record = { + 'ancestors': ancestors, + 'authors': ['sarauer_ellen'], + 'caption': caption, + 'plot_types': ['line'], + 'long_names': [var_attrs['long_name']], + } + with ProvenanceLogger(self.cfg) as provenance_logger: + provenance_logger.log(plot_path, provenance_record) + provenance_logger.log(netcdf_path, provenance_record) + + def create_hovmoeller_z_vs_time_plot(self, datasets): + """Create Hovmoeller Z vs. time plot.""" + plot_type = 'hovmoeller_z_vs_time' + if plot_type not in self.plots: + return + + if not datasets: + raise ValueError(f"No input data to plot '{plot_type}' given") + + # Get reference dataset if possible + ref_dataset = self._get_reference_dataset(datasets) + if ref_dataset is None: + logger.info("Plotting %s without reference dataset", plot_type) + else: + logger.info("Plotting %s with reference dataset '%s'", plot_type, + self._get_label(ref_dataset)) + + # Get plot function + plot_func = self._get_plot_func(plot_type) + + # Create a single plot for each dataset (incl. reference dataset if + # given) + for dataset in datasets: + if dataset == ref_dataset: + continue + ancestors = [dataset['filename']] + if ref_dataset is None: + (plot_path, + netcdf_paths) = (self._plot_hovmoeller_z_vs_time_without_ref( + plot_func, dataset)) + caption = ( + f"Hovmoeller Z vs. time plot of {dataset['long_name']} " + f"of dataset " + f"{dataset['dataset']} (project {dataset['project']}) " + f"from {dataset['start_year']} to {dataset['end_year']}.") + else: + (plot_path, + netcdf_paths) = (self._plot_hovmoeller_z_vs_time_with_ref( + plot_func, dataset, ref_dataset)) + caption = ( + f"Hovmoeller Z vs. time plot of {dataset['long_name']} " + f"of dataset " + f"{dataset['dataset']} (project {dataset['project']}) " + f"including bias relative to {ref_dataset['dataset']} " + f"(project {ref_dataset['project']}) from " + f"{dataset['start_year']} to {dataset['end_year']}.") + ancestors.append(ref_dataset['filename']) + + # If statistics are shown add a brief description to the caption + if self.plots[plot_type]['show_stats']: + caption += ( + " The number in the top left corner corresponds to the " + "spatiotemporal mean.") + + # Save plot + plt.savefig(plot_path, **self.cfg['savefig_kwargs']) + logger.info("Wrote %s", plot_path) + plt.close() + + # Save netCDFs + for (netcdf_path, cube) in netcdf_paths.items(): + io.iris_save(cube, netcdf_path) + + # Provenance tracking + provenance_record = { + 'ancestors': ancestors, + 'authors': ['kuehbacher_birgit', 'heuer_helge'], + 'caption': caption, + 'plot_types': ['vert'], + 'long_names': [dataset['long_name']], + } + with ProvenanceLogger(self.cfg) as provenance_logger: + provenance_logger.log(plot_path, provenance_record) + for netcdf_path in netcdf_paths: + provenance_logger.log(netcdf_path, provenance_record) + + def create_hovmoeller_time_vs_lat_or_lon_plot(self, datasets): + """Create the Hovmoeller plot with time vs latitude or longitude.""" + plot_type = 'hovmoeller_time_vs_lat_or_lon' + if plot_type not in self.plots: + return + + if not datasets: + raise ValueError(f"No input data to plot '{plot_type}' given") + + # Get reference dataset if possible + ref_dataset = self._get_reference_dataset(datasets) + if ref_dataset is None: + logger.info("Plotting %s without reference dataset", plot_type) + else: + logger.info("Plotting %s with reference dataset '%s'", plot_type, + self._get_label(ref_dataset)) + + # Get plot function + plot_func = self._get_plot_func(plot_type) + + # Create a single plot for each dataset (incl. reference dataset if + # given) + for dataset in datasets: + if dataset == ref_dataset: + continue + ancestors = [dataset['filename']] + if ref_dataset is None: + (plot_path, netcdf_paths) = ( + self._plot_hovmoeller_time_vs_lat_or_lon_without_ref( + plot_func, + dataset) + ) + caption = ( + f"Hovmoeller plot of {dataset['long_name']} of dataset " + f"{dataset['dataset']} (project {dataset['project']}) " + f"from {dataset['start_year']} to {dataset['end_year']}." + ) + else: + (plot_path, netcdf_paths) = ( + self._plot_hovmoeller_time_vs_lat_or_lon_with_ref( + plot_func, dataset, ref_dataset) + ) + caption = ( + f"Hovmoeller plot of {dataset['long_name']} of dataset " + f"{dataset['dataset']} (project {dataset['project']}) " + f"including bias relative to {ref_dataset['dataset']} " + f"(project {ref_dataset['project']}) from " + f"{dataset['start_year']} to {dataset['end_year']}." + ) + ancestors.append(ref_dataset['filename']) + + # Save plot + plt.savefig(plot_path, **self.cfg['savefig_kwargs']) + logger.info("Wrote %s", plot_path) + plt.close() + + # Save netCDFs + for (netcdf_path, cube) in netcdf_paths.items(): + io.iris_save(cube, netcdf_path) + + # Provenance tracking + provenance_record = { + 'ancestors': ancestors, + 'authors': ['schlund_manuel', 'kraft_jeremy', 'ruhe_lukas'], + 'caption': caption, + 'plot_types': ['zonal'], + 'long_names': [dataset['long_name']], + } + with ProvenanceLogger(self.cfg) as provenance_logger: + provenance_logger.log(plot_path, provenance_record) + for netcdf_path in netcdf_paths: + provenance_logger.log(netcdf_path, provenance_record) + def compute(self): """Plot preprocessed data.""" - for (short_name, datasets) in self.grouped_input_data.items(): - logger.info("Processing variable %s", short_name) - self.create_timeseries_plot(datasets, short_name) - self.create_annual_cycle_plot(datasets, short_name) - self.create_map_plot(datasets, short_name) - self.create_zonal_mean_profile_plot(datasets, short_name) - self.create_1d_profile_plot(datasets, short_name) + for (var_key, datasets) in self.grouped_input_data.items(): + logger.info("Processing variable %s", var_key) + self.create_timeseries_plot(datasets) + self.create_annual_cycle_plot(datasets) + self.create_map_plot(datasets) + self.create_zonal_mean_profile_plot(datasets) + self.create_1d_profile_plot(datasets) + self.create_variable_vs_lat_plot(datasets) + self.create_hovmoeller_z_vs_time_plot(datasets) + self.create_hovmoeller_time_vs_lat_or_lon_plot(datasets) def main(): diff --git a/esmvaltool/recipes/monitor/recipe_monitor_with_refs.yml b/esmvaltool/recipes/monitor/recipe_monitor_with_refs.yml index 0d1415979a..e75cc763da 100644 --- a/esmvaltool/recipes/monitor/recipe_monitor_with_refs.yml +++ b/esmvaltool/recipes/monitor/recipe_monitor_with_refs.yml @@ -7,6 +7,11 @@ documentation: (ongoing) model simulations. authors: - schlund_manuel + - heuer_helge + - kraft_jeremy + - kuehbacher_birgit + - ruhe_lukas + - sarauer_ellen - winterstein_franziska maintainer: - schlund_manuel @@ -14,8 +19,8 @@ documentation: datasets: # Note: plot_label currently only used by diagnostic plot_multiple_annual_cycles - - {project: CMIP6, dataset: EC-Earth3, exp: historical, ensemble: r1i1p1f1, grid: gr, plot_label: 'EC-Earth3 historical'} - - {project: CMIP6, dataset: CanESM5, exp: historical, ensemble: r1i1p1f1, grid: gn, plot_label: 'Reference (CanESM5 historical)', reference_for_monitor_diags: true} + - {project: CMIP6, dataset: MPI-ESM1-2-HR, exp: historical, ensemble: r1i1p1f1, grid: gn, plot_label: 'MPI-ESM1-2-HR historical'} + - {project: CMIP6, dataset: MPI-ESM1-2-LR, exp: historical, ensemble: r1i1p1f1, grid: gn, plot_label: 'Reference (MPI-ESM1-2-LR historical)', reference_for_monitor_diags: true} preprocessors: @@ -67,6 +72,36 @@ preprocessors: scheme: linear coordinate: air_pressure + var_vs_lat: + climate_statistics: + operator: mean + regrid: + target_grid: 2x2 + scheme: linear + zonal_statistics: + operator: mean + convert_units: + units: mm day-1 + + global_mean_extract_levels: + custom_order: true + extract_levels: + levels: {cmor_table: CMIP6, coordinate: alt16} + scheme: linear + coordinate: altitude + regrid: + target_grid: 2x2 + scheme: linear + area_statistics: + operator: mean + + zonal_mean_2d: + regrid: + target_grid: 2x2 + scheme: linear + zonal_statistics: + operator: mean + diagnostics: @@ -87,9 +122,9 @@ diagnostics: annual_mean_kwargs: linestyle: '--' plot_kwargs: - EC-Earth3: # = dataset since 'facet_used_for_labels' is 'dataset' by default + MPI-ESM1-2-HR: # = dataset since 'facet_used_for_labels' is 'dataset' by default color: C0 - CanESM5: + MPI-ESM1-2-LR: color: black plot_multiple_annual_cycles: @@ -108,9 +143,9 @@ diagnostics: legend_kwargs: loc: upper right plot_kwargs: - 'EC-Earth3 historical': # = plot_label since 'facet_used_for_labels: plot_label' + 'MPI-ESM1-2-HR historical': # = plot_label since 'facet_used_for_labels: plot_label' color: C0 - 'Reference (CanESM5 historical)': + 'Reference (MPI-ESM1-2-LR historical)': color: black pyplot_kwargs: title: Near-Surface Air Temperature on Northern Hemisphere @@ -150,6 +185,7 @@ diagnostics: plot_kwargs_bias: levels: [-10.0, -7.5, -5.0, -2.5, 0.0, 2.5, 5.0, 7.5, 10.0] + plot_1D_profiles_with_references: description: Plot 1D profiles including reference datasets. variables: @@ -164,7 +200,58 @@ diagnostics: plots: 1d_profile: plot_kwargs: - EC-Earth3: # = dataset since 'facet_used_for_labels' is 'dataset' by default + MPI-ESM1-2-HR: # = dataset since 'facet_used_for_labels' is 'dataset' by default color: C0 - CanESM5: + MPI-ESM1-2-LR: color: black + + plot_variable_vs_latitude: + description: Creates a single-panel variable plot over latitude. + variables: + pr: + preprocessor: var_vs_lat + mip: Amon + timerange: '20000101/20030101' + scripts: + plot: + <<: *plot_multi_dataset_default + script: monitor/multi_datasets.py + plots: + variable_vs_lat: + + plot_hovmoeller_z_vs_time: + description: Plot Hovmoeller Z vs. time including reference datasets. + variables: + ta: + preprocessor: global_mean_extract_levels + mip: Amon + timerange: '2000/2004' + scripts: + plot: + <<: *plot_multi_dataset_default + script: monitor/multi_datasets.py + plots: + hovmoeller_z_vs_time: + plot_func: contourf + common_cbar: true + time_format: '%Y' + log_y: false + pyplot_kwargs: + ylim: [0, 20000] + + plot_time_vs_lat_with_references: + description: Plot Hovmoeller time vs. latitude including reference datasets. + variables: + tas: + mip: Amon + preprocessor: zonal_mean_2d + timerange: '2000/2004' + scripts: + plot: + <<: *plot_multi_dataset_default + script: monitor/multi_datasets.py + plots: + hovmoeller_time_vs_lat_or_lon: + common_cbar: true + show_x_minor_ticks: false + time_format: '%Y'