{ "cells": [ { "cell_type": "markdown", "id": "5097b345-063a-429a-aa89-a211cf592396", "metadata": {}, "source": [ "## ERA5 data on the Planetary Computer\n", "\n", "The [ERA5 dataset](https://confluence.ecmwf.int/display/CKB/ERA5%3A+data+documentation) from the ECMWF, converted to Zarr by [PlanetOS](https://planetos.com/) data on weather." ] }, { "cell_type": "markdown", "id": "a8323d1d-3a1f-4287-bc5e-afe8da0bf4ec", "metadata": {}, "source": [ "### Query using the STAC API\n", "\n", "The data assets are a collection of Zarr groups, which can be opened with libraries like [xarray](https://xarray.pydata.org/).\n", "\n", "Each STAC item covers a single month and the entire globe. You'll likely query on the `datetime`." ] }, { "cell_type": "code", "execution_count": 1, "id": "2cccba56-8575-4cd7-ab91-421e2cc85dde", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pystac_client\n", "\n", "catalog = pystac_client.Client.open(\n", " \"https://planetarycomputer.microsoft.com/api/stac/v1/\"\n", ")\n", "search = catalog.search(collections=[\"era5-pds\"], datetime=\"1980-01\")\n", "items = search.get_all_items()\n", "\n", "len(items)" ] }, { "cell_type": "code", "execution_count": 2, "id": "0eef9d10-73d3-4f9d-a160-e678a6f2ebfb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[, ]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(items)" ] }, { "cell_type": "markdown", "id": "f7dd402c-f724-4129-9c79-d787f19aba0b", "metadata": {}, "source": [ "There will be two items per month, depending on the kind of variables within: `fc` (or \"forecast\") and `an` (or \"analysis\").\n", "\n", "* An **analysis**, of the atmospheric conditions, is a blend of observations\n", " with a previous forecast. An analysis can only provide\n", " [instantaneous](https://confluence.ecmwf.int/display/CKB/Model+grid+box+and+time+step)\n", " parameters (parameters valid at a specific time, e.g temperature at 12:00),\n", " but not accumulated parameters, mean rates or min/max parameters.\n", "* A **forecast** starts with an analysis at a specific time (the 'initialization\n", " time'), and a model computes the atmospheric conditions for a number of\n", " 'forecast steps', at increasing 'validity times', into the future. A forecast\n", " can provide\n", " [instantaneous](https://confluence.ecmwf.int/display/CKB/Model+grid+box+and+time+step)\n", " parameters, accumulated parameters, mean rates, and min/max parameters.\n", "\n", "You can narrow your search to a specific kind using the `era5:kind` property." ] }, { "cell_type": "code", "execution_count": 3, "id": "7681664c-84dc-4291-8e54-6d389b2abd2f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "import pystac_client\n", "\n", "catalog = pystac_client.Client.open(\n", " \"https://planetarycomputer.microsoft.com/api/stac/v1/\"\n", ")\n", "search = catalog.search(\n", " collections=[\"era5-pds\"], datetime=\"1980-01\", query={\"era5:kind\": {\"eq\": \"an\"}}\n", ")\n", "items = search.get_all_items()\n", "\n", "print(len(items))\n", "item = items[0]" ] }, { "cell_type": "markdown", "id": "34d4b90c-01bf-4fc6-a060-4bd19eff6bc4", "metadata": {}, "source": [ "There are several assets available, one for each data variable. We can build up a dataset with all the variables using `xarray.open_dataset` and `combine_by_coords`." ] }, { "cell_type": "code", "execution_count": 4, "id": "7560c3de-dc8f-487e-adb9-4983b16a6e18", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:                            (time: 744, lat: 721, lon: 1440)\n",
       "Coordinates:\n",
       "  * lat                                (lat) float32 90.0 89.75 ... -89.75 -90.0\n",
       "  * lon                                (lon) float32 0.0 0.25 ... 359.5 359.8\n",
       "  * time                               (time) datetime64[ns] 1980-01-01 ... 1...\n",
       "Data variables:\n",
       "    air_pressure_at_mean_sea_level     (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    air_temperature_at_2_metres        (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    dew_point_temperature_at_2_metres  (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    eastward_wind_at_100_metres        (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    eastward_wind_at_10_metres         (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    northward_wind_at_100_metres       (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    northward_wind_at_10_metres        (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    sea_surface_temperature            (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "    surface_air_pressure               (time, lat, lon) float32 dask.array<chunksize=(372, 150, 150), meta=np.ndarray>\n",
       "Attributes:\n",
       "    institution:  ECMWF\n",
       "    source:       Reanalysis\n",
       "    tilte:        ERA5 forecasts
" ], "text/plain": [ "\n", "Dimensions: (time: 744, lat: 721, lon: 1440)\n", "Coordinates:\n", " * lat (lat) float32 90.0 89.75 ... -89.75 -90.0\n", " * lon (lon) float32 0.0 0.25 ... 359.5 359.8\n", " * time (time) datetime64[ns] 1980-01-01 ... 1...\n", "Data variables:\n", " air_pressure_at_mean_sea_level (time, lat, lon) float32 dask.array\n", " air_temperature_at_2_metres (time, lat, lon) float32 dask.array\n", " dew_point_temperature_at_2_metres (time, lat, lon) float32 dask.array\n", " eastward_wind_at_100_metres (time, lat, lon) float32 dask.array\n", " eastward_wind_at_10_metres (time, lat, lon) float32 dask.array\n", " northward_wind_at_100_metres (time, lat, lon) float32 dask.array\n", " northward_wind_at_10_metres (time, lat, lon) float32 dask.array\n", " sea_surface_temperature (time, lat, lon) float32 dask.array\n", " surface_air_pressure (time, lat, lon) float32 dask.array\n", "Attributes:\n", " institution: ECMWF\n", " source: Reanalysis\n", " tilte: ERA5 forecasts" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import planetary_computer\n", "import xarray as xr\n", "\n", "signed_item = planetary_computer.sign(item)\n", "datasets = [\n", " xr.open_dataset(asset.href, **asset.extra_fields[\"xarray:open_kwargs\"])\n", " for asset in signed_item.assets.values()\n", "]\n", "\n", "ds = xr.combine_by_coords(datasets, join=\"exact\")\n", "ds" ] }, { "cell_type": "markdown", "id": "c2fda08e-5513-496d-8ce5-65fbad4efa1e", "metadata": {}, "source": [ "Now we can plot timeseries for the month, averaged over space:" ] }, { "cell_type": "code", "execution_count": 5, "id": "a795fd49-8904-418d-897b-c13ea8d121ca", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ds[\"sea_surface_temperature\"].mean(dim=[\"lon\", \"lat\"]).plot();" ] }, { "cell_type": "markdown", "id": "15c37cfa-4b18-4050-97c5-c3210a213358", "metadata": {}, "source": [ "Or make a map of some variable on a single date." ] }, { "cell_type": "code", "execution_count": 6, "id": "7d8beee6-1a5a-4198-b8b3-3f35194a2046", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ds[\"sea_surface_temperature\"].isel(time=0).plot(size=8);" ] } ], "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.8.13" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }