{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "nbsphinx": "hidden", "tags": [] }, "outputs": [], "source": [ "# Workaround for determining the notebook folder within a running notebook\n", "# This cell is not visible when the documentation is built.\n", "\n", "from __future__ import annotations # noqa: F404\n", "\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()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Extending xclim\n", "\n", "`xclim` tries to make it easy for users to add their own indices and indicators. The following goes into details on how to create `**Indices**` and document them so that xclim can parse most of the metadata directly. We then explain the multiple ways new `**Indicators**` can be created and, finally, how we can regroup and structure them in virtual submodules.\n", "\n", "Central to `xclim` are the **Indicators**, objects computing indices over climate variables, but `xclim` also provides many other modules:\n", "\n", "\n", "\n", "This introduction will focus on the Indicator/Index part of `xclim` and how one can extend it by implementing new ones.\n", "\n", "## Indices vs Indicators\n", "\n", "Internally and in the documentation, `xclim` makes a distinction between \"indices\" and \"indicators\".\n", "\n", "### index\n", "\n", " * A python function accepting DataArrays and other parameters (usually built-in types)\n", " * Returns one or several DataArrays.\n", " * Handles the units : checks input units and set proper CF-compliant output units. But doesn't usually prescribe specific units, the output will at minimum have the proper dimensionality.\n", " * Performs **no** other checks or set any (non-unit) metadata.\n", " * Accessible through [xclim.indices](../indices.rst).\n", "\n", "### indicator\n", "\n", " * An instance of a subclass of `xclim.core.indicator.Indicator` that wraps around an `index` (stored in its `compute` property).\n", " * Returns one or several DataArrays.\n", " * Handles missing values, performs input data and metadata checks (see [usage](usage.ipynb#indicators)).\n", " * Always outputs data in the same units.\n", " * Adds dynamically generated metadata to the output after computation.\n", " * Accessible through [xclim.indicators](../indicators.rst)\n", "\n", "Most metadata stored in the Indicators is parsed from the underlying index documentation, so defining indices with complete documentation and an appropriate signature helps the process. The two next sections go into details on the definition of both objects.\n", "\n", "#### Call sequence\n", "\n", "The following graph shows the steps done when calling an Indicator. Attributes and methods of the Indicator object relating to those steps are listed on the right side.\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Defining new indices\n", "\n", "The annotated example below shows the general template to be followed when defining proper _indices_. In the comments, `Ind` is the indicator instance that would be created from this function.\n", "\n", "