Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ updates:
directory: "/"
schedule:
interval: "weekly"
reviewers:
- "btschwertfeger"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
reviewers:
- "btschwertfeger"
ignore:
- dependency-name: "ruff"
2 changes: 1 addition & 1 deletion .github/workflows/_codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run: python -m pip install --upgrade pip

- name: Install package
run: python -m pip install ".[dev]"
run: python -m pip install ".[dev,test]"

- name: Generate coverage report
run: pytest --cov --cov-report=xml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
python -m pip install --upgrade pip

- name: Install package
run: python -m pip install ".[dev]"
run: python -m pip install ".[dev,test]"

- name: Run unit tests
run: pytest -vv tests
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.2
rev: v0.3.5
hooks:
- id: ruff
args:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ build:
.PHONY: dev
dev:
@git lfs install
$(PYTHON) -m pip install -e ".[dev]"
$(PYTHON) -m pip install -e ".[dev,test]"

## install Install the package
##
Expand Down
61 changes: 59 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Welcome to python-cmethods, a powerful Python package designed for bias
correction and adjustment of climate data. Built with a focus on ease of use and
efficiency, python-cmethods offers a comprehensive suite of functions tailored
for applying bias correction methods to climate model simulations and
observational datasets.
observational datasets via command-line interface and API.

Please cite this project as described in
https://zenodo.org/doi/10.5281/zenodo.7652755.
Expand Down Expand Up @@ -143,7 +143,64 @@ python3 -m pip install python-cmethods

<a name="examples"></a>

## 4. Usage and Examples
## 4. CLI Usage

The python-cmethods package provides a command-line interface for applying
various bias correction methods out of the box.

Keep in mind that due to the various kinds of data and possibilities to
pre-process those, the CLI only provides a basic application of the implemented
techniques. For special parameters, adjustments, and data preparation, please
use programming interface.

Listing the parameters and their requirements is available by passing the
`--help` option:

```bash
cmethods --help
```

Applying the cmethods tool on the provided example data using the linear scaling
approach is shown below:

```bash
cmethods \
--obs examples/input_data/observations.nc \
--simh examples/input_data/control.nc \
--simp examples/input_data/scenario.nc \
--method linear_scaling \
--kind add \
--variable tas \
--group time.month \
--output linear_scaling.nc

2024/04/08 18:11:12 INFO | Loading data sets ...
2024/04/08 18:11:12 INFO | Data sets loaded ...
2024/04/08 18:11:12 INFO | Applying linear_scaling ...
2024/04/08 18:11:15 INFO | Saving result to linear_scaling.nc ...
```

For applying a distribution-based bias correction technique, the following
example may help:

```bash
cmethods \
--obs examples/input_data/observations.nc \
--simh examples/input_data/control.nc \
--simp examples/input_data/scenario.nc \
--method quantile_delta_mapping \
--kind add \
--variable tas \
--quantiles 1000 \
--output quantile_delta_mapping.nc

2024/04/08 18:16:34 INFO | Loading data sets ...
2024/04/08 18:16:35 INFO | Data sets loaded ...
2024/04/08 18:16:35 INFO | Applying quantile_delta_mapping ...
2024/04/08 18:16:35 INFO | Saving result to quantile_delta_mapping.nc ...
```

## 5. Programming Interface Usage and Examples

```python
import xarray as xr
Expand Down
171 changes: 165 additions & 6 deletions cmethods/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright (C) 2023 Benjamin Thomas Schwertfeger
# GitHub: https://github.com/btschwertfeger
#
# pylint: disable=consider-using-f-string,logging-not-lazy

r"""
Module providing the a method named "adjust" to apply different bias
Expand All @@ -24,12 +25,170 @@
_{m} = long-term monthly interval
"""

from cmethods.core import adjust
from __future__ import annotations

import logging
import sys

__author__ = "Benjamin Thomas Schwertfeger"
__copyright__ = __author__
__email__ = "contact@b-schwertfeger.de"
__link__ = "https://github.com/btschwertfeger"
__github__ = "https://github.com/btschwertfeger/python-cmethods"
import cloup
import xarray as xr
from cloup import (
HelpFormatter,
HelpTheme,
Path,
Style,
command,
option,
option_group,
version_option,
)
from cloup.constraints import Equal, If, require_all

from cmethods.core import adjust

__all__ = ["adjust"]


@command(
context_settings={
"auto_envvar_prefix": "CMETHODS",
"help_option_names": ["-h", "--help"],
},
formatter_settings=HelpFormatter.settings(
theme=HelpTheme(
invoked_command=Style(fg="bright_yellow"),
heading=Style(fg="bright_white", bold=True),
constraint=Style(fg="magenta"),
col1=Style(fg="bright_yellow"),
),
),
)
@version_option(message="%version%")
@option(
"--obs",
"--observations",
required=True,
type=Path(exists=True),
help="Reference data set (control period)",
)
@option(
"--simh",
"--simulated-historical",
required=True,
type=Path(exists=True),
help="Modeled data set (control period)",
)
@option(
"--simp",
"--simulated-scenario",
required=True,
type=Path(exists=True),
help="Modeled data set (scenario period)",
)
@option(
"--method",
required=True,
type=cloup.Choice(
[
"linear_scaling",
"variance_scaling",
"delta_method",
"quantile_mapping",
"quantile_delta_mapping",
],
case_sensitive=False,
),
help="Bias adjustment method to apply",
)
@option(
"--kind",
required=True,
type=cloup.Choice(["+", "add", "*", "mult"]),
help="Kind of adjustment",
)
@option(
"--variable",
required=True,
type=str,
help="Variable of interest",
)
@option(
"-o",
"--output",
required=True,
type=str,
callback=lambda _, __, value: (value if value.endswith(".nc") else f"{value}.nc"),
help="Output file name",
)
@option_group(
"Scaling-Based Adjustment Options",
option(
"--group",
type=str,
help="Temporal grouping",
),
constraint=If(
Equal("method", "linear_scaling")
& Equal("method", "variance_scaling")
& Equal("method", "delta_method"),
then=require_all,
),
)
@option_group(
"Distribution-Based Adjustment Options",
option(
"--quantiles",
type=int,
help="Quantiles to respect",
),
constraint=If(
Equal("method", "quantile_mapping") & Equal("method", "quantile_delta_mapping"),
then=require_all,
),
)
def cli(**kwargs) -> None:
"""
Command-line tool to apply bias correction procedures to climate data.

Copyright (C) 2023 Benjamin Thomas Schwertfeger\n
GitHub: https://github.com/btschwertfeger/python-cmethods
"""

logging.basicConfig(
format="%(asctime)s %(levelname)8s | %(message)s",
datefmt="%Y/%m/%d %H:%M:%S",
level=logging.INFO,
)

logging.info("Loading data sets ...")
try:
for key, message in zip(
("obs", "simh", "simp"),
(
"observation data set",
"modeled data set of the control period",
"modeled data set of the scenario period",
),
):
kwargs[key] = xr.open_dataset(kwargs[key])
if not isinstance(kwargs[key], xr.Dataset):
raise TypeError("The data sets must be type xarray.Dataset")

if kwargs["variable"] not in kwargs[key]:
raise KeyError(
f"Variable '{kwargs['variable']}' is missing in the {message}",
)
kwargs[key] = kwargs[key][kwargs["variable"]]
except (TypeError, KeyError) as exc:
logging.error(exc)
sys.exit(1)

logging.info("Data sets loaded ...")
kwargs["n_quantiles"] = kwargs["quantiles"]
del kwargs["quantiles"]

logging.info("Applying %s ..." % kwargs["method"])
result = adjust(**kwargs)

logging.info("Saving result to %s ..." % kwargs["output"])
result.to_netcdf(kwargs["output"])
41 changes: 41 additions & 0 deletions doc/cli.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.. -*- coding: utf-8 -*-
.. Copyright (C) 2023 Benjamin Thomas Schwertfeger
.. GitHub: https://github.com/btschwertfeger
..

Command-Line Interface
======================

The command-line interface provides the following help instructions

.. code-block:: bash

cmethods --help

Usage: cmethods [OPTIONS]

Command line tool to apply bias adjustment procedures to climate data.

Scaling-Based Adjustment Options:
[all required if --method="linear_scaling" and --method="variance_scaling" and
--method="delta_method"]
--group TEXT Temporal grouping

Distribution-Based Adjustment Options:
[all required if --method="quantile_mapping" and
--method="quantile_delta_mapping"]
--quantiles INTEGER Quantiles to respect

Other options:
--version Show the version and exit.
--obs, --observations PATH Reference data set (control period) [required]
--simh, --simulated-historical PATH
Modeled data set (control period) [required]
--simp, --simulated-scenario PATH
Modeled data set (scenario period) [required]
--method [linear_scaling|variance_scaling|delta_method|quantile_mapping|quantile_delta_mapping]
Bias adjustment method to apply [required]
--kind [add|mult] Kind of adjustment [required]
--variable TEXT Variable of interest [required]
-o, --output TEXT Output file name [required]
-h, --help Show this message and exit.
4 changes: 4 additions & 0 deletions doc/cmethods.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.. -*- coding: utf-8 -*-
.. Copyright (C) 2023 Benjamin Thomas Schwertfeger
.. GitHub: https://github.com/btschwertfeger
..

Classes and Functions
=====================
Expand Down
Loading