Skip to content

Commit

Permalink
applied suggestions by @riley-brady
Browse files Browse the repository at this point in the history
  • Loading branch information
btschwertfeger committed Jan 20, 2024
1 parent 5bdd0e4 commit 903eebb
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 60 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ on:
push:
branches:
- "**"
schedule:
- cron: "20 4 * * 0"

concurrency:
group: CICD-${{ github.ref }}
Expand All @@ -37,7 +39,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
Expand All @@ -59,7 +61,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version: ["3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
Expand All @@ -51,7 +51,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
Expand Down
47 changes: 16 additions & 31 deletions cmethods/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#

r"""
Module to apply different bias correction techniques to time-series climate data
Module to apply different bias correction techniques to time-series
climate data.
T = Temperatures ($T$)
X = Some climate variable ($X$)
Expand All @@ -23,7 +24,7 @@

from __future__ import annotations

from typing import Any, Callable, Optional
from typing import Any, Callable, List, Optional, Tuple, Union

import numpy as np
import xarray as xr
Expand Down Expand Up @@ -92,7 +93,7 @@ class CMethods:
due to complex atmospheric and meteorological processes.
"""

MAX_SCALING_FACTOR: int | float = 10
MAX_SCALING_FACTOR: Union[int, float] = 10

# ? -----========= L I N E A R - S C A L I N G =========------
def linear_scaling(
Expand Down Expand Up @@ -442,7 +443,7 @@ def adjust(
self: CMethods, method: str, obs: XRData, simh: XRData, simp: XRData, **kwargs
) -> XRData:
"""
Function to apply a bias correction technique on 1-and 3-dimensional
Function to apply a bias correction technique on 1-and multidimensional
data sets. For more information please refer to the method specific
requirements and execution examples.
Expand Down Expand Up @@ -472,6 +473,10 @@ def adjust(
)

# No grouped correction | distribution-based technique
# NOTE: This is disabled since using groups like "time.month" will lead
# to unrealistic monthly transitions. If such behavior is wanted,
# mock this function or apply ``CMethods.__apply_ufunc` directly
# on your data sets.
if kwargs.get("group", None) is None:
return self.__apply_ufunc(method, obs, simh, simp, **kwargs).to_dataset()

Expand All @@ -484,9 +489,9 @@ def adjust(
group: str = kwargs["group"]
del kwargs["group"]

obs_g: list[tuple[int, XRData]] = list(obs.groupby(group))
simh_g: list[tuple[int, XRData]] = list(simh.groupby(group))
simp_g: list[tuple[int, XRData]] = list(simp.groupby(group))
obs_g: List[Tuple[int, XRData]] = list(obs.groupby(group))
simh_g: List[Tuple[int, XRData]] = list(simh.groupby(group))
simp_g: List[Tuple[int, XRData]] = list(simp.groupby(group))

result: Optional[XRData] = None
for index in range(len(list(obs_g))):
Expand All @@ -505,28 +510,6 @@ def adjust(

return result

def __get_function(self: CMethods, method: str) -> Callable:
"""
Returns the bias correction function corresponding to the ``method`` name.
:param method: The method name to get the function for
:type method: str
:raises UnknownMethodError: If the function is not implemented
:return: The function of the corresponding method
:rtype: function
"""
if method == "linear_scaling":
return self.linear_scaling
if method == "variance_scaling":
return self.variance_scaling
if method == "delta_method":
return self.delta_method
if method == "quantile_mapping":
return self.quantile_mapping
if method == "quantile_delta_mapping":
return self.quantile_delta_mapping
raise UnknownMethodError(method, METHODS)

def __apply_ufunc(
self: CMethods,
method: str,
Expand All @@ -536,9 +519,11 @@ def __apply_ufunc(
**kwargs: dict,
) -> XRData:
check_xr_types(obs=obs, simh=simh, simp=simp)
if method not in METHODS:
raise UnknownMethodError(method, METHODS)

result: XRData = xr.apply_ufunc(
self.__get_function(method),
getattr(self, method),
obs,
simh,
# Need to spoof a fake time axis since 'time' coord on full dataset is different
Expand All @@ -562,7 +547,7 @@ def __apply_ufunc(
# order where time is commonly first.
return result.transpose(*obs.dims)

def get_available_methods(self: CMethods) -> list[str]:
def get_available_methods(self: CMethods) -> List[str]:
"""
Function to return the available adjustment methods of the CMethods class.
Expand Down
11 changes: 6 additions & 5 deletions cmethods/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@

"""Module providing static information for the python-cmethods package"""

from typing import List

SCALING_METHODS: list[str] = ["linear_scaling", "variance_scaling", "delta_method"]
SCALING_METHODS: List[str] = ["linear_scaling", "variance_scaling", "delta_method"]
DISTRIBUTION_METHODS: list[str] = [
"quantile_mapping",
"detrended_quantile_mapping",
"quantile_delta_mapping",
]

CUSTOM_METHODS: list[str] = SCALING_METHODS + DISTRIBUTION_METHODS
METHODS: list[str] = CUSTOM_METHODS
CUSTOM_METHODS: List[str] = SCALING_METHODS + DISTRIBUTION_METHODS
METHODS: List[str] = CUSTOM_METHODS

ADDITIVE: list[str] = ["+", "add"]
MULTIPLICATIVE: list[str] = ["*", "mult"]
ADDITIVE: List[str] = ["+", "add"]
MULTIPLICATIVE: List[str] = ["*", "mult"]
25 changes: 16 additions & 9 deletions cmethods/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from __future__ import annotations

import warnings
from typing import Optional
from typing import Optional, Union

import numpy as np

Expand Down Expand Up @@ -96,8 +96,8 @@ def nan_or_equal(value1: float, value2: float) -> bool:


def ensure_devidable(
numerator: float | np.ndarray,
denominator: float | np.ndarray,
numerator: Union[float, np.ndarray],
denominator: Union[float, np.ndarray],
max_scaling_factor: float,
) -> np.ndarray:
"""
Expand Down Expand Up @@ -128,7 +128,10 @@ def ensure_devidable(
return result


def get_pdf(x: list | np.ndarray, xbins: list | np.ndarray) -> np.ndarray:
def get_pdf(
x: Union[list, np.ndarray],
xbins: Union[list, np.ndarray],
) -> np.ndarray:
r"""
Compuites and returns the the probability density function :math:`P(x)`
of ``x`` based on ``xbins``.
Expand All @@ -155,7 +158,10 @@ def get_pdf(x: list | np.ndarray, xbins: list | np.ndarray) -> np.ndarray:
return pdf


def get_cdf(x: list | np.ndarray, xbins: list | np.ndarray) -> np.ndarray:
def get_cdf(
x: Union[list, np.ndarray],
xbins: Union[list, np.ndarray],
) -> np.ndarray:
r"""
Computes and returns returns the cumulative distribution function :math:`F(x)`
of ``x`` based on ``xbins``.
Expand Down Expand Up @@ -184,9 +190,9 @@ def get_cdf(x: list | np.ndarray, xbins: list | np.ndarray) -> np.ndarray:


def get_inverse_of_cdf(
base_cdf: list | np.ndarray,
insert_cdf: list | np.ndarray,
xbins: list | np.ndarray,
base_cdf: Union[list, np.ndarray],
insert_cdf: Union[list, np.ndarray],
xbins: Union[list, np.ndarray],
) -> np.ndarray:
r"""
Returns the inverse cumulative distribution function as:
Expand All @@ -206,7 +212,8 @@ def get_inverse_of_cdf(


def get_adjusted_scaling_factor(
factor: int | float, max_scaling_factor: int | float
factor: Union[int, float],
max_scaling_factor: Union[int, float],
) -> float:
r"""
Returns:
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ authors = [
description = "Collection of bias correction procedures for single and multidimensional climate data"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.11"
requires-python = ">=3.8"
dependencies = ["xarray>=2022.11.0", "netCDF4>=1.6.1", "numpy"]
keywords = [
"climate-science",
Expand All @@ -30,7 +30,11 @@ keywords = [
classifiers = [
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Programming Language :: Python",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Natural Language :: English",
"Operating System :: MacOS",
"Operating System :: Unix",
Expand Down
10 changes: 5 additions & 5 deletions tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from __future__ import annotations

from typing import List

import numpy as np
import xarray as xr
from sklearn.metrics import mean_squared_error
Expand Down Expand Up @@ -45,9 +47,7 @@ def is_3d_rmse_better(result, obsp, simp) -> bool:
return (rmse_values_new_ds < rmse_values_old_ds).all()


def get_datasets(
kind: str,
) -> tuple[xr.Dataset, xr.Dataset, xr.Dataset, xr.Dataset]:
def get_datasets(kind: str) -> tuple[xr.Dataset, xr.Dataset, xr.Dataset, xr.Dataset]:
historical_time = xr.cftime_range(
"1971-01-01", "2000-12-31", freq="D", calendar="noleap"
)
Expand All @@ -56,7 +56,7 @@ def get_datasets(
)
latitudes = np.arange(23, 27, 1)

def get_hist_temp_for_lat(lat: int) -> list[float]:
def get_hist_temp_for_lat(lat: int) -> List[float]:
"""Returns a fake interval time series by latitude value"""
return 273.15 - (
lat * np.cos(2 * np.pi * historical_time.dayofyear / 365)
Expand All @@ -65,7 +65,7 @@ def get_hist_temp_for_lat(lat: int) -> list[float]:
+ 0.1 * (historical_time - historical_time[0]).days / 365
)

def get_fake_hist_precipitation_data() -> list[float]:
def get_fake_hist_precipitation_data() -> List[float]:
"""Returns ratio based fake time series"""
pr = (
np.cos(2 * np.pi * historical_time.dayofyear / 365)
Expand Down
5 changes: 0 additions & 5 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,3 @@ def test_adjust_failing_no_group_for_distribution(cm: CMethods, datasets: dict)
n_quantiles=100,
group="time.month",
)


def test_get_function_unknown_method(cm: CMethods) -> None:
with pytest.raises(UnknownMethodError):
cm._CMethods__get_function("not-existing")

0 comments on commit 903eebb

Please sign in to comment.