Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update doc for custom missing methods #2076

Merged
merged 5 commits into from
Feb 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions docs/notebooks/customize.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,23 @@
"source": [
"This method checks that there are less than `nm=11` invalid values in a month and that there are no consecutive runs of `nc>=5` invalid values. Thus, every month is now valid.\n",
"\n",
"Finally, it is possible for advanced users to register their own method. Xclim's missing methods are in fact based on class instances. Thus, to create a custom missing class, one should implement a subclass based on `xclim.core.checks.MissingBase` and overriding at least the `is_missing` method. The method should take a `null` argument and a `count` argument.\n",
"<div class=\"alert alert-warning\">\n",
"\n",
"- `null` is a `DataArrayResample` instance of the resampled mask of invalid values in the input data array.\n",
"- `count` is the number of days in each resampled periods and any number of other keyword arguments.\n",
"The content that follows is based on an experimental part of xclim, the way missing methods are implemented might change in the near future. Access of missing methods as functions of ``xclim.core.missing`` and usage of these algorithms in the indicators will be preserved, but custom subclasses might break with future changes.\n",
"\n",
"The `is_missing` method should return a boolean mask, at the same frequency as the indicator output (same as `count`), where True values are for elements that are considered missing and masked on the output.\n",
"</div>\n",
"\n",
"When registering the class with the `xclim.core.checks.register_missing_method` decorator, the keyword arguments will be registered as options for the missing method. One can also implement a `validate` static method that receives only those options and returns whether they should be considered valid or not."
"Finally, it is possible for advanced users to register their own methods. Xclim's missing methods are in fact class-based. To create a custom missing class, one should implement a subclass of `xclim.core.checks.MissingBase` and override at least the `is_missing` method. This method should take the following arguments:\n",
"\n",
"- `null`, a `DataArray` of the mask of invalid values in the input data array (with the same time coordinate as the raw data).\n",
"- `count`, `DataArray` of the number of days in each resampled periods\n",
"- `freq`, the resampling frequency.\n",
"\n",
"The `is_missing` method should return a boolean mask, resampled at the `freq` frequency, the same as the indicator output (same as `count`), where `True` values are for elements that are considered missing and masked on the output.\n",
"\n",
"To add additional arguments, one should override the `__init__` (receiving those arguments) and the `validate` static method, which validates them. The options are then stored in the `options` property of the instance. See example below and the docstrings in the module.\n",
"\n",
"When registering the class with the `xclim.core.checks.register_missing_method` decorator, the keyword arguments will be registered as options for the missing method. "
]
},
{
Expand All @@ -173,9 +182,15 @@
"class MissingConsecutive(MissingBase):\n",
" \"\"\"Any period with more than max_n consecutive missing values is considered invalid\"\"\"\n",
"\n",
" def is_missing(self, null, count, max_n=5):\n",
" def __init__(self, max_n: int = 5):\n",
" super().__init__(max_n=max_n)\n",
"\n",
" def is_missing(self, null, count, freq):\n",
" \"\"\"Return a boolean mask where True values are for elements that are considered missing and masked on the output.\"\"\"\n",
" return null.map(longest_run, dim=\"time\") >= max_n\n",
" return (\n",
" null.resample(time=freq).map(longest_run, dim=\"time\")\n",
" >= self.options[\"max_n\"]\n",
" )\n",
"\n",
" @staticmethod\n",
" def validate(max_n):\n",
Expand Down Expand Up @@ -204,6 +219,13 @@
" ) # compute monthly max tasmax\n",
"tx_mean.sel(time=\"2013\", lat=75, lon=200)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand All @@ -217,7 +239,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
"version": "3.12.7"
}
},
"nbformat": 4,
Expand Down
Loading