From 5987636d9c9df9e696549d1a0bcb53cc5aa8dd19 Mon Sep 17 00:00:00 2001 From: Julieanna Bacon Date: Tue, 12 Mar 2024 12:28:18 -0400 Subject: [PATCH 1/3] netcdf preprocess: Parallelized workflow to crop original IMS netcdf files to centered window at variable window size with luigi --- config/preprocess_netcdf.toml | 4 + icedyno/preprocess/crop.py | 80 +++++++++ pixi.lock | 307 ++++++++++++++++++++++++++++------ pixi.toml | 2 + 4 files changed, 344 insertions(+), 49 deletions(-) create mode 100644 config/preprocess_netcdf.toml create mode 100644 icedyno/preprocess/crop.py diff --git a/config/preprocess_netcdf.toml b/config/preprocess_netcdf.toml new file mode 100644 index 0000000..58216ce --- /dev/null +++ b/config/preprocess_netcdf.toml @@ -0,0 +1,4 @@ +[CropFiles] +input_dir = "ims_1km" +output_dir = "ims_netcdf_1km_cropped_4_000_000km_window" +window_size = 4000 diff --git a/icedyno/preprocess/crop.py b/icedyno/preprocess/crop.py new file mode 100644 index 0000000..0a5ea5f --- /dev/null +++ b/icedyno/preprocess/crop.py @@ -0,0 +1,80 @@ +""" +To run this as a Luigi DAG locally: +``pixi run python icedyno/preprocess/crop.py`` + +You may have to enable toml support with luigi by setting an variable in your terminal, like ``export LUIGI_CONFIG_PARSER=toml`` +""" +import glob +import os +import pathlib + +import luigi +import xarray as xr + + +class CropFiles(luigi.Task): + """ + Crop IMS and MASIE NetCDF files from the center of their grids (where x, y == 1/2*sie.shape) based on input window_size. + + """ + + input_dir = luigi.Parameter() + output_dir = luigi.Parameter() + + window_size = luigi.IntParameter(default=4000) + year = luigi.IntParameter() + + def output(self) -> luigi.LocalTarget: + return luigi.LocalTarget( + os.path.join("data", self.output_dir, f"_SUCCESS_{self.year}") + ) + + def run(self) -> None: + year_output_dir = os.path.join("data", self.output_dir, str(self.year)) + if not os.path.exists(year_output_dir): + os.makedirs(year_output_dir) + + input_cdf_files = glob.glob( + os.path.join("data", self.input_dir, str(self.year), "*.nc") + ) + + for cdf_filepath in input_cdf_files: + output_filename = ( + os.path.join(year_output_dir, pathlib.Path(cdf_filepath).stem) + + f"_grid{self.window_size}.nc" + ) + if os.path.exists(output_filename): + print(cdf_filepath, "already on disk, skipping...") + + # Open the original NetCDF file + ds = xr.open_dataset(cdf_filepath, engine="h5netcdf") + + x_coord = ds["x"].shape[0] // 2 + y_coord = ds["y"].shape[0] // 2 + window = self.window_size * 1000 + + cropped_ds = ds.sel( + x=slice(x_coord - window, x_coord + window), + y=slice(y_coord - window, y_coord + window), + ) + + # Write the cropped data to a new NetCDF file + cropped_ds.to_netcdf(output_filename, engine="h5netcdf") + + +if __name__ == "__main__": + os.environ["LUIGI_CONFIG_PARSER"] = "toml" + + config_path = os.path.join("config", "preprocess_netcdf.toml") + + config = luigi.configuration.get_config(parser="toml") + config.read(config_path) + + luigi.configuration.add_config_path(config_path) + + ## Change acording to your number of cores + n_workers = 10 + years = range(2014, 2025) + + tasks = [CropFiles(year=year) for year in years] + luigi.build(tasks, workers=n_workers, local_scheduler=True) diff --git a/pixi.lock b/pixi.lock index ec709b6..a22ff3f 100644 --- a/pixi.lock +++ b/pixi.lock @@ -40,6 +40,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.2.0-py312h8572e83_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.1-py312h30efb56_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/docutils-0.20.1-py312h7900ff3_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.1-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py312h66d9856_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-10.2.1-h00ab1b0_0.conda @@ -64,7 +65,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.17-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py312h7900ff3_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.1-py312h7900ff3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.2-py312h7900ff3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-h2f55d51_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py312h8572e83_1.conda @@ -140,6 +141,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.5-h232c23b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/luigi-3.5.0-py312h7900ff3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.5-py312h98912ed_0.conda @@ -259,6 +261,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/h5netcdf-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -280,13 +283,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.21.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.13.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.25.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lockfile-0.12.2-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2 @@ -319,7 +323,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.14.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 @@ -329,6 +333,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-daemon-3.0.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda @@ -413,6 +418,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/h5netcdf-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -434,13 +440,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.21.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.13.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.25.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lockfile-0.12.2-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2 @@ -472,7 +479,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.14.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 @@ -482,6 +489,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-daemon-3.0.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda @@ -504,6 +512,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.0-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.3.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.2.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.8.19.20240311-pyhd8ed1ab_0.conda @@ -552,6 +561,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.3-py312h3f2338b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.2.0-py312hbf0bb39_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.1-py312hede676d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/docutils-0.20.1-py312hb401068_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/expat-2.6.1-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fiona-1.9.6-py312hc18349f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-10.2.1-h7728843_0.conda @@ -570,7 +580,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.17-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-2.4-py312hb401068_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.1-py312hb401068_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.2-py312hb401068_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-h5f07ac3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.5-py312h49ebfd2_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda @@ -624,6 +634,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.10.1-hc158999_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-17.0.6-hb6ac08f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/luigi-3.5.0-py312hb401068_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.9.4-hf0c8a7f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lzo-2.10-haf1e3a3_1000.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-2.1.5-py312h41838bb_0.conda @@ -722,6 +733,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/h5netcdf-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -743,13 +755,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.21.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.13.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.25.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lockfile-0.12.2-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2 @@ -781,7 +794,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.14.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 @@ -791,6 +804,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-daemon-3.0.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda @@ -813,6 +827,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.0-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.3.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.2.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.8.19.20240311-pyhd8ed1ab_0.conda @@ -861,6 +876,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.3-py312hf635c46_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.2.0-py312h76e736e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.1-py312h20a0b95_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/docutils-0.20.1-py312h81bd7bf_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.6.1-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.9.6-py312hd158ed5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-10.2.1-h2ffa867_0.conda @@ -879,7 +895,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.17-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-2.4-py312h81bd7bf_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.1-py312h81bd7bf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.2-py312h81bd7bf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h210d843_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.5-py312h389731b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda @@ -933,6 +949,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.10.1-ha0bc3c6_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-17.0.6-hcd81f8e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/luigi-3.5.0-py312h81bd7bf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.9.4-hb7217d7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h642e427_1000.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-2.1.5-py312he37b823_0.conda @@ -1030,6 +1047,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/h5netcdf-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -1051,7 +1069,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.21.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.13.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.2-pyhd8ed1ab_0.conda @@ -1089,7 +1107,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.14.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2 @@ -1191,7 +1209,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.0.0-h57928b3_49841.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-2.4-py312h2e8e312_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.1-py312h2e8e312_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.2-py312h2e8e312_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-hd248416_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.5-py312h0d7def4_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.2-heb0366b_0.conda @@ -1242,6 +1260,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.5-hc3477c8_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzip-1.10.1-h1d365fa_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/luigi-3.5.0-py312h2e8e312_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.9.4-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-he774522_1000.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/m2w64-gcc-libgfortran-5.3.0-6.tar.bz2 @@ -3951,6 +3970,52 @@ packages: license_family: APACHE size: 274915 timestamp: 1702383349284 +- kind: conda + name: docutils + version: 0.20.1 + build: py312h7900ff3_3 + build_number: 3 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/docutils-0.20.1-py312h7900ff3_3.conda + sha256: b9fb75d806afc53d9d7b98edb0c45ac38a3cc983916b8dac4ad7ddac5c18a024 + md5: 1b90835ae26b9b8250b302649359a989 + depends: + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 + size: 898253 + timestamp: 1701882735141 +- kind: conda + name: docutils + version: 0.20.1 + build: py312h81bd7bf_3 + build_number: 3 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/docutils-0.20.1-py312h81bd7bf_3.conda + sha256: e1ad41c6401ab2ada143d6e1dbbe6ae8afbe3e651211bb414b9ae1f0f8c13249 + md5: 50ea9a1ab48349f343ca2ae82833bda4 + depends: + - python >=3.12,<3.13.0a0 + - python >=3.12,<3.13.0a0 *_cpython + - python_abi 3.12.* *_cp312 + license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 + size: 901757 + timestamp: 1701883118423 +- kind: conda + name: docutils + version: 0.20.1 + build: py312hb401068_3 + build_number: 3 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/docutils-0.20.1-py312hb401068_3.conda + sha256: 35b4dc2820e724be842f3987b9e9de57d9ab410d1f669d2a94ff997192281e70 + md5: 02a0e6021c5d5a3338775d0dfe3c4d6b + depends: + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 + size: 900339 + timestamp: 1701883109471 - kind: conda name: entrypoints version: '0.4' @@ -5211,6 +5276,23 @@ packages: license_family: MIT size: 46754 timestamp: 1634280590080 +- kind: conda + name: h5netcdf + version: 1.3.0 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/h5netcdf-1.3.0-pyhd8ed1ab_0.conda + sha256: 0195b109e6b18d7efa06124d268fd5dd426f67e2feaee50a358211ba4a4b219b + md5: 6890388078d9a3a20ef793c5ffb169ed + depends: + - h5py + - packaging + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + size: 42170 + timestamp: 1699412919171 - kind: conda name: h5py version: 3.10.0 @@ -6107,13 +6189,13 @@ packages: timestamp: 1709672683901 - kind: conda name: jupyter_client - version: 8.6.0 + version: 8.6.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda - sha256: 86cbb9070862cf23a245451efce539ca214e610849d0950bb8ac90c545bd158d - md5: 6bd3f1069cdebb44c7ae9efb900e312d + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 + md5: c03972cfce69ad913d520c652e5ed908 depends: - importlib_metadata >=4.8.3 - jupyter_core >=4.12,!=5.0.* @@ -6124,16 +6206,16 @@ packages: - traitlets >=5.3 license: BSD-3-Clause license_family: BSD - size: 105838 - timestamp: 1699284056169 + size: 106042 + timestamp: 1710255955150 - kind: conda name: jupyter_core - version: 5.7.1 + version: 5.7.2 build: py312h2e8e312_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.1-py312h2e8e312_0.conda - sha256: d4ad01e013ad873c08fb8118c339695d9f289a908d59a9ffc1e68833ad61405b - md5: 4169f425045de1e7e7ddc19fba8eaf71 + url: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.2-py312h2e8e312_0.conda + sha256: bf2a315febec297e05fa77e39bd371d53553bd1c347e495ac34198fec18afb11 + md5: 3ed5c1981d05f125696f392407d36ce2 depends: - platformdirs >=2.5 - python >=3.12,<3.13.0a0 @@ -6142,16 +6224,16 @@ packages: - traitlets >=5.3 license: BSD-3-Clause license_family: BSD - size: 109627 - timestamp: 1704727662178 + size: 109880 + timestamp: 1710257719549 - kind: conda name: jupyter_core - version: 5.7.1 + version: 5.7.2 build: py312h7900ff3_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.1-py312h7900ff3_0.conda - sha256: ce667e4829f934ace4437474ad4775bbd5ac53a597529afebfd8533dec1e697c - md5: a26a2c80b748744dafb642a9a729e119 + url: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.2-py312h7900ff3_0.conda + sha256: 22a6259c2b139191c76ed7633d1865757b3c15007989f6c74304a80f28e5a262 + md5: eee5a2e3465220ed87196bbb5665f420 depends: - platformdirs >=2.5 - python >=3.12,<3.13.0a0 @@ -6159,16 +6241,16 @@ packages: - traitlets >=5.3 license: BSD-3-Clause license_family: BSD - size: 93563 - timestamp: 1704727167076 + size: 92843 + timestamp: 1710257533875 - kind: conda name: jupyter_core - version: 5.7.1 + version: 5.7.2 build: py312h81bd7bf_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.1-py312h81bd7bf_0.conda - sha256: 56e3b3527364b8065a178112c146f07a59106eefe0a73f6cfaac38ea0f93eec8 - md5: 64dc06b5c9b1ff20ad9afcf00f588cfc + url: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.2-py312h81bd7bf_0.conda + sha256: 5ab0e75a30915d34ae27b4a76f1241c2f4cc4419b6b1c838cc1160b9ec8bfaf5 + md5: 209b9cb7159212afce5e16d7a3ee3b47 depends: - platformdirs >=2.5 - python >=3.12,<3.13.0a0 @@ -6177,16 +6259,16 @@ packages: - traitlets >=5.3 license: BSD-3-Clause license_family: BSD - size: 92987 - timestamp: 1704727587406 + size: 93829 + timestamp: 1710257916303 - kind: conda name: jupyter_core - version: 5.7.1 + version: 5.7.2 build: py312hb401068_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.1-py312hb401068_0.conda - sha256: 410f57e7812dbf9122d416b4a9fc8d3833836fe40929ef845e221d4c8de0edbc - md5: 5db7505ee6fbb00f060782a8d93f974a + url: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.2-py312hb401068_0.conda + sha256: 3e57d1eaf22c793711367335f9f8b647c011b64a95bfc796b50967a4b2ae27c2 + md5: a205e28ce7ab71773dcaaf94f6418612 depends: - platformdirs >=2.5 - python >=3.12,<3.13.0a0 @@ -6194,8 +6276,8 @@ packages: - traitlets >=5.3 license: BSD-3-Clause license_family: BSD - size: 92773 - timestamp: 1704812314487 + size: 92679 + timestamp: 1710257658978 - kind: conda name: jupyter_events version: 0.9.0 @@ -10496,6 +10578,114 @@ packages: license_family: APACHE size: 274631 timestamp: 1701222947083 +- kind: conda + name: lockfile + version: 0.12.2 + build: py_1 + build_number: 1 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/lockfile-0.12.2-py_1.tar.bz2 + sha256: d3a68045ef74a2a7b8c8a55b242fdbc875d362e37adcf793613cf0d8c8e4fbf7 + md5: c104d98e09c47519950cffb8dd5b4f10 + depends: + - python + license: MIT + license_family: MIT + size: 10856 + timestamp: 1531372274693 +- kind: conda + name: luigi + version: 3.5.0 + build: py312h2e8e312_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/luigi-3.5.0-py312h2e8e312_0.conda + sha256: ef58be732d7aaf5cd57e4f23d99f43a77967c8e8966bdc9549f3d3906841c0f5 + md5: 9f658de27da5c64db9c7670c9f80beb6 + depends: + - jsonschema + - prometheus_client >=0.5.0,<0.15 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.7.5,<3 + - python_abi 3.12.* *_cp312 + - setuptools + - tenacity >=8,<9 + - toml <2.0.0 + - tornado >=5.0,<7 + license: Apache-2.0 + license_family: Apache + size: 1317712 + timestamp: 1705340569066 +- kind: conda + name: luigi + version: 3.5.0 + build: py312h7900ff3_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/luigi-3.5.0-py312h7900ff3_0.conda + sha256: 6ee26282116f16035d674502b28124810444e74cffee240c173269cba3fc6ac2 + md5: 58cd3cea6fbceebe970da7f050689b86 + depends: + - jsonschema + - prometheus_client >=0.5.0,<0.15 + - python >=3.12,<3.13.0a0 + - python-daemon + - python-dateutil >=2.7.5,<3 + - python_abi 3.12.* *_cp312 + - setuptools + - tenacity >=8,<9 + - toml <2.0.0 + - tornado >=5.0,<7 + license: Apache-2.0 + license_family: Apache + size: 1301655 + timestamp: 1705340017029 +- kind: conda + name: luigi + version: 3.5.0 + build: py312h81bd7bf_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/luigi-3.5.0-py312h81bd7bf_0.conda + sha256: c962430b9fe81ce1ec8d19be2b2ccb58601d6a00fe77fb8d80a3560bd568a940 + md5: 08cf3dcd12261e802c890463ec229a1d + depends: + - jsonschema + - prometheus_client >=0.5.0,<0.15 + - python >=3.12,<3.13.0a0 + - python >=3.12,<3.13.0a0 *_cpython + - python-daemon + - python-dateutil >=2.7.5,<3 + - python_abi 3.12.* *_cp312 + - setuptools + - tenacity >=8,<9 + - toml <2.0.0 + - tornado >=5.0,<7 + license: Apache-2.0 + license_family: Apache + size: 1305078 + timestamp: 1705340376949 +- kind: conda + name: luigi + version: 3.5.0 + build: py312hb401068_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/luigi-3.5.0-py312hb401068_0.conda + sha256: 4375efc5c5c9dd5b23a733e2df82e33e0b5030b5333c90e623911bcf77dd2a64 + md5: 29a91174a844f96ac5bbdf186ffed0e0 + depends: + - jsonschema + - prometheus_client >=0.5.0,<0.15 + - python >=3.12,<3.13.0a0 + - python-daemon + - python-dateutil >=2.7.5,<3 + - python_abi 3.12.* *_cp312 + - setuptools + - tenacity >=8,<9 + - toml <2.0.0 + - tornado >=5.0,<7 + license: Apache-2.0 + license_family: Apache + size: 1301543 + timestamp: 1705340364904 - kind: conda name: lz4-c version: 1.9.4 @@ -12726,19 +12916,19 @@ packages: timestamp: 1701485332654 - kind: conda name: prometheus_client - version: 0.20.0 + version: 0.14.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda - sha256: 757cd91d01c2e0b64fadf6bc9a11f558cf7638d897dfbaf7415ddf324d5405c9 - md5: 9a19b94034dd3abb2b348c8b93388035 + url: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.14.1-pyhd8ed1ab_0.tar.bz2 + sha256: 66d41fd720b39faad502ea4f67cf70c797ff4a4c5bc01fef536a0880e882713e + md5: b7fa7d86530b8de805268e48988eb483 depends: - - python >=3.8 + - python >=3.6 license: Apache-2.0 license_family: Apache - size: 48913 - timestamp: 1707932844383 + size: 50172 + timestamp: 1649447244565 - kind: conda name: prompt-toolkit version: 3.0.42 @@ -13401,6 +13591,25 @@ packages: license: Python-2.0 size: 13085901 timestamp: 1708117361381 +- kind: conda + name: python-daemon + version: 3.0.1 + build: pyhd8ed1ab_2 + build_number: 2 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/python-daemon-3.0.1-pyhd8ed1ab_2.conda + sha256: 0918c11fab3c3d40739047dcabd107379dd44f0c839e1eb89eb59cc24c3357c2 + md5: ce98ed304e32a8075f7ff5e53c405046 + depends: + - docutils + - lockfile >=0.10 + - python >=3.0 + - setuptools >=62.4.0 + license: Apache-2.0 + license_family: APACHE + size: 33618 + timestamp: 1700732416187 - kind: conda name: python-dateutil version: 2.9.0 diff --git a/pixi.toml b/pixi.toml index 9ef24a0..66446f5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -25,3 +25,5 @@ plotly = ">=5.19.0,<5.20" seaborn = ">=0.13.2,<0.14" pyproj = ">=3.6.1,<3.7" pip = ">=24.0,<25" +h5netcdf = ">=1.3.0,<1.4" +luigi = ">=3.5.0,<3.6" From 0ca9855b8de1bd88018630a96e55cdee3e5bda4a Mon Sep 17 00:00:00 2001 From: Julieanna Bacon Date: Tue, 12 Mar 2024 15:01:54 -0400 Subject: [PATCH 2/3] preprocess: Support centering netcdf crop window arbitrarily and added additional documentation to config file and docstrings. Added project to grid function --- config/preprocess_netcdf.toml | 12 ++++++-- icedyno/preprocess/crop.py | 55 +++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/config/preprocess_netcdf.toml b/config/preprocess_netcdf.toml index 58216ce..b3b34c9 100644 --- a/config/preprocess_netcdf.toml +++ b/config/preprocess_netcdf.toml @@ -1,4 +1,12 @@ [CropFiles] +# Full relative directory is data/input_dir, data/output_dir input_dir = "ims_1km" -output_dir = "ims_netcdf_1km_cropped_4_000_000km_window" -window_size = 4000 +# Change this output_dir name to reflect the window size and center coordinates selected +output_dir = "ims_netcdf_1km_cropped_4_000_000m_window" + +# Final shape will be (window_size*2, window_size*2) +window_size = 4000 #km + +# Expect str format in x,y coordinates if provided. Example: "1000, 2000" +# Defaults to center of current grid system if "None" +center_coordinates = "1000, 1500"#None" diff --git a/icedyno/preprocess/crop.py b/icedyno/preprocess/crop.py index 0a5ea5f..1c8d42b 100644 --- a/icedyno/preprocess/crop.py +++ b/icedyno/preprocess/crop.py @@ -9,6 +9,7 @@ import pathlib import luigi +import numpy as np import xarray as xr @@ -16,13 +17,17 @@ class CropFiles(luigi.Task): """ Crop IMS and MASIE NetCDF files from the center of their grids (where x, y == 1/2*sie.shape) based on input window_size. + Supports centering the window of the cropped files at different locations. + See config/preprocess_netcdf.toml for configuration settings. """ input_dir = luigi.Parameter() output_dir = luigi.Parameter() + center_coordinates = luigi.Parameter() + window_size = luigi.IntParameter(default=4000) - year = luigi.IntParameter() + year = luigi.IntParameter() # Determined at runtime def output(self) -> luigi.LocalTarget: return luigi.LocalTarget( @@ -39,19 +44,35 @@ def run(self) -> None: ) for cdf_filepath in input_cdf_files: + # Set output file name and check if the output file already exists on disk. output_filename = ( os.path.join(year_output_dir, pathlib.Path(cdf_filepath).stem) - + f"_grid{self.window_size}.nc" + + f"_grid{self.window_size}" ) + if self.center_coordinates != "None": + output_filename += ( + f"_{self.center_coordinates.replace(' ', '')}center.nc" + ) + else: + output_filename += ".nc" + if os.path.exists(output_filename): print(cdf_filepath, "already on disk, skipping...") # Open the original NetCDF file ds = xr.open_dataset(cdf_filepath, engine="h5netcdf") - x_coord = ds["x"].shape[0] // 2 - y_coord = ds["y"].shape[0] // 2 - window = self.window_size * 1000 + if self.center_coordinates != "None": + # Expects self.center_coordinates x,y to be "x, y" float values. + x, y = [float(coord) for coord in self.center_coordinates.split(",")] + + # Project x, y to the defined grid and find the index in the grid corresponding to that pair. + x_coord = find_closest_index_in_grid(x, ds.x) + y_coord = find_closest_index_in_grid(y, ds.y) + else: + x_coord = ds["x"].shape[0] // 2 + y_coord = ds["y"].shape[0] // 2 + window = self.window_size * 1000 # from km to meters cropped_ds = ds.sel( x=slice(x_coord - window, x_coord + window), @@ -62,6 +83,28 @@ def run(self) -> None: cropped_ds.to_netcdf(output_filename, engine="h5netcdf") +def find_closest_index_in_grid(target: float, coordinates: np.array) -> int: + """ + Given a target coordinate in projected coordinates (x or y) and the list of coordinates, return the index of the closest number in the coordinates. + Assumes a 1km grid. + """ + assert np.allclose(coordinates % 1000, 500) + start = coordinates[ + 0 + ] # Assume that the first element of coordinates is the minimum number in the list + # -12287500.0 for IMS 1km data. + + # Define the step size + grid_resolution = 1000 # meters + + # Calculate the index of the closest number + index = int((target - start) // grid_resolution) + + # If the solution is correct, the target and the found value should never be more than the grid_resolution apart. + assert abs(coordinates[index] - target) < grid_resolution + return index + + if __name__ == "__main__": os.environ["LUIGI_CONFIG_PARSER"] = "toml" @@ -74,7 +117,7 @@ def run(self) -> None: ## Change acording to your number of cores n_workers = 10 - years = range(2014, 2025) + years = range(2015, 2025) tasks = [CropFiles(year=year) for year in years] luigi.build(tasks, workers=n_workers, local_scheduler=True) From 6925889d908397d9f76b73ed609b7db7650396af Mon Sep 17 00:00:00 2001 From: Julieanna Bacon Date: Tue, 12 Mar 2024 16:03:52 -0400 Subject: [PATCH 3/3] centering crop preprocess: Updated descriptions in the configuration file and tested process more thoroughly --- config/preprocess_netcdf.toml | 6 ++++-- icedyno/preprocess/crop.py | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/config/preprocess_netcdf.toml b/config/preprocess_netcdf.toml index b3b34c9..49961d5 100644 --- a/config/preprocess_netcdf.toml +++ b/config/preprocess_netcdf.toml @@ -1,12 +1,14 @@ [CropFiles] # Full relative directory is data/input_dir, data/output_dir input_dir = "ims_1km" + # Change this output_dir name to reflect the window size and center coordinates selected -output_dir = "ims_netcdf_1km_cropped_4_000_000m_window" +# Example: _50000x_15000y +output_dir = "ims_netcdf_1km_cropped_4_000_000m_window # Final shape will be (window_size*2, window_size*2) window_size = 4000 #km # Expect str format in x,y coordinates if provided. Example: "1000, 2000" # Defaults to center of current grid system if "None" -center_coordinates = "1000, 1500"#None" +center_coordinates = "None" diff --git a/icedyno/preprocess/crop.py b/icedyno/preprocess/crop.py index 1c8d42b..12420cb 100644 --- a/icedyno/preprocess/crop.py +++ b/icedyno/preprocess/crop.py @@ -78,7 +78,6 @@ def run(self) -> None: x=slice(x_coord - window, x_coord + window), y=slice(y_coord - window, y_coord + window), ) - # Write the cropped data to a new NetCDF file cropped_ds.to_netcdf(output_filename, engine="h5netcdf")