diff --git a/notebooks/tutorial/FourCastMini Demo.ipynb b/notebooks/tutorial/FourCastMini Demo.ipynb new file mode 100644 index 00000000..abad5765 --- /dev/null +++ b/notebooks/tutorial/FourCastMini Demo.ipynb @@ -0,0 +1,1138 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d499237-9410-4f01-b517-93100f47a0bf", + "metadata": {}, + "source": [ + "# Quick Training and Inference Demo\n", + "\n", + "Overview:\n", + "- Downloading training data (takes a few minutes)\n", + "- Training a neural network to predict global weather conditions (takes around 90 minutes per epoch)\n", + "- Inferencing the network on unseen data (takes only a moment)\n", + "\n", + "This demo allows the user to download a 2.8GB file containing around 60 years of global eartht system analysis data. Analysis means the science comnunity's best estimate of historical weather conditions based on available observations. The data set used here was produced by the European Centre for Medium Range Weather Forecasting (ECMWF). This is a standard data set used in the field, however most research is done on a higher-resolution version of the data. That said, there is valuable research done at the lower resolution also. The spatial (latitude and longitude) resolution of this data is 64 pixels by 32 pixels, but the time series is very long. Only a few of the most interesting variables are downloaded in this notebook, for reasons of space.\n", + "\n", + "The data is made available by the ECMWF under license, and the conditions are described here: https://www.ecmwf.int/en/forecasts/accessing-forecasts/licenses-available . Please review this before making use of the data for anything. In this tutorial, the data is downloaded using instructions from the weatherbench2 data guide. Please see https://weatherbench2.readthedocs.io/en/latest/data-guide.html for more information on the data, open access, and accessing other resolutions of the data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c7e44d63-956f-41fd-95a6-6441ded61a3e", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "# IMPORTANT! Set this to where you want to store your copy of the data!\n", + "# Set os.environ['ERA5LOWRESDEMO'] = '.' # to use your home directory\n", + "os.environ['ERA5LOWRESDEMO'] = os.environ['PBS_JOBFS']\n", + "\n", + "import hydra\n", + "import pathlib\n", + "import xarray as xr\n", + "\n", + "from omegaconf import OmegaConf\n", + "\n", + "import pyearthtools.data.archive\n", + "import pyearthtools.tutorial\n", + "import pyearthtools.training\n", + "import pyearthtools.pipeline\n", + "\n", + "import fourcastnext\n", + "\n", + "# import torch; torch.set_default_device() # Uncomment and set this if you need to configure a non-default device." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "365f4984-8838-4fda-8964-93c288bd9c7e", + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment the code in this cell in order to download data the first time running through.\n", + "\n", + "# era5_lowres = xr.open_zarr('gs://weatherbench2/datasets/era5/1959-2022-6h-64x32_equiangular_conservative.zarr')\n", + "# subset = era5_lowres[['10m_u_component_of_wind', '10m_v_component_of_wind', '2m_temperature', 'mean_sea_level_pressure']]\n", + "\n", + "# # IMPORTANT! Put this somewhere sensible, then set the environment variable as indicated at the start of the tutorial\n", + "# subset.to_netcdf(os.environ['ERA5LOWRESDEMO'] + '/era5_lowres.nc')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "61aec70a-ffbb-4a37-95dc-9f6ceb59a361", + "metadata": {}, + "outputs": [], + "source": [ + "era5_loaded = xr.open_dataset(os.environ['ERA5LOWRESDEMO'] + '/era5_lowres.nc')\n", + "# era5_loaded # Uncomment this if you want to " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "217eb07c-e789-4193-b78e-e9699f45da3c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset> Size: 132kB\n",
+       "Dimensions:                  (time: 4, longitude: 64, latitude: 32)\n",
+       "Coordinates:\n",
+       "  * latitude                 (latitude) float64 256B -87.19 -81.56 ... 87.19\n",
+       "  * longitude                (longitude) float64 512B 0.0 5.625 ... 348.8 354.4\n",
+       "  * time                     (time) datetime64[ns] 32B 2010-01-01 ... 2010-01...\n",
+       "Data variables:\n",
+       "    10m_u_component_of_wind  (time, longitude, latitude) float32 33kB dask.array<chunksize=(4, 36, 18), meta=np.ndarray>\n",
+       "    10m_v_component_of_wind  (time, longitude, latitude) float32 33kB dask.array<chunksize=(4, 36, 18), meta=np.ndarray>\n",
+       "    2m_temperature           (time, longitude, latitude) float32 33kB dask.array<chunksize=(4, 36, 18), meta=np.ndarray>\n",
+       "    mean_sea_level_pressure  (time, longitude, latitude) float32 33kB dask.array<chunksize=(4, 36, 18), meta=np.ndarray>
" + ], + "text/plain": [ + " Size: 132kB\n", + "Dimensions: (time: 4, longitude: 64, latitude: 32)\n", + "Coordinates:\n", + " * latitude (latitude) float64 256B -87.19 -81.56 ... 87.19\n", + " * longitude (longitude) float64 512B 0.0 5.625 ... 348.8 354.4\n", + " * time (time) datetime64[ns] 32B 2010-01-01 ... 2010-01...\n", + "Data variables:\n", + " 10m_u_component_of_wind (time, longitude, latitude) float32 33kB dask.array\n", + " 10m_v_component_of_wind (time, longitude, latitude) float32 33kB dask.array\n", + " 2m_temperature (time, longitude, latitude) float32 33kB dask.array\n", + " mean_sea_level_pressure (time, longitude, latitude) float32 33kB dask.array" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "accessor = pyearthtools.data.archive.era5_demo_subset('foo')\n", + "accessor['2010-01-01']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "38ff3d85-8a7e-4145-9c52-6f1516d91800", + "metadata": {}, + "outputs": [], + "source": [ + "config_dir = str((pathlib.Path(fourcastnext.__file__).parent / '../../Training/limited_variables_early_stopping').resolve())\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "bee177a3-c883-4f6c-b1d2-0f9f446ceeec", + "metadata": {}, + "outputs": [], + "source": [ + "initialised = hydra.initialize_config_dir(version_base=None, config_dir = config_dir)\n", + "cfg = hydra.compose(config_name=\"lowres.yaml\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c05733a4-e8e8-4b21-9b6d-5449dfdcc9dd", + "metadata": {}, + "outputs": [], + "source": [ + "splits = {\n", + " \"train_split\": pyearthtools.pipeline.iterators.DateRange(*cfg.data.splits.train),\n", + " \"valid_split\": pyearthtools.pipeline.iterators.DateRange(*cfg.data.splits.valid),\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3f0e9c1c-39eb-457b-9001-9f1c9ae45a28", + "metadata": {}, + "outputs": [], + "source": [ + "pipeline_path = str((pathlib.Path(fourcastnext.__file__).parent / '../../Training/pipelines/low_res_demo_subset.pipe').resolve())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "9eae67cf-fe58-42d8-88b6-56a317ce9e5a", + "metadata": {}, + "outputs": [], + "source": [ + "datamodule = pyearthtools.training.data.lightning.PipelineLightningDataModule(\n", + " pipeline_path,\n", + " **splits,\n", + " **cfg.data.module\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "0c475fbf-f74f-42c7-a0b5-887047677f38", + "metadata": {}, + "outputs": [], + "source": [ + "model = hydra.utils.instantiate(cfg.model)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "22980641-e1a5-46c8-890d-218c9c2c6790", + "metadata": {}, + "outputs": [], + "source": [ + "checkpoint_path = os.environ['ERA5LOWRESDEMO']" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "771fe4e1-9550-4b2c-b6cb-b540e57b952a", + "metadata": {}, + "outputs": [], + "source": [ + "trainer = pyearthtools.training.lightning.Train(\n", + " model,\n", + " datamodule,\n", + " path=checkpoint_path,\n", + " trainer_kwargs={'num_sanity_val_steps': 0},\n", + " **OmegaConf.to_object(cfg.trainer)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "b072c58d-6ca0-4189-9c1a-183a09843557", + "metadata": {}, + "outputs": [], + "source": [ + "# IMPORTANT! Uncomment this cell to fit the model. It takes a long time and produced some debugging output, so it has been commented out for display purposes.\n", + "\n", + "# trainer.fit()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1578cde1-a7ce-43a3-a9c7-7ef717add262", + "metadata": {}, + "outputs": [], + "source": [ + "# IMPORTANT! Your checkpoints will be in a unique location based on your training!\n", + "full_checkpoint_path = checkpoint_path + '/Checkpoints/Valid' + '/model-epoch=02-step=15000-valid_loss=40.18821716308594.ckpt'" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "53e74990-2dc0-4d0e-bdf0-2d42d59e5155", + "metadata": {}, + "outputs": [], + "source": [ + "pmodel = fourcastnext.registered_model.FourCastNextRM(\n", + " pipeline='low_res',\n", + " output='.',\n", + " ckpt_path = full_checkpoint_path,\n", + " lead_time=240 # What lead time to predict out to (anywhere from 24 to 240 hours is reasonable)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "daf50654-db6c-4de2-8aa7-78ff967bd7b2", + "metadata": {}, + "outputs": [], + "source": [ + "# IMPORTANT! This cell must be run to produce prediction data. It produces a lot of debugging information, so it has been commented out for display purposes.\n", + "# prediction = pmodel.run('2011-01-01T00')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "b04a23ed-d0a9-4885-82d7-f670b8e7ae73", + "metadata": {}, + "outputs": [], + "source": [ + "data_pipeline = pyearthtools.pipeline.Pipeline(\n", + " pyearthtools.data.archive.era5_demo_subset(['msl', '10u', '10v', '2t']),\n", + " pyearthtools.data.transforms.coordinates.StandardLongitude(type=\"-180-180\"),\n", + " fourcastnext.CropToRectangleSmall(),\n", + " pyearthtools.pipeline.modifications.TemporalRetrieval(\n", + " concat=True,\n", + " samples = ((-6, 1), (6, 2, 6))\n", + " ),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "201f87fe-07bb-41f3-9fca-8835698daa4b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkEAAAHFCAYAAAD1zS3+AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAePtJREFUeJzt3Xl4U1X+P/D3Tdqk6V4odIFCC4KCFWGKYkEFVLZBBHFURIGi8pNBZBNRRr9SVEABGUZccQHcxg1wHBQsyiaCsisCoqyt0FoopXuTNDm/P5hG054TmqU0oe/X8+RRTm7OPXdJ+HC3tyaEECAiIiJqZHQNPQAiIiKihsAiiIiIiBolFkFERETUKLEIIiIiokaJRRARERE1SiyCiIiIqFFiEURERESNEosgIiIiapRYBBEREVGjxCKIfGLLli3IzMzE2bNna73Xq1cv9OrV64KP6UL45ZdfMHXqVKSlpSE6OhpNmjRBjx498Mknn0inz8/PR0ZGBmJjYxEaGor09HR8/fXXtaZbtWoVRo4ciSuuuALBwcHQNE05hieeeAI333wzWrRoAU3TkJGR4fZy1Me4XFm0aBEuu+wyGI1GpKSkYObMmbBarU7TrFixAnfddRcuueQSmEwmJCcn4+6778avv/7qmCYzMxOapp339ef978iRIxg6dCiio6MRHh6OPn36YNeuXdJxnj59GhMnTkRycjKMRiPi4uIwYMAAnDlzpk7L6c68PvjgA3Tu3BkhISFITEzEpEmTUFpaWqf5XOh5EV00BJEPzJs3TwAQR48erfXevn37xL59+y78oC6ARYsWicsuu0zMmjVLZGVliS+++EKMGjVKABAzZ850mrayslKkpqaKli1binfffVdkZWWJwYMHi6CgILFhwwanae+9917Rrl07cccdd4i0tDTh6qsaGhoqrrnmGjF27FhhMBjEqFGj3FqG+hqXyjPPPCM0TRPTp08X69evF3PnzhUGg0GMGTPGabqrr75a3HLLLeKtt94SGzZsEO+8847o0KGDCA8PFz/99JMQQoicnByxdetWx2vFihUCgHjooYec2qv3v/z8fJGYmCguv/xysXz5cvH555+La6+9VkRERIiff/7Zaf4nTpwQbdq0Ee3btxdvvPGG2Lhxo1i+fLkYP368yM3NPe9yujOvd999VwAQ999/v1i3bp149dVXRVRU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rh0GDx6MMWPG4LXXXkNERAQee+wxtGjRAoMHD65zPw899BDmzJmDSy65BJdddhkWLVqEwsLCWkeH/iw5ORmbNm3CsGHDYDQaERsbi169euHUqVOYO3cu/va3v2HNmjVYvXo1IiMjHZ+bOHEinn32WbRr1w4dOnTAggULcPbsWcf7ERERmDp1KiZPngy73Y5rr70WxcXF2LJlC8LDwzFq1CiP1hURkQqPBBEFqCVLliAtLQ0333wz0tPTIYTAF198UesUmCuPPvoo7rrrLowcORLp6ekIDw9Hv379EBISovzMU089hWPHjqFt27Zo1qwZAKBDhw54+eWX8dJLL+HKK6/Etm3bnO5CA4CHH34YI0eOREZGBtLT0xEREeG4ILva008/jSeffBJz5sxBhw4d0K9fP/z3v/9FSkqKG2uGiKhuNOHJBQBEdFGy2+3o0KED7rjjDjz99NMNPRwionrF02FEjdjx48eRlZWFnj17wmw248UXX8TRo0cxfPjwhh4aEVG94+kwokZMp9Nh6dKluOqqq9CjRw/s3bsXX331VZ0vriYiCmQ8HUZERESNEo8EERERUaPEIoiIiIgaJRZBRERE1CixCCIiIqJGiUUQERERNUosgoiIiKhRYhFEREREjRKLICIiImqUWAQRERFRo/T/AQRbPpNtAnl/AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot prediction\n", + "LEAD_INTERVAL = 4 # (each interval is an additional 6 hours)\n", + "(prediction['2m_temperature'][LEAD_INTERVAL] - 273.15).plot(x='longitude', y='latitude')" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "c0eea386-b3b8-4bcc-b2d5-040daa2b5036", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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vhEtWrQQ48aNs9Xhq/t2qa1bt4oFCxaIPXv2iGPHjonPPvtMxMbGirvuusu2TU3211d9+umnIjAwULz77rviwIEDYsKECSIkJEQcP368vrtWY08++aTYuHGjOHbsmPj+++/FnXfeKcLCwmz78NJLL4mIiAixfPlysW/fPnH//feLmJgYUVhYWM89lysqKrJ9pgDYzr8TJ04IIWq2P4899pho0aKF+Oabb8Tu3bvFbbfdJq677jpRVVVVX7slhHC+b0VFReLJJ58UW7duFRkZGWLDhg0iOTlZNG/e3C/2jXwDgyAfMXLkSAHAYdmwYYMQQog1a9aIzp07i9DQUBEcHCwSExPFwoULRWVlpV09P/30k7jllluE0WgUZrNZpKWl1fst5JfbNyEuBEoDBgwQJpNJNG7cWIwbN87udnghfHPfLrVr1y7RrVs3ERERIYKCgsTVV18tpk+fLoqLi+22q8n++qpXX31VtGrVShgMBnH99deLTZs21XeXXHLfffeJmJgYERgYKGJjY8WQIUPE/v37beutVquYPn26MJvNwmg0iltvvVXs27evHnvs3IYNG6Sfr5EjRwoharY/paWlYty4caJx48bCZDKJO++8U2RmZtbD3thztm8lJSWiT58+omnTpiIwMFC0bNlSjBw50qHfvrpv5Bs0IXzwkbtEREREtYxzgoiIiKhBYhBEREREDRKDICIiImqQGAQRERFRg8QgiIiIiBokBkFERETUIDEIIiIiogaJQRCRH+nZsycmTJhwxbSZmppqy9dFRFTXmECViJxavnw5AgMDbf+Oj4/HhAkT6jwYIyLyNgZBRORU48aN67sLRES1gpfDiPxUfn4+RowYgcjISAQHB6N///749ddfbevff/99NGrUCF9//TXat2+P0NBQ9OvXzy57fVVVFcaPH49GjRqhSZMmePrppzFy5Ei7S1QXXw7r2bMnTpw4gYkTJ0LTNGiaBgBIS0tD586d7fq3cOFCxMfH2/5tsVgwadIkW1tTpkzBpVl7hBCYM2cOWrduDZPJhOuuuw7/+te/vHPAiIguwSCIyE+lpqZi586d+Oqrr7Bt2zYIIfCnP/0JlZWVtm1KSkowb948fPjhh9i8eTMyMzMxefJk2/qXX34ZH3/8MZYsWYLvvvsOhYWF+PLLL5VtLl++HC1atMDzzz+P7Oxsu4DqcubPn4/33nsP7777LrZs2YKzZ89ixYoVdts8++yzWLJkCV5//XXs378fEydOxIMPPohNmzbV/MAQEdUQL4cR+aFff/0VX331Fb777jt0794dAPDxxx8jLi4OX375Je655x4AQGVlJd544w1cddVVAIBx48bh+eeft9WzaNEiTJ06FXfffTcAYPHixVi9erWy3caNG0Ov1yMsLAxms9mlPi9cuBBTp07Fn//8ZwDAG2+8ga+//tq2vri4GAsWLMD69euRnJwMAGjdujW2bNmCN998EykpKS61R0R0OQyCiPzQwYMHERAQgG7dutnKmjRpgquvvhoHDx60lQUHB9sCIACIiYlBbm4uAKCgoAC///47brzxRtt6vV6PpKQkWK1Wr/a3oKAA2dnZtuAGAAICAtC1a1fbJbEDBw6grKwMvXv3tnttRUUFunTp4tX+EBEBDIKI/NKlc2kuLq+epwPA7q4uANA0zeG1F2/vrG5ndDqdw+suvixXE9WB16pVq9C8eXO7dUaj0eU+ERFdDucEEfmhDh06oKqqCtu3b7eV5eXl4ZdffkH79u1rVEdERASio6Pxww8/2MosFgv27Nnj9HUGgwEWi8WurGnTpsjJybELhPbu3WvXVkxMDL7//ntbWVVVFXbt2mW3T0ajEZmZmWjTpo3dEhcXV6N9IiJyBUeCiPxQ27ZtMWjQIIwePRpvvvkmwsLC8Mwzz6B58+YYNGhQjet5/PHHMXv2bLRp0wbXXHMNFi1ahPz8fIfRoYvFx8dj8+bNGDp0KIxGI6KiotCzZ0+cPn0ac+bMwV/+8hesXbsWa9asQXh4uO11TzzxBF566SW0bdsW7du3x4IFC3Du3Dnb+rCwMEyePBkTJ06E1WrFzTffjMLCQmzduhWhoaEYOXKkW8eKiEiFI0FEfmrJkiVISkrCnXfeieTkZAghsHr1aodLYM48/fTTuP/++zFixAgkJycjNDQUffv2RVBQkPI1zz//PI4fP46rrroKTZs2BQC0b98er732Gl599VVcd911+OGHH+zuQgOAJ598EiNGjEBqaiqSk5MRFhZmm5Bd7YUXXsBzzz2H2bNno3379ujbty/+85//ICEhwYUjQ0RUM5pwZwIAEV2RrFYr2rdvj3vvvRcvvPBCfXeHiKhW8XIYUQN24sQJpKenIyUlBeXl5Vi8eDEyMjIwbNiw+u4aEVGt4+UwogZMp9Ph/fffxw033IAePXpg3759+Oabb2o8uZqIyJ/xchgRERE1SBwJIiIiogaJQRARERE1SAyCiIiIqEFiEEREREQNEoMgIiIiapAYBBEREVGDxCCIiIiIGiQGQURERNQgMQgiIiKiBun/A7f+ufwWohsxAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot observation\n", + "(data_pipeline['2011-01-02T12'][0]['2m_temperature']- 273.15).plot(x='longitude', y='latitude')" + ] + }, + { + "cell_type": "markdown", + "id": "7552300c-4e2d-4804-bae1-45370dc65312", + "metadata": {}, + "source": [ + "# Things to try next\n", + "\n", + "1. This model uses a simple crop to fit the kernel size expected by FourCastNeXt. It would be better to regrid it to the right size.\n", + "2. The model needs to train for quite a while to converge. A common problem in machine learning is not knowing quite how long to train a network. Try training it on more data, or for more epochs, and chart out how that affects the training effectiveness as measured by the loss function\n", + "3. This notebook doesn't include any comparisons to benchmarks such as a persistence model or an alternative model. Charting skill score comparisons would be very useful.\n", + "4. A scorecard of results can also be informative, to see accuracy from multiple perspectives\n", + "5. Charting the skill of the model with respect to lead time would also be a useful exercise" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b4452b0-3deb-4e42-8ac7-d6c22e5a0a25", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/packages/bundled_models/fourcastnext/Training/configs/config.yaml b/packages/bundled_models/fourcastnext/Training/configs/config.yaml index dd6c508d..cdeac2ae 100644 --- a/packages/bundled_models/fourcastnext/Training/configs/config.yaml +++ b/packages/bundled_models/fourcastnext/Training/configs/config.yaml @@ -10,7 +10,7 @@ defaults: experiment_name: ${now:%Y-%m-%d}/${now:%H-%M-%S} path: /scratch/kd24/${oc.env:USER}/ML/FourCastNeXt/Training/${experiment_name} -fit: False +fit: false hydra: verbose: false diff --git a/packages/bundled_models/fourcastnext/Training/configs/data/module/default.yaml b/packages/bundled_models/fourcastnext/Training/configs/data/module/default.yaml index 585b7705..14d15ad0 100644 --- a/packages/bundled_models/fourcastnext/Training/configs/data/module/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/configs/data/module/default.yaml @@ -1,2 +1,2 @@ -num_workers: 12 -batch_size: 8 +num_workers: 4 +batch_size: 4 diff --git a/packages/bundled_models/fourcastnext/Training/configs/data/splits/default.yaml b/packages/bundled_models/fourcastnext/Training/configs/data/splits/default.yaml index 1167f230..87aefd69 100644 --- a/packages/bundled_models/fourcastnext/Training/configs/data/splits/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/configs/data/splits/default.yaml @@ -1,4 +1,4 @@ -random: True +random: true random_seed: 42 train: - 1980 diff --git a/packages/bundled_models/fourcastnext/Training/configs/data/splits/short_training.yaml b/packages/bundled_models/fourcastnext/Training/configs/data/splits/short_training.yaml new file mode 100644 index 00000000..f286ebcf --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/configs/data/splits/short_training.yaml @@ -0,0 +1,10 @@ +random: true +random_seed: 42 +train: + - 2000 + - 2015 + - 6 hours +valid: + - 2018 + - 2020 + - 6 hours diff --git a/packages/bundled_models/fourcastnext/Training/configs/model/default.yaml b/packages/bundled_models/fourcastnext/Training/configs/model/default.yaml index 204af0e6..49312355 100644 --- a/packages/bundled_models/fourcastnext/Training/configs/model/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/configs/model/default.yaml @@ -1,10 +1,9 @@ - +--- _target_: fourcastnext.lightning_model.FourCastNextLM _recursive_: true - # Model parameters to init AFNONet model_params: - img_size : ${data.img_size} - in_channels : ${data.in_channels} - out_channels : ${data.out_channels} + img_size: ${data.img_size} + in_channels: ${data.in_channels} + out_channels: ${data.out_channels} diff --git a/packages/bundled_models/fourcastnext/Training/configs/trainer/default.yaml b/packages/bundled_models/fourcastnext/Training/configs/trainer/default.yaml index 379a8c37..d2ca183d 100644 --- a/packages/bundled_models/fourcastnext/Training/configs/trainer/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/configs/trainer/default.yaml @@ -1,5 +1,6 @@ +--- precision: 16-mixed -max_epochs: 200 +max_epochs: 5 checkpointing: - monitor: "train_loss" @@ -18,5 +19,5 @@ checkpointing: mode: "max" dirpath: "{path}/Checkpoints/Epoch" filename: "model-{epoch:02d}" - save_on_train_epoch_end: True + save_on_train_epoch_end: true save_top_k: 50 diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/lowres.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/lowres.yaml new file mode 100644 index 00000000..d27caba4 --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/lowres.yaml @@ -0,0 +1,9 @@ +# Use the ERA5 limited variable pipeline + +pipelines: pipelines/limited_variables.pipe + +img_size: + - 64 + - 28 +in_channels: 4 +out_channels: 4 diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/module/default.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/module/default.yaml index 1a197ec1..14d15ad0 100644 --- a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/module/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/module/default.yaml @@ -1,2 +1,2 @@ num_workers: 4 -batch_size: 1 +batch_size: 4 diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/default.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/default.yaml index 2843fa6b..87aefd69 100644 --- a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/default.yaml @@ -1,8 +1,8 @@ -random: True +random: true random_seed: 42 train: - - 2000 - - 2015 + - 1980 + - 2018 - 6 hours valid: - 2018 diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/short_training_splits.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/short_training_splits.yaml new file mode 100644 index 00000000..365610d0 --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/data/splits/short_training_splits.yaml @@ -0,0 +1,11 @@ +--- +random: true +random_seed: 42 +train: + - 2000 + - 2015 + - 6 hours +valid: + - 2018 + - 2020 + - 6 hours diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/limited_vars_early_stop.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/limited_vars_early_stop.yaml index 1fda4d18..b8c71ad1 100644 --- a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/limited_vars_early_stop.yaml +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/limited_vars_early_stop.yaml @@ -10,7 +10,7 @@ defaults: experiment_name: ${now:%Y-%m-%d}/${now:%H-%M-%S} path: /scratch/kd24/${oc.env:USER}/ML/FourCastNeXt/Training/${experiment_name} -fit: False +fit: false hydra: verbose: false diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/lowres.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/lowres.yaml new file mode 100644 index 00000000..3a16ba65 --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/lowres.yaml @@ -0,0 +1,19 @@ +--- +defaults: + - _self_ + - trainer: few_epochs + - model: default + - data: lowres + + - data/splits: short_training_splits + - data/module: default + +experiment_name: ${now:%Y-%m-%d}/${now:%H-%M-%S} +path: ./Experiments/FourCastNeXt/Training/${experiment_name} + +fit: false + +hydra: + verbose: false + run: + dir: ${path} diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/model/default.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/model/default.yaml index 204af0e6..49312355 100644 --- a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/model/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/model/default.yaml @@ -1,10 +1,9 @@ - +--- _target_: fourcastnext.lightning_model.FourCastNextLM _recursive_: true - # Model parameters to init AFNONet model_params: - img_size : ${data.img_size} - in_channels : ${data.in_channels} - out_channels : ${data.out_channels} + img_size: ${data.img_size} + in_channels: ${data.in_channels} + out_channels: ${data.out_channels} diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/default.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/default.yaml index 379a8c37..ab70ccb7 100644 --- a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/default.yaml +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/default.yaml @@ -18,5 +18,5 @@ checkpointing: mode: "max" dirpath: "{path}/Checkpoints/Epoch" filename: "model-{epoch:02d}" - save_on_train_epoch_end: True + save_on_train_epoch_end: true save_top_k: 50 diff --git a/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/few_epochs.yaml b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/few_epochs.yaml new file mode 100644 index 00000000..d2ca183d --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/limited_variables_early_stopping/trainer/few_epochs.yaml @@ -0,0 +1,23 @@ +--- +precision: 16-mixed +max_epochs: 5 + +checkpointing: +- monitor: "train_loss" + mode: "min" + dirpath: "{path}/Checkpoints/Train" + filename: "model-{epoch:02d}-{step:02d}" + every_n_train_steps: 1000 + save_top_k: 10 +- monitor: "valid_loss" + mode: "min" + dirpath: "{path}/Checkpoints/Valid" + filename: "model-{epoch:02d}-{step:02d}-{valid_loss}" + every_n_train_steps: 5000 + save_top_k: 10 +- monitor: "epoch" + mode: "max" + dirpath: "{path}/Checkpoints/Epoch" + filename: "model-{epoch:02d}" + save_on_train_epoch_end: true + save_top_k: 50 diff --git a/packages/bundled_models/fourcastnext/Training/pipelines/low_res_demo_subset.pipe b/packages/bundled_models/fourcastnext/Training/pipelines/low_res_demo_subset.pipe new file mode 100644 index 00000000..cf1489cd --- /dev/null +++ b/packages/bundled_models/fourcastnext/Training/pipelines/low_res_demo_subset.pipe @@ -0,0 +1,46 @@ +!pyearthtools@pyearthtools.pipeline.controller.Pipeline +__args: !!python/tuple +- !pyearthtools@pyearthtools.data.archive.era5_demo_subset + level_value: null + product: reanalysis + transforms: null + variables: + - msl + - 10u + - 10v + - 2t +- !pyearthtools@pyearthtools.pipeline.operations.transforms.Transforms + apply: !pyearthtools@pyearthtools.data.transforms.coordinates.StandardLongitude + type: -180-180 + transforms: null + undo: null +- !pyearthtools@fourcastnext.CropToRectangleSmall + warn: true +- !pyearthtools@pyearthtools.pipeline.modifications.idx_modification.TemporalRetrieval + concat: true + delta_unit: null + merge_function: null + merge_kwargs: + axis: 1 + samples: !!python/tuple + - !!python/tuple + - -6 + - 1 + - !!python/tuple + - 6 + - 2 + - 6 +- !pyearthtools@pyearthtools.pipeline.operations.xarray.conversion.ToNumpy + warn: true +- !pyearthtools@pyearthtools.pipeline.operations.numpy.reshape.Rearrange + rearrange: c t h w -> t c h w + rearrange_kwargs: null + reverse_rearrange: null + skip: false +exceptions_to_ignore: null +iterator: null +sampler: !pyearthtools@pyearthtools.pipeline.samplers.Default {} + +--CONFIG-- +VERSION: 1.0.1 +import: [] diff --git a/packages/bundled_models/fourcastnext/src/fourcastnext/__init__.py b/packages/bundled_models/fourcastnext/src/fourcastnext/__init__.py index a571c343..1837ba9b 100644 --- a/packages/bundled_models/fourcastnext/src/fourcastnext/__init__.py +++ b/packages/bundled_models/fourcastnext/src/fourcastnext/__init__.py @@ -48,3 +48,28 @@ def undo_func(self, dataset_to_undo, **kwargs): # Just return the cropped data, cannot 'undo' this one return dataset_to_undo + + +class CropToRectangleSmall(Operation): + """Cut with Bounding box""" + + def __init__(self, warn=True): + """ + Default ERA5 is 721x1440. FourCastNeXt needs to be able to use 2x2 kernels, so needs an even number grid + dimension. For now, this class just disposes of the surplus pixels. In future the cropping strategy + from the paper could be implemented, or a complex regrid could be performed to resample to an even grid + """ + super().__init__() + self.record_initialisation() + + def apply_func(self, dataset: xr.Dataset): + subset_dataset = dataset.isel( + latitude=slice(0, -4), + ) + + return subset_dataset + + def undo_func(self, dataset_to_undo, **kwargs): + + # Just return the cropped data, cannot 'undo' this one + return dataset_to_undo diff --git a/packages/bundled_models/fourcastnext/src/fourcastnext/configs/Data/low_res.pipe b/packages/bundled_models/fourcastnext/src/fourcastnext/configs/Data/low_res.pipe new file mode 100644 index 00000000..cf1489cd --- /dev/null +++ b/packages/bundled_models/fourcastnext/src/fourcastnext/configs/Data/low_res.pipe @@ -0,0 +1,46 @@ +!pyearthtools@pyearthtools.pipeline.controller.Pipeline +__args: !!python/tuple +- !pyearthtools@pyearthtools.data.archive.era5_demo_subset + level_value: null + product: reanalysis + transforms: null + variables: + - msl + - 10u + - 10v + - 2t +- !pyearthtools@pyearthtools.pipeline.operations.transforms.Transforms + apply: !pyearthtools@pyearthtools.data.transforms.coordinates.StandardLongitude + type: -180-180 + transforms: null + undo: null +- !pyearthtools@fourcastnext.CropToRectangleSmall + warn: true +- !pyearthtools@pyearthtools.pipeline.modifications.idx_modification.TemporalRetrieval + concat: true + delta_unit: null + merge_function: null + merge_kwargs: + axis: 1 + samples: !!python/tuple + - !!python/tuple + - -6 + - 1 + - !!python/tuple + - 6 + - 2 + - 6 +- !pyearthtools@pyearthtools.pipeline.operations.xarray.conversion.ToNumpy + warn: true +- !pyearthtools@pyearthtools.pipeline.operations.numpy.reshape.Rearrange + rearrange: c t h w -> t c h w + rearrange_kwargs: null + reverse_rearrange: null + skip: false +exceptions_to_ignore: null +iterator: null +sampler: !pyearthtools@pyearthtools.pipeline.samplers.Default {} + +--CONFIG-- +VERSION: 1.0.1 +import: [] diff --git a/packages/data/.yamllint.yml b/packages/data/.yamllint.yml index 7e4b2ee5..3a3e85eb 100644 --- a/packages/data/.yamllint.yml +++ b/packages/data/.yamllint.yml @@ -1,4 +1,4 @@ - +--- extends: default rules: diff --git a/packages/data/src/pyearthtools/data/data.yaml b/packages/data/src/pyearthtools/data/data.yaml index e0abddfc..039673bd 100644 --- a/packages/data/src/pyearthtools/data/data.yaml +++ b/packages/data/src/pyearthtools/data/data.yaml @@ -6,24 +6,24 @@ data: # Data configuration chunks: 'auto' combine_attrs: 'drop_conflicts' xarray_mf: - parallel: False + parallel: false save: # Save files default kwargs xarray: engine: 'netcdf4' zarr: - compute: True + compute: true search_function: 'filesystem' # Search function to use to find files - experimental: False # Experimental feature toggle + experimental: false # Experimental feature toggle series: warning_threshold: 5 # .series warning threshold - future_warning: True # Show FutureWarning of pyearthtools's development + future_warning: true # Show FutureWarning of pyearthtools's development patterns: # Pattern defaults default_extension: .nc diff --git a/packages/data/src/pyearthtools/data/static/_geographic/Australia/Capital/download.yaml b/packages/data/src/pyearthtools/data/static/_geographic/Australia/Capital/download.yaml index 326f9e57..0163a1d9 100644 --- a/packages/data/src/pyearthtools/data/static/_geographic/Australia/Capital/download.yaml +++ b/packages/data/src/pyearthtools/data/static/_geographic/Australia/Capital/download.yaml @@ -1,4 +1,3 @@ - --- # Download Config For Capital Cities Data url: https://www.abs.gov.au/statistics/standards/australian-statistical-geography-standard-asgs-edition-3/jul2021-jun2026/access-and-downloads/digital-boundary-files/GCCSA_2021_AUST_SHP_GDA2020.zip diff --git a/packages/data/src/pyearthtools/data/static/_geographic/Australia/States/download.yaml b/packages/data/src/pyearthtools/data/static/_geographic/Australia/States/download.yaml index 7fc6ba04..b2471e7a 100644 --- a/packages/data/src/pyearthtools/data/static/_geographic/Australia/States/download.yaml +++ b/packages/data/src/pyearthtools/data/static/_geographic/Australia/States/download.yaml @@ -1,4 +1,3 @@ - --- # Download Config For States Data url: https://www.abs.gov.au/statistics/standards/australian-statistical-geography-standard-asgs-pyearthtoolsion-3/jul2021-jun2026/access-and-downloads/digital-boundary-files/STE_2021_AUST_SHP_GDA2020.zip diff --git a/packages/data/src/pyearthtools/data/static/_geographic/Australia/download.yaml b/packages/data/src/pyearthtools/data/static/_geographic/Australia/download.yaml index 155e7c66..2f1eced3 100644 --- a/packages/data/src/pyearthtools/data/static/_geographic/Australia/download.yaml +++ b/packages/data/src/pyearthtools/data/static/_geographic/Australia/download.yaml @@ -1,6 +1,5 @@ - --- # Download Config For Australia Data url: https://www.abs.gov.au/statistics/standards/australian-statistical-geography-standard-asgs-edition-3/jul2021-jun2026/access-and-downloads/digital-boundary-files/AUS_2021_AUST_SHP_GDA2020.zip save_name: Australia.zip -zip: true +zip: true \ No newline at end of file diff --git a/packages/data/src/pyearthtools/data/static/_geographic/World/download.yaml b/packages/data/src/pyearthtools/data/static/_geographic/World/download.yaml index bb9912f8..21baceec 100644 --- a/packages/data/src/pyearthtools/data/static/_geographic/World/download.yaml +++ b/packages/data/src/pyearthtools/data/static/_geographic/World/download.yaml @@ -1,4 +1,3 @@ - --- # Download Config For World Data url: https://public.opendatasoft.com/api/explore/v2.1/catalog/datasets/world-administrative-boundaries/exports/shp?lang=en&timezone=Australia%2FSydney diff --git a/packages/data/src/pyearthtools/data/transforms/RegionLookup.yaml b/packages/data/src/pyearthtools/data/transforms/RegionLookup.yaml index 7697dcc9..e3f0eb27 100644 --- a/packages/data/src/pyearthtools/data/transforms/RegionLookup.yaml +++ b/packages/data/src/pyearthtools/data/transforms/RegionLookup.yaml @@ -11,7 +11,7 @@ Australia: Oceania: [-50, -5, 90, 180] -Adelaide: [-39,-30, 131, 140] +Adelaide: [-39, -30, 131, 140] Brisbane: [-30, -20, 145, 155] Sydney: [-38, -28, 145, 155] Melbourne: [-42, -32, 139, 151] diff --git a/packages/nci_site_archive/mkdocs.yml b/packages/nci_site_archive/mkdocs.yml index 93088ff2..e45fd1fc 100644 --- a/packages/nci_site_archive/mkdocs.yml +++ b/packages/nci_site_archive/mkdocs.yml @@ -57,7 +57,7 @@ plugins: docstring_style: "google" paths: [src] members_order: source - show_submodules: True + show_submodules: true options: allow_inspection: false show_source: false diff --git a/packages/pipeline/src/pyearthtools/pipeline/pipeline.yaml b/packages/pipeline/src/pyearthtools/pipeline/pipeline.yaml index 61d0bdf1..de4bf830 100644 --- a/packages/pipeline/src/pyearthtools/pipeline/pipeline.yaml +++ b/packages/pipeline/src/pyearthtools/pipeline/pipeline.yaml @@ -1,15 +1,15 @@ pipeline: - run_parallel: False # Attempt to run parallel at all, if False, will use Serial Interface + run_parallel: false # Attempt to run parallel at all, if False, will use Serial Interface parallel: # Configuration for parallel running enabled: # Which interfaces are enabled - Delayed: True - Futures: False + Delayed: true + Futures: false dask: # Configuration for dask - start: True + start: true client: # Dask client config - processes: False + processes: false config: {} # Dask config to be set after spinning up distributed cluster @@ -21,4 +21,4 @@ pipeline: default_ignore: [] # Default exceptions to ignore when iterating repr: - show_graph: True # Show graph in ipython repr + show_graph: true # Show graph in ipython repr diff --git a/packages/tutorial/pyproject.toml b/packages/tutorial/pyproject.toml index b97e8ea3..a72c5bcf 100644 --- a/packages/tutorial/pyproject.toml +++ b/packages/tutorial/pyproject.toml @@ -15,9 +15,6 @@ classifiers = [ "Operating System :: OS Independent", ] dependencies = [ - "pyearthtools.data", - "pyearthtools.pipeline", - "pyearthtools.training", "rich", "ipywidgets", "scores", diff --git a/packages/tutorial/src/pyearthtools/tutorial/ERA5DataClass.py b/packages/tutorial/src/pyearthtools/tutorial/ERA5DataClass.py index 7ec32f44..37794e88 100644 --- a/packages/tutorial/src/pyearthtools/tutorial/ERA5DataClass.py +++ b/packages/tutorial/src/pyearthtools/tutorial/ERA5DataClass.py @@ -30,6 +30,7 @@ import functools from pathlib import Path from typing import Any, Literal +import xarray as xr import pyearthtools.data from pyearthtools.data import Petdt @@ -45,10 +46,13 @@ # This tells pyearthtools what the actual resolution or time-step of the data is inside the files ERA_RESOLUTION = (1, "hour") +ERADEMO_RESOLUTION = (6, "hour") # This dictionary tells pyearthtools what variable renames to apply during load ERA5_RENAME = {"t2m": "2t", "u10": "10u", "v10": "10v", "siconc": "ci"} +ERA5DEMO_RENAME = {"t2m": "2t", "10u": "10m_u_component_of_wind", "v10": "10v"} + V_TO_PATH = { "10m_u_component_of_wind": "10m_u_component_of_wind", "10m_v_component_of_wind": "10m_v_component_of_wind", @@ -192,3 +196,107 @@ def filesystem( def _import(self): """module to import for to load this step in an Pipeline""" return "pyearthtools.tutorial" + + +@register_archive("era5_demo_subset", sample_kwargs=dict(variable="2t")) +class ERA5LowResDemoIndex(ArchiveIndex): + """ECWMF ReAnalysis v5""" + + @property + def _desc_(self): + return { + "singleline": "ECWMF ReAnalysis v5", + "range": "1970-current", + "Documentation": "https://confluence.ecmwf.int/display/CKB/ERA5%3A+data+documentation", + } + + @decorators.alias_arguments( + level_value=["pressure"], + variables=["variable"], + product=["resolution"], + ) + @decorators.variable_modifications(variable_keyword="variables", remove_variables=False) + @decorators.deprecated_arguments( + level="`level` is deprecated in the ERA5 index. Simply provide the variables, `level` will be autofound." + ) + def __init__( + self, + variables: list[str] | str, + *, + level_value: int | float | list[int | float] | tuple[list | int, ...] | None = None, + transforms: Transform | TransformCollection | None = None, + product=None, + ): + """ + Setup ERA5 Low-Res Indexer + + Args: + variables (list[str] | str): + Data variables to retrieve + resolution (Literal[ERA_RES], optional): + Resolution of data, must be one of 'monthly-averaged','monthly-averaged-by-hour', 'reanalysis'. + Defaults to 'reanalysis'. + level_value: (int, optional): + Level value to select if data contains levels. Defaults to None. + transforms (Transform | TransformCollection, optional): + Base Transforms to apply. + Defaults to TransformCollection(). + """ + + variables = [variables] if isinstance(variables, str) else variables + + self.resolution = ERADEMO_RESOLUTION + self.dataset = None + + self.variables = variables + base_transform = TransformCollection() + + base_transform += pyearthtools.data.transforms.attributes.Rename(ERA5DEMO_RENAME) + # base_transform += pyearthtools.data.transforms.variables.variable_trim(variables) + + self.level_value = level_value + + if level_value: + base_transform += pyearthtools.data.transforms.coordinates.Select( + {coord: level_value for coord in ["level"]}, ignore_missing=True + ) + + super().__init__( + transforms=base_transform + (transforms or TransformCollection()), + data_interval=ERADEMO_RESOLUTION, + ) + self.record_initialisation() + + def filesystem( + self, + querytime: str | Petdt, + ) -> Path | dict[str, str | Path]: + ERA5_HOME = self.ROOT_DIRECTORIES["era5lowresdemo"] + + """ + This tells pyearthtools how to go from a request for a date/time to a path containing the files + which will match that request. + """ + path = Path(ERA5_HOME) / "era5_lowres.nc" # Everything fits into a single 2 GIG file + + return [path] + + def load(self, *args, **kwargs): + """ + This particular example has all its data in a single file, so repeatedly + loading files is avoided through caching the loaded dataset. This isn't + a great general pattern, but works well for the tutorial. + """ + + if self.dataset: + return self.dataset + + ds = xr.open_dataset(args[0][0], engine="h5netcdf") + self.dataset = ds + + return self.dataset + + @property + def _import(self): + """module to import for to load this step in an Pipeline""" + return "pyearthtools.tutorial" diff --git a/packages/tutorial/src/pyearthtools/tutorial/__init__.py b/packages/tutorial/src/pyearthtools/tutorial/__init__.py index 8ff1b4c3..284e94f5 100644 --- a/packages/tutorial/src/pyearthtools/tutorial/__init__.py +++ b/packages/tutorial/src/pyearthtools/tutorial/__init__.py @@ -30,9 +30,12 @@ default_base = "/g/data/wb00/NCI-Weatherbench/5.625deg" # taken from NCI noteboook on github lowres_base = os.environ.get("ERA5LOWRES", default_base) +USER_HOME = os.path.expanduser("~") +lowresdemo_base = os.environ.get("ERA5LOWRESDEMO", USER_HOME) ROOT_DIRECTORIES = { "era5lowres": lowres_base, # Update this to the base dir, get var from config + "era5lowresdemo": lowresdemo_base, # Update this to the base dir, get var from config } # Register archive returns a callable which can be used to register an object diff --git a/packages/utils/src/pyearthtools/utils/iPython.py b/packages/utils/src/pyearthtools/utils/iPython.py index d63a325a..33b29f6d 100644 --- a/packages/utils/src/pyearthtools/utils/iPython.py +++ b/packages/utils/src/pyearthtools/utils/iPython.py @@ -20,6 +20,7 @@ # TODO: Determine if this file should be deleted, or else give an example of its # use in a notebook + def display_np_arrays_as_images(): def np_to_png(a): if 2 <= len(a.shape) <= 3: