diff --git a/.cruft.json b/.cruft.json index 834f38d..26045e0 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/collijk/python-package-cookiecutter", - "commit": "7e9285f84cc6b52165dbc97b9a0d4f059d0f6818", + "commit": "cd59edc69d51f9485bca69eb940e0706bc65e9ba", "checkout": null, "context": { "cookiecutter": { @@ -11,7 +11,8 @@ "project_slug": "climate-data", "package_name": "climate_data", "project_short_description": "Pipelines to extract, format, and downscale ERA5 and CMIP6 data.", - "_template": "https://github.com/collijk/python-package-cookiecutter" + "_template": "https://github.com/collijk/python-package-cookiecutter", + "_commit": "cd59edc69d51f9485bca69eb940e0706bc65e9ba" } }, "directory": null diff --git a/.github/alternative_workflows/build_docs.yml b/.github/alternative_workflows/build_docs.yml new file mode 100644 index 0000000..0a90580 --- /dev/null +++ b/.github/alternative_workflows/build_docs.yml @@ -0,0 +1,21 @@ +name: Build and Deploy Docs + +on: + workflow_dispatch: + pull_request: + branches: + - main + types: + - closed + +jobs: + build-and-deploy-docs: + if: ${{ github.event.pull_request.merged }} or ${{ github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_TOKEN }} + - uses: ./.github/actions/python-poetry-env + - name: Deploy docs + run: poetry run mkdocs gh-deploy --force diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 764b8e8..ffd771a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v5.0.0 hooks: - id: check-ast - id: check-added-large-files diff --git a/poetry.lock b/poetry.lock index 64d9874..3c791bf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "affine" @@ -570,73 +570,73 @@ test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist" [[package]] name = "coverage" -version = "7.6.9" +version = "7.6.10" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85d9636f72e8991a1706b2b55b06c27545448baf9f6dbf51c4004609aacd7dcb"}, - {file = "coverage-7.6.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:608a7fd78c67bee8936378299a6cb9f5149bb80238c7a566fc3e6717a4e68710"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96d636c77af18b5cb664ddf12dab9b15a0cfe9c0bde715da38698c8cea748bfa"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cded8a3cff93da9edc31446872d2997e327921d8eed86641efafd350e1df1"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7b15f589593110ae767ce997775d645b47e5cbbf54fd322f8ebea6277466cec"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:44349150f6811b44b25574839b39ae35291f6496eb795b7366fef3bd3cf112d3"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d891c136b5b310d0e702e186d70cd16d1119ea8927347045124cb286b29297e5"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db1dab894cc139f67822a92910466531de5ea6034ddfd2b11c0d4c6257168073"}, - {file = "coverage-7.6.9-cp310-cp310-win32.whl", hash = "sha256:41ff7b0da5af71a51b53f501a3bac65fb0ec311ebed1632e58fc6107f03b9198"}, - {file = "coverage-7.6.9-cp310-cp310-win_amd64.whl", hash = "sha256:35371f8438028fdccfaf3570b31d98e8d9eda8bb1d6ab9473f5a390969e98717"}, - {file = "coverage-7.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:932fc826442132dde42ee52cf66d941f581c685a6313feebed358411238f60f9"}, - {file = "coverage-7.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:085161be5f3b30fd9b3e7b9a8c301f935c8313dcf928a07b116324abea2c1c2c"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc660a77e1c2bf24ddbce969af9447a9474790160cfb23de6be4fa88e3951c7"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c69e42c892c018cd3c8d90da61d845f50a8243062b19d228189b0224150018a9"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0824a28ec542a0be22f60c6ac36d679e0e262e5353203bea81d44ee81fe9c6d4"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4401ae5fc52ad8d26d2a5d8a7428b0f0c72431683f8e63e42e70606374c311a1"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98caba4476a6c8d59ec1eb00c7dd862ba9beca34085642d46ed503cc2d440d4b"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee5defd1733fd6ec08b168bd4f5387d5b322f45ca9e0e6c817ea6c4cd36313e3"}, - {file = "coverage-7.6.9-cp311-cp311-win32.whl", hash = "sha256:f2d1ec60d6d256bdf298cb86b78dd715980828f50c46701abc3b0a2b3f8a0dc0"}, - {file = "coverage-7.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:0d59fd927b1f04de57a2ba0137166d31c1a6dd9e764ad4af552912d70428c92b"}, - {file = "coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8"}, - {file = "coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f"}, - {file = "coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692"}, - {file = "coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97"}, - {file = "coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664"}, - {file = "coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb"}, - {file = "coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba"}, - {file = "coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1"}, - {file = "coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419"}, - {file = "coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9"}, - {file = "coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b"}, - {file = "coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611"}, - {file = "coverage-7.6.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:adb697c0bd35100dc690de83154627fbab1f4f3c0386df266dded865fc50a902"}, - {file = "coverage-7.6.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:be57b6d56e49c2739cdf776839a92330e933dd5e5d929966fbbd380c77f060be"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1592791f8204ae9166de22ba7e6705fa4ebd02936c09436a1bb85aabca3e599"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e12ae8cc979cf83d258acb5e1f1cf2f3f83524d1564a49d20b8bec14b637f08"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5555cff66c4d3d6213a296b360f9e1a8e323e74e0426b6c10ed7f4d021e464"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9389a429e0e5142e69d5bf4a435dd688c14478a19bb901735cdf75e57b13845"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:592ac539812e9b46046620341498caf09ca21023c41c893e1eb9dbda00a70cbf"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a27801adef24cc30871da98a105f77995e13a25a505a0161911f6aafbd66e678"}, - {file = "coverage-7.6.9-cp39-cp39-win32.whl", hash = "sha256:8e3c3e38930cfb729cb8137d7f055e5a473ddaf1217966aa6238c88bd9fd50e6"}, - {file = "coverage-7.6.9-cp39-cp39-win_amd64.whl", hash = "sha256:e28bf44afa2b187cc9f41749138a64435bf340adfcacb5b2290c070ce99839d4"}, - {file = "coverage-7.6.9-pp39.pp310-none-any.whl", hash = "sha256:f3ca78518bc6bc92828cd11867b121891d75cae4ea9e908d72030609b996db1b"}, - {file = "coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, + {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, + {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, + {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, + {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, + {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, + {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, + {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, + {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, + {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, + {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, + {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, + {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, + {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, + {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, ] [package.dependencies] @@ -1310,13 +1310,13 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "griffe" -version = "1.5.1" +version = "1.5.4" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." optional = false python-versions = ">=3.9" files = [ - {file = "griffe-1.5.1-py3-none-any.whl", hash = "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860"}, - {file = "griffe-1.5.1.tar.gz", hash = "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b"}, + {file = "griffe-1.5.4-py3-none-any.whl", hash = "sha256:ed33af890586a5bebc842fcb919fc694b3dc1bc55b7d9e0228de41ce566b4a1d"}, + {file = "griffe-1.5.4.tar.gz", hash = "sha256:073e78ad3e10c8378c2f798bd4ef87b92d8411e9916e157fd366a17cc4fd4e52"}, ] [package.dependencies] @@ -2054,13 +2054,13 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "1.12.2" +version = "1.13.0" description = "A Python handler for mkdocstrings." optional = false python-versions = ">=3.9" files = [ - {file = "mkdocstrings_python-1.12.2-py3-none-any.whl", hash = "sha256:7f7d40d6db3cb1f5d19dbcd80e3efe4d0ba32b073272c0c0de9de2e604eda62a"}, - {file = "mkdocstrings_python-1.12.2.tar.gz", hash = "sha256:7a1760941c0b52a2cd87b960a9e21112ffe52e7df9d0b9583d04d47ed2e186f3"}, + {file = "mkdocstrings_python-1.13.0-py3-none-any.whl", hash = "sha256:b88bbb207bab4086434743849f8e796788b373bd32e7bfefbf8560ac45d88f97"}, + {file = "mkdocstrings_python-1.13.0.tar.gz", hash = "sha256:2dbd5757e8375b9720e81db16f52f1856bf59905428fd7ef88005d1370e2f64c"}, ] [package.dependencies] @@ -3484,13 +3484,13 @@ test = ["boto3 (>=1.2.4)", "fsspec", "hypothesis", "packaging", "pytest (>=2.8.2 [[package]] name = "rasterra" -version = "0.6.0" +version = "0.6.1" description = "A sleek, object-oriented interface designed for intuitive raster data manipulation in Python." optional = false python-versions = "<3.13,>=3.10" files = [ - {file = "rasterra-0.6.0-py3-none-any.whl", hash = "sha256:7b26d128ee880f2313d6d0e070df821f9275877a77675118be41679e4d81d2de"}, - {file = "rasterra-0.6.0.tar.gz", hash = "sha256:d2d229263cf5d06dc7030f42727359fe13ecd02522a47bc55b9299d1c23638d5"}, + {file = "rasterra-0.6.1-py3-none-any.whl", hash = "sha256:a03cd7243a56fc713b1c5cff41674deff85f8cc4e58219e9052c65460ee73d61"}, + {file = "rasterra-0.6.1.tar.gz", hash = "sha256:577da878077e2ac8281e4ea50c99dfc9935819e8782aadf2c753186192b9fd96"}, ] [package.dependencies] @@ -3661,13 +3661,13 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "rra-tools" -version = "1.0.12" +version = "1.0.13" description = "Common utilities for IHME Rapid Response team pipelines." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "rra_tools-1.0.12-py3-none-any.whl", hash = "sha256:d6df1712d06da04d373659cdcb704f90bc06da6c4d1920cd35bab6b66bed059c"}, - {file = "rra_tools-1.0.12.tar.gz", hash = "sha256:50410665b944d1f4315d1a4133c1c3ef20ea5ab18f6550b8123213138f50e12f"}, + {file = "rra_tools-1.0.13-py3-none-any.whl", hash = "sha256:be4302eb788764159c7ea4b961fb67666fe3160e157a8a20cabbde115508773e"}, + {file = "rra_tools-1.0.13.tar.gz", hash = "sha256:b5532e0531cba44e0a15aa47b1afa69652d380cc8ae4511ca68e1a7d0596b835"}, ] [package.dependencies] @@ -4353,4 +4353,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.10, <3.13" -content-hash = "2a1eeaa827c3a9f4996c629b270ffdc6e466c6f9034287edad8f9e06ea99d37d" +content-hash = "ba5d7cdb41315f8cacf4e6e6fa9757b3919e0058271d0a26a57d004ee3e3caf7" diff --git a/pyproject.toml b/pyproject.toml index 61cae70..2bae62b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,10 +52,10 @@ pydantic = "^2.10.4" [tool.poetry.group.dev.dependencies] -mkdocstrings = {version = ">=0.23", extras = ["python"]} +mkdocstrings = {version = "*", extras = ["python"]} mkdocs-material = "*" mkdocs-table-reader-plugin = "*" -mkdocs-gen-files = "^0.5.0" +mkdocs-gen-files = "*" mypy = "*" pre-commit = "*" pymdown-extensions = "*" @@ -63,13 +63,13 @@ pytest = "*" pytest-github-actions-annotate-failures = "*" pytest-cov = "*" python-kacl = "*" -ruff = ">=0.2.0" -pandas-stubs = "^2.2.3.241009" -types-pyyaml = "^6.0.12.20240311" -types-requests = "^2.31.0.20240406" -types-tqdm = "^4.66.0.20240417" -mkdocs-literate-nav = "^0.6.1" -mkdocs-section-index = "^0.3.9" +ruff = "*" +pandas-stubs = "*" +types-pyyaml = "*" +types-requests = "*" +types-tqdm = "*" +mkdocs-literate-nav = "*" +mkdocs-section-index = "*" [build-system] @@ -111,6 +111,7 @@ ignore = [ "FBT002", # Boolean positional args are super common in clis "PD901", # Generic df names are fine "S311", # Not using random numbers for crypto purposes + "S101", # Use of `assert` detected ] [tool.ruff.lint.per-file-ignores] diff --git a/scripts/gen_data_pages.py b/scripts/gen_data_pages.py index 7cf3d28..0cbf24b 100644 --- a/scripts/gen_data_pages.py +++ b/scripts/gen_data_pages.py @@ -186,7 +186,7 @@ - Daily Storage Root: `{cdata.daily_results}` - Naming Convention: `{{SCENARIO}}/{{DAILY_VARIABLE}}/{{YEAR}}.nc` (historical data only) - - `{{SCENARIO}}`: Generally, only historical data is available at the daily level, so this will be `historical`. + - `{{SCENARIO}}`: Generally, only historical data is available at the daily level, so this will be `historical`. - `{{DAILY_VARIABLE}}`: The name of the variable being stored. - `{{YEAR}}`: The year of the data being stored. - Annual Storage Root: `{cdata.results}` diff --git a/src/climate_data/cli_options.py b/src/climate_data/cli_options.py index 620231a..5a5dc11 100644 --- a/src/climate_data/cli_options.py +++ b/src/climate_data/cli_options.py @@ -25,7 +25,6 @@ from climate_data import constants as cdc - _T = TypeVar("_T") _P = ParamSpec("_P") @@ -109,6 +108,7 @@ def with_cmip6_experiment( help="CMIP6 experiment to extract.", ) + def with_cmip6_variable( *, allow_all: bool = False, @@ -147,6 +147,7 @@ def with_draw( help="Draw to process.", ) + def with_scenario( *, allow_all: bool = False, @@ -168,24 +169,24 @@ def with_overwrite() -> ClickOption[_P, _T]: __all__ = [ - "with_year", - "with_month", - "with_era5_variable", - "with_era5_dataset", - "with_cmip6_source", + "RUN_ALL", + "ClickOption", + "with_choice", "with_cmip6_experiment", - "with_target_variable", - "with_draw", - "with_scenario", - "with_overwrite", - "with_output_directory", - "with_queue", - "with_verbose", + "with_cmip6_source", "with_debugger", + "with_draw", + "with_era5_dataset", + "with_era5_variable", "with_input_directory", + "with_month", "with_num_cores", + "with_output_directory", + "with_overwrite", "with_progress_bar", - "RUN_ALL", - "ClickOption", - "with_choice", + "with_queue", + "with_scenario", + "with_target_variable", + "with_verbose", + "with_year", ] diff --git a/src/climate_data/constants.py b/src/climate_data/constants.py index b1a0260..820ae6a 100644 --- a/src/climate_data/constants.py +++ b/src/climate_data/constants.py @@ -1,10 +1,9 @@ from pathlib import Path -from typing import NamedTuple, Literal +from typing import Literal, NamedTuple -from pydantic import BaseModel import numpy as np import xarray as xr - +from pydantic import BaseModel ############## # File roots # @@ -40,13 +39,16 @@ # Extraction Constants + class _ERA5Datasets(NamedTuple): # Use named tuple so that we can access the dataset names as attributes reanalysis_era5_land: str = "reanalysis-era5-land" reanalysis_era5_single_levels: str = "reanalysis-era5-single-levels" + ERA5_DATASETS = _ERA5Datasets() + class _ERA5Variables(NamedTuple): u_component_of_wind: str = "10m_u_component_of_wind" v_component_of_wind: str = "10m_v_component_of_wind" @@ -56,6 +58,7 @@ class _ERA5Variables(NamedTuple): total_precipitation: str = "total_precipitation" sea_surface_temperature: str = "sea_surface_temperature" + ERA5_VARIABLES = _ERA5Variables() CMIP6_SOURCES = [ @@ -83,11 +86,13 @@ class _ERA5Variables(NamedTuple): "NorESM2-MM", ] + class _CMIP6Experiments(NamedTuple): ssp126: str = "ssp126" ssp245: str = "ssp245" ssp585: str = "ssp585" + CMIP6_EXPERIMENTS = _CMIP6Experiments() @@ -161,7 +166,7 @@ def names(self) -> list[str]: return [v.name for v in self] def get(self, name: str) -> CMIP6Variable: - return getattr(self, name) + return getattr(self, name) # type: ignore[no-any-return] def to_dict(self) -> dict[str, CMIP6Variable]: return {v.name: v for v in self} @@ -181,10 +186,12 @@ def to_dict(self) -> dict[str, CMIP6Variable]: DRAWS = [str(d) for d in range(100)] + class _Scenarios(NamedTuple): historical: str = "historical" ssp126: str = "ssp126" ssp245: str = "ssp245" ssp585: str = "ssp585" + SCENARIOS = _Scenarios() diff --git a/src/climate_data/downscale/prepare_predictors.py b/src/climate_data/downscale/prepare_predictors.py index 0e83d18..374e0aa 100644 --- a/src/climate_data/downscale/prepare_predictors.py +++ b/src/climate_data/downscale/prepare_predictors.py @@ -1,6 +1,6 @@ -from typing import ParamSpec, TypeVar from collections.abc import Sequence from pathlib import Path +from typing import ParamSpec, TypeVar import click import numpy as np @@ -9,12 +9,13 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData from climate_data.utils import make_raster_template - _T = TypeVar("_T") _P = ParamSpec("_P") @@ -98,7 +99,9 @@ def load_lcz_data( def prepare_predictors_main( - lat_start: str | int, lon_start: str | int, output_dir: str | Path, + lat_start: str | int, + lon_start: str | int, + output_dir: str | Path, ) -> None: lat_start = int(lat_start) lon_start = int(lon_start) @@ -162,8 +165,8 @@ def prepare_predictors(output_dir: str, queue: str) -> None: runner="cdtask", task_name="downscale prepare_predictors", node_args={ - "lat-start": clio.LATITUDES, - "lon-start": clio.LONGITUDES, + "lat-start": LATITUDES, + "lon-start": LONGITUDES, }, task_args={ "output-dir": output_dir, diff --git a/src/climate_data/downscale/prepare_training_data.py b/src/climate_data/downscale/prepare_training_data.py index d4ac5e9..df98f19 100644 --- a/src/climate_data/downscale/prepare_training_data.py +++ b/src/climate_data/downscale/prepare_training_data.py @@ -9,6 +9,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData diff --git a/src/climate_data/extract/cmip6.py b/src/climate_data/extract/cmip6.py index 1444791..a8c9491 100644 --- a/src/climate_data/extract/cmip6.py +++ b/src/climate_data/extract/cmip6.py @@ -12,6 +12,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -40,7 +42,7 @@ def extract_cmip6_main( cdata = ClimateData(output_dir) meta = cdata.load_cmip6_metadata() - *_, offset, scale, table_id = cdc.CMIP6_VARIABLES.get(cmip6_variable) + *_, offset, scale, table_id = cdc.CMIP6_VARIABLES.get(cmip6_variable) mask = ( (meta.source_id == cmip6_source) @@ -106,10 +108,10 @@ def extract_cmip6_task( overwrite: bool, ) -> None: extract_cmip6_main( - cmip6_variable, - cmip6_experiment, + cmip6_variable, + cmip6_experiment, cmip6_source, - output_dir, + output_dir, overwrite, ) @@ -138,14 +140,16 @@ def extract_cmip6( capture model inclusion criteria as it does not account for the year range avaialable in the data. This determiniation is made when we proccess the data in later steps. """ - sources = ( - cdc.CMIP6_SOURCES if cmip6_source == clio.RUN_ALL else [cmip6_source] - ) + sources = cdc.CMIP6_SOURCES if cmip6_source == clio.RUN_ALL else [cmip6_source] experiments = ( - cdc.CMIP6_EXPERIMENTS if cmip6_experiment == clio.RUN_ALL else [cmip6_experiment] + cdc.CMIP6_EXPERIMENTS + if cmip6_experiment == clio.RUN_ALL + else [cmip6_experiment] ) variables = ( - cdc.CMIP6_VARIABLES.names() if cmip6_variable == clio.RUN_ALL else [cmip6_variable] + cdc.CMIP6_VARIABLES.names() + if cmip6_variable == clio.RUN_ALL + else [cmip6_variable] ) overwrite_arg = {"overwrite": None} if overwrite else {} @@ -154,8 +158,8 @@ def extract_cmip6( runner="cdtask", task_name="extract cmip6", node_args={ - "cmip6-source": sources, - "cmip6-experiment": experiments, + "cmip6-source": list(sources), + "cmip6-experiment": list(experiments), "cmip6-variable": variables, }, task_args={ diff --git a/src/climate_data/extract/elevation.py b/src/climate_data/extract/elevation.py index 8e1cae2..38f116e 100644 --- a/src/climate_data/extract/elevation.py +++ b/src/climate_data/extract/elevation.py @@ -7,6 +7,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -91,7 +93,7 @@ def extract_elevation_task( msg = "Downloaded using aws cli, this implementation is not valid" raise NotImplementedError(msg) - extract_elevation_main(output_dir, model_name, lat_start, lon_start) + extract_elevation_main(model_name, lat_start, lon_start, output_dir) @click.command() # type: ignore[arg-type] diff --git a/src/climate_data/extract/era5.py b/src/climate_data/extract/era5.py index 352f215..343afa9 100644 --- a/src/climate_data/extract/era5.py +++ b/src/climate_data/extract/era5.py @@ -5,6 +5,7 @@ import itertools import zipfile +from collections.abc import Sequence from pathlib import Path import cdsapi @@ -16,6 +17,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -49,9 +52,7 @@ def download_era5_main( ) -> None: cdata = ClimateData(output_dir) - final_out_path = cdata.extracted_era5_path( - era5_dataset, era5_variable, year, month - ) + final_out_path = cdata.extracted_era5_path(era5_dataset, era5_variable, year, month) download_path = final_out_path.with_suffix(".zip") data_format, download_format = "netcdf", "zip" @@ -113,9 +114,7 @@ def unzip_and_compress_era5( ) -> None: cdata = ClimateData(output_dir) - final_out_path = cdata.extracted_era5_path( - era5_dataset, era5_variable, year, month - ) + final_out_path = cdata.extracted_era5_path(era5_dataset, era5_variable, year, month) zip_path = final_out_path.with_suffix(".zip") check_zipfile(zip_path) @@ -184,7 +183,6 @@ def download_era5_task( @click.command() # type: ignore[arg-type] - @clio.with_era5_dataset() @clio.with_era5_variable() @clio.with_month() @@ -208,7 +206,7 @@ def unzip_and_compress_era5_task( def build_task_lists( cdata: ClimateData, - *spec_variables: list[str], + *spec_variables: Sequence[str], ) -> tuple[list[tuple[str, ...]], ...]: to_download = [] to_compress = [] @@ -280,12 +278,8 @@ def extract_era5( users = list(credentials["keys"]) jobs_per_user = 20 - datasets = ( - cdc.ERA5_DATASETS if era5_dataset == clio.RUN_ALL else [era5_dataset] - ) - variables = ( - cdc.ERA5_VARIABLES if era5_variable == clio.RUN_ALL else [era5_variable] - ) + datasets = cdc.ERA5_DATASETS if era5_dataset == clio.RUN_ALL else [era5_dataset] + variables = cdc.ERA5_VARIABLES if era5_variable == clio.RUN_ALL else [era5_variable] years = cdc.FULL_HISTORY_YEARS if year == clio.RUN_ALL else [year] months = cdc.MONTHS if month == clio.RUN_ALL else [month] diff --git a/src/climate_data/extract/ncei_climate_stations.py b/src/climate_data/extract/ncei_climate_stations.py index 2b1de06..11b733a 100644 --- a/src/climate_data/extract/ncei_climate_stations.py +++ b/src/climate_data/extract/ncei_climate_stations.py @@ -8,6 +8,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -23,7 +25,7 @@ def extract_ncei_climate_stations_main(year: int | str, output_dir: str | Path) gz_path = cdata.ncei_climate_stations / f"{year}.tar.gz" if gz_path.exists(): gz_path.unlink() - year_dir = cdata.ncei_climate_stations / year + year_dir = cdata.ncei_climate_stations / str(year) mkdir(year_dir, exist_ok=True) url = URL_TEMPLATE.format(year=year) diff --git a/src/climate_data/extract/rub_local_climate_zones.py b/src/climate_data/extract/rub_local_climate_zones.py index 7b0128d..8048408 100644 --- a/src/climate_data/extract/rub_local_climate_zones.py +++ b/src/climate_data/extract/rub_local_climate_zones.py @@ -5,6 +5,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData diff --git a/src/climate_data/generate/historical_daily.py b/src/climate_data/generate/historical_daily.py index d572d3f..e8ca42f 100644 --- a/src/climate_data/generate/historical_daily.py +++ b/src/climate_data/generate/historical_daily.py @@ -9,6 +9,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -52,7 +54,7 @@ ), "wind_speed": utils.Transform( source_variables=[ - cdc.ERA5_VARIABLES.u_component_of_wind, + cdc.ERA5_VARIABLES.u_component_of_wind, cdc.ERA5_VARIABLES.v_component_of_wind, ], transform_funcs=[utils.vector_magnitude, utils.daily_mean], @@ -102,9 +104,7 @@ def load_variable( # There are some slight numerical differences in the lat/long for some of # the land datasets. They are gridded consistently, so just tweak the # coordinates so things align. - ds = ds.assign_coords( - latitude=cdc.TARGET_LAT[::-1], longitude=cdc.TARGET_LON - ) + ds = ds.assign_coords(latitude=cdc.TARGET_LAT[::-1], longitude=cdc.TARGET_LON) else: ds = load_and_shift_longitude(path) conversion = CONVERT_MAP[variable] @@ -125,11 +125,19 @@ def generate_historical_daily_main( month_str = f"{month:02d}" print(f"loading single-levels for {month_str}") single_level = [ - load_variable(cdata, sv, year, month_str, cdc.ERA5_DATASETS.reanalysis_era5_single_levels) + load_variable( + cdata, + sv, + year, + month_str, + cdc.ERA5_DATASETS.reanalysis_era5_single_levels, + ) for sv in transform.source_variables ] print("collapsing") - ds = transform(*single_level, key=cdc.ERA5_DATASETS.reanalysis_era5_single_levels).compute() + ds = transform( + *single_level, key=cdc.ERA5_DATASETS.reanalysis_era5_single_levels + ).compute() # collapsing often screws the date dtype, so fix it ds = ds.assign(date=pd.to_datetime(ds.date)) @@ -142,12 +150,16 @@ def generate_historical_daily_main( else: print(f"loading land for {month_str}") land = [ - load_variable(cdata, sv, year, month_str, cdc.ERA5_DATASETS.reanalysis_era5_land) + load_variable( + cdata, sv, year, month_str, cdc.ERA5_DATASETS.reanalysis_era5_land + ) for sv in transform.source_variables ] print("collapsing") with dask.config.set(**{"array.slicing.split_large_chunks": False}): # type: ignore[arg-type] - ds_land = transform(*land, key=cdc.ERA5_DATASETS.reanalysis_era5_land).compute() + ds_land = transform( + *land, key=cdc.ERA5_DATASETS.reanalysis_era5_land + ).compute() ds_land = ds_land.assign(date=pd.to_datetime(ds_land.date)) print("combining") @@ -170,7 +182,7 @@ def generate_historical_daily_main( assert set(ds_year.coords) == {"date", "latitude", "longitude"} assert set(ds_year.data_vars) == {"value"} assert ds_year["value"].dtype == "float32" - assert ds_year["value"].notnull().all().item() + assert ds_year["value"].notna().all().item() cdata.save_daily_results( ds_year, @@ -186,7 +198,7 @@ def generate_historical_daily_main( @clio.with_target_variable(list(TRANSFORM_MAP)) @clio.with_year(cdc.FULL_HISTORY_YEARS) @clio.with_output_directory(cdc.MODEL_ROOT) -def generate_historical_daily_task( +def generate_historical_daily_task( target_variable: str, year: str, output_dir: str, diff --git a/src/climate_data/generate/historical_reference.py b/src/climate_data/generate/historical_reference.py index 2d72346..1ca428b 100644 --- a/src/climate_data/generate/historical_reference.py +++ b/src/climate_data/generate/historical_reference.py @@ -4,6 +4,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -19,7 +21,7 @@ def generate_historical_reference_main( cdata = ClimateData(output_dir) paths = [ cdata.daily_results_path("historical", target_variable, year) - for year in clio.VALID_REFERENCE_YEARS + for year in cdc.REFERENCE_YEARS ] print(f"Building reference data from: {len(paths)} files.") @@ -58,7 +60,6 @@ def generate_historical_reference_main( @click.command() # type: ignore[arg-type] @clio.with_target_variable(list(TRANSFORM_MAP)) @clio.with_output_directory(cdc.MODEL_ROOT) - def generate_historical_reference_task( target_variable: str, output_dir: str, diff --git a/src/climate_data/generate/scenario_annual.py b/src/climate_data/generate/scenario_annual.py index 4b28e08..3958723 100644 --- a/src/climate_data/generate/scenario_annual.py +++ b/src/climate_data/generate/scenario_annual.py @@ -8,6 +8,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -132,12 +134,10 @@ def generate_scenario_annual_main( if scenario == "historical": # Symlink all the other draws to the same file source = cdata.annual_results_path(scenario, target_variable, year, "0") - for d in clio.VALID_DRAWS: + for d in cdc.DRAWS: if d == "0": continue - destination = cdata.annual_results_path( - scenario, target_variable, year, d - ) + destination = cdata.annual_results_path(scenario, target_variable, year, d) if destination.exists(): destination.unlink() destination.symlink_to(source) @@ -161,8 +161,7 @@ def generate_scenario_annual_task( raise ValueError(msg) if year in cdc.FORECAST_YEARS and scenario == "historical": msg = ( - f"Forecast years must use a future experiment: " - f"{cdc.CMIP6_EXPERIMENTS}." + f"Forecast years must use a future experiment: " f"{cdc.CMIP6_EXPERIMENTS}." ) raise ValueError(msg) @@ -170,9 +169,7 @@ def generate_scenario_annual_task( msg = "Historical years must use draw 0." raise ValueError(msg) - generate_scenario_annual_main( - output_dir, target_variable, scenario, year, draw - ) + generate_scenario_annual_main(output_dir, target_variable, scenario, year, draw) def build_arg_list( @@ -189,9 +186,7 @@ def build_arg_list( if target_variable == clio.RUN_ALL else [target_variable] ) - scenarios = ( - cdc.SCENARIOS if scenario == clio.RUN_ALL else [scenario] - ) + scenarios = cdc.SCENARIOS if scenario == clio.RUN_ALL else [scenario] draws = cdc.DRAWS if draw == clio.RUN_ALL else [draw] to_run, complete = [], [] diff --git a/src/climate_data/generate/scenario_daily.py b/src/climate_data/generate/scenario_daily.py index 61aea59..77fbcb9 100644 --- a/src/climate_data/generate/scenario_daily.py +++ b/src/climate_data/generate/scenario_daily.py @@ -11,6 +11,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -189,9 +191,7 @@ def generate_scenario_daily_main( transform, anomaly_type = TRANSFORM_MAP[target_variable] - source_paths = get_source_paths( - cdata, transform.source_variables, cmip6_experiment - ) + source_paths = get_source_paths(cdata, transform.source_variables, cmip6_experiment) print("loading historical reference") historical_reference = cdata.load_daily_results( diff --git a/src/climate_data/generate/scenario_inclusion.py b/src/climate_data/generate/scenario_inclusion.py index 7296cf9..3351df4 100644 --- a/src/climate_data/generate/scenario_inclusion.py +++ b/src/climate_data/generate/scenario_inclusion.py @@ -9,6 +9,8 @@ from climate_data import ( cli_options as clio, +) +from climate_data import ( constants as cdc, ) from climate_data.data import ClimateData @@ -63,9 +65,7 @@ def generate_scenario_inclusion_main( .reset_index() ) - inclusion_df["include"] = inclusion_df.valid_scenarios == len( - clio.VALID_CMIP6_EXPERIMENTS - ) + inclusion_df["include"] = inclusion_df.valid_scenarios == len(cdc.CMIP6_EXPERIMENTS) inclusion_df = ( inclusion_df.loc[inclusion_df.include] .set_index(["source", "variant", "variable"]) diff --git a/src/climate_data/generate/utils.py b/src/climate_data/generate/utils.py index 3a25003..da4ad41 100644 --- a/src/climate_data/generate/utils.py +++ b/src/climate_data/generate/utils.py @@ -258,9 +258,8 @@ def interpolate_to_target_latlon( xr.Dataset Interpolated dataset """ - valid_lat_lon = ( - (target_lat is not None and target_lon is not None) - or (target_lat is None and target_lon is None) + valid_lat_lon = (target_lat is not None and target_lon is not None) or ( + target_lat is None and target_lon is None ) if not valid_lat_lon: msg = "Both target_lat and target_lon must be provided or neither" @@ -268,6 +267,7 @@ def interpolate_to_target_latlon( if target_lon is None: # Avoid cyclic imports from climate_data.constants import TARGET_LON, TARGET_LAT # noqa: I001 + target_lon = TARGET_LON target_lat = TARGET_LAT @@ -299,13 +299,17 @@ def __init__( def __call__(self, *datasets: xr.Dataset, key: str | None = None) -> xr.Dataset: if len(datasets) > 1: # Enforce consistency in the spatial dimensions of the input datasets - datasets = list(datasets) - target_lat = datasets[0].latitude - target_lon = datasets[0].longitude - for i in range(1, len(datasets)): - datasets[i] = interpolate_to_target_latlon( - datasets[i], method="linear", target_lon=target_lon, target_lat=target_lat + datasets_list = list(datasets) + target_lat = datasets_list[0].latitude + target_lon = datasets_list[0].longitude + for i in range(1, len(datasets_list)): + datasets_list[i] = interpolate_to_target_latlon( + datasets_list[i], + method="linear", + target_lon=target_lon, + target_lat=target_lat, ) + datasets = tuple(datasets_list) if isinstance(self.transform_funcs, dict): if key is None: