Skip to content

Commit

Permalink
Update doc for custom missing methods (#2076)
Browse files Browse the repository at this point in the history
### What kind of change does this PR introduce?

I had completely forgotten that we had a section explaining how to
create custom missing methods! This updates the notebook with the new
way of doing things, but also adds a warning because this is still
experimental.

### Does this PR introduce a breaking change?
No.
  • Loading branch information
Zeitsperre authored Feb 12, 2025
2 parents 2a44a74 + 78f8e76 commit a912e8a
Showing 1 changed file with 30 additions and 8 deletions.
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

0 comments on commit a912e8a

Please sign in to comment.