{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This cell is not visible when the documentation is built.\n", "\n", "from __future__ import annotations\n", "\n", "import numpy as np\n", "import pandas as pd\n", "import xarray as xr\n", "from scipy.interpolate import interp1d\n", "\n", "# Workaround for determining the notebook folder within a running notebook\n", "try:\n", " from _finder import _find_current_folder\n", "\n", " notebook_folder = _find_current_folder()\n", "except ImportError:\n", " from pathlib import Path\n", "\n", " notebook_folder = Path().cwd()\n", "\n", "pd.plotting.register_matplotlib_converters()\n", "\n", "data_folder = notebook_folder / \"data\"\n", "data_folder.mkdir(exist_ok=True)\n", "\n", "# time vector on 4 years\n", "times = pd.date_range(\"2000-01-01\", \"2003-12-31\", freq=\"D\")\n", "# temperature data as seasonal cycle -18 to 18\n", "tas = xr.DataArray(\n", " -18 * np.cos(2 * np.pi * times.dayofyear / 365),\n", " dims=(\"time\",),\n", " coords={\"time\": times},\n", " name=\"tas\",\n", " attrs={\n", " \"units\": \"degC\",\n", " \"standard_name\": \"air_temperature\",\n", " \"long_name\": \"Mean air temperature at surface\",\n", " },\n", ")\n", "\n", "# write 10 members adding cubic-smoothed gaussian noise of wave number 43 and amplitude 20\n", "# resulting temp will oscillate between -18 and 38\n", "for i in range(10):\n", " tasi = tas + 20 * interp1d(np.arange(43), np.random.random((43,)), kind=\"quadratic\")(np.linspace(0, 42, tas.size))\n", " tasi.name = \"tas\"\n", " tasi.attrs.update(tas.attrs)\n", " tasi.attrs[\"title\"] = f\"tas of member {i:02d}\"\n", " tasi.to_netcdf(data_folder.joinpath(f\"ens_tas_m{i}.nc\"))\n", "\n", "# Create 'toy' criteria selection data\n", "np.random.normal(loc=3.5, scale=1.5, size=50)\n", "# crit['delta_annual_tavg']\n", "np.random.seed(0)\n", "test = xr.DataArray(np.random.normal(loc=3, scale=1.5, size=100), dims=[\"realization\"]).assign_coords(\n", " horizon=\"2041-2070\"\n", ")\n", "test = xr.concat(\n", " (\n", " test,\n", " xr.DataArray(np.random.normal(loc=5.34, scale=2, size=100), dims=[\"realization\"]).assign_coords(\n", " horizon=\"2071-2100\"\n", " ),\n", " ),\n", " dim=\"horizon\",\n", ")\n", "\n", "ds_crit = xr.Dataset()\n", "\n", "ds_crit[\"delta_annual_tavg\"] = test\n", "test = xr.DataArray(np.random.normal(loc=5, scale=5, size=100), dims=[\"realization\"]).assign_coords(horizon=\"2041-2070\")\n", "test = xr.concat(\n", " (\n", " test,\n", " xr.DataArray(np.random.normal(loc=10, scale=8, size=100), dims=[\"realization\"]).assign_coords(\n", " horizon=\"2071-2100\"\n", " ),\n", " ),\n", " dim=\"horizon\",\n", ")\n", "ds_crit[\"delta_annual_prtot\"] = test\n", "test = xr.DataArray(np.random.normal(loc=0, scale=3, size=100), dims=[\"realization\"]).assign_coords(horizon=\"2041-2070\")\n", "test = xr.concat(\n", " (\n", " test,\n", " xr.DataArray(np.random.normal(loc=2, scale=4, size=100), dims=[\"realization\"]).assign_coords(\n", " horizon=\"2071-2100\"\n", " ),\n", " ),\n", " dim=\"horizon\",\n", ")\n", "ds_crit[\"delta_JJA_prtot\"] = test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ensembles\n", "=========\n", "\n", "An important aspect of climate models is that they are run multiple times with some initial perturbations to see how they replicate the natural variability of the climate. Through [xclim.ensembles](../api.rst#ensembles-module), xclim provides an easy interface to compute ensemble statistics on different members. Most methods perform checks and conversion on top of simpler `xarray` methods, providing an easier interface to use.\n", "\n", "### create_ensemble\n", "Our first step is to create an ensemble. This method takes a list of files defining the same variables over the same coordinates and concatenates them into one dataset with an added dimension `realization`.\n", "\n", "Using `xarray` a very simple way of creating an ensemble dataset would be :\n", "```python\n", "import xarray\n", "\n", "xarray.open_mfdataset(files, concat_dim='realization')\n", "```\n", "\n", "However, this is only successful when the dimensions of all the files are identical AND only if the calendar type of each netcdf file is the same\n", "\n", "xclim's `create_ensemble()` method overcomes these constraints, selecting the common time period to all files and assigns a standard calendar type to the dataset.\n", "\n", "