Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 0 additions & 2 deletions .github/workflows/cd-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: cd

on:
push:
tags:
- '**'

jobs:
pypi:
uses: ecmwf/reusable-workflows/.github/workflows/cd-pypi.yml@v2
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/cd-test-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: test-cd

on:
pull_request:
branches: ["main"]

jobs:
pypi:
uses: ecmwf/reusable-workflows/.github/workflows/cd-pypi.yml@v2
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/label-public-pr.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Manage labels of pull requests that originate from forks
name: label-public-pr

on:
pull_request_target:
types: [opened, synchronize]

jobs:
label:
uses: ecmwf/reusable-workflows/.github/workflows/label-pr.yml@v2
3 changes: 0 additions & 3 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
name: Quality assurance

on:
push:
branches: ["main", "develop"]
pull_request:
branches: ["main", "develop"]
types: [opened, synchronize, reopened]

jobs:
pre-commit:
uses: ecmwf/reusable-workflows/.github/workflows/qa-precommit-run.yml@v2
with:
skip-hooks: "no-commit-to-branch"

tests:
strategy:
matrix:
Expand Down
9 changes: 7 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ repos:
- id: no-commit-to-branch
args: [--branch, main]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.2
rev: v0.15.4
hooks:
- id: ruff-check
args: [--fix, --show-fixes]
exclude: '(dev/.*|.*_)\.py$'
args:
- --line-length=120
- --fix
- --exit-non-zero-on-fix
- --preview
- id: ruff-format
- repo: https://github.com/executablebooks/mdformat
rev: 1.0.0
Expand Down
3 changes: 0 additions & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

version: 2

build:
os: ubuntu-24.04
tools:
python: "3.12"

python:
install:
- method: pip
path: .
extra_requirements:
- docs

sphinx:
configuration: docs/conf.py
5 changes: 1 addition & 4 deletions docs/notebooks/climate_indices_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@
"import earthkit.plots as ekp\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from earthkit.climate.indicators.precipitation import (\n",
" daily_precipitation_intensity,\n",
" maximum_consecutive_wet_days,\n",
")\n",
"from earthkit.climate.indicators.precipitation import daily_precipitation_intensity, maximum_consecutive_wet_days\n",
"from earthkit.climate.indicators.temperature import (\n",
" daily_temperature_range,\n",
" heating_degree_days,\n",
Expand Down
8 changes: 2 additions & 6 deletions docs/notebooks/performance_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -556,9 +556,7 @@
"import xarray as xr\n",
"\n",
"\n",
"def run_climate_indicator(\n",
" func: Callable[..., Any], kwargs: Dict[str, Any], use_flox: Optional[bool] = None\n",
") -> Any:\n",
"def run_climate_indicator(func: Callable[..., Any], kwargs: Dict[str, Any], use_flox: Optional[bool] = None) -> Any:\n",
" \"\"\"\n",
" Unified execution wrapper for climate indicator functions with configurable backend options.\n",
"\n",
Expand Down Expand Up @@ -1493,9 +1491,7 @@
" # Let's double check the user intent. Usually Xclim NoFlox is the \"base\" reference.\n",
" # The original code searched for Library='Xclim'. We stick to that.\n",
" baseline_row = df_res.loc[\n",
" (df_res[\"Indicator\"] == indicator)\n",
" & (df_res[\"Library\"] == \"Xclim\")\n",
" & (df_res[\"Mode\"] == baseline_mode)\n",
" (df_res[\"Indicator\"] == indicator) & (df_res[\"Library\"] == \"Xclim\") & (df_res[\"Mode\"] == baseline_mode)\n",
" ]\n",
"\n",
" if not baseline_row.empty:\n",
Expand Down
43 changes: 18 additions & 25 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools>=65", "wheel", "setuptools-scm>=8"]
requires = ["setuptools>=65", "setuptools-scm>=8", "wheel"]

[project]
authors = [
Expand All @@ -17,40 +17,37 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering"
]
dependencies = [
"earthkit-data>=0.17.0",
"earthkit-data>=0.17",
"numpy>=1.22",
"xarray>=2023.1",
"xclim>=0.59.1",
"xsdba>=0.5,<0.6"
]
description = "Tools for calculating climate indicies, climate change analysis and attribution."
dynamic = ["version", "readme"]
dynamic = ["readme", "version"]
license = {file = "LICENSE"}
name = "earthkit-climate"
requires-python = ">=3.10"

[project.optional-dependencies]
dev = [
optional-dependencies.dev = [
"black",
"ruff",
"ipykernel",
"ipython",
"mypy",
"pre-commit",
"ipython",
"pytest",
"pytest-cov",
"pytest-mock",
"ipykernel"
"ruff"
]
docs = [
optional-dependencies.docs = [
"furo",
"nbsphinx",
"roman-numerals-py>=3.1.0,<4",
"roman-numerals-py>=3.1,<4",
"sphinx",
"sphinx-autoapi",
"furo"
"sphinx-autoapi"
]

[tool.coverage.run]
Expand All @@ -60,10 +57,8 @@ branch = true
addopts = "-vv --cov=. --cov-report=html --doctest-glob='*.md' --doctest-glob='*.rst'"

[tool.ruff]
line-length = 110

[tool.ruff.lint]
ignore = [
line-length = 120
lint.ignore = [
"D1", # pydocstyle: Missing Docstrings
"D107", # pydocstyle: numpy convention
"D203",
Expand All @@ -77,16 +72,14 @@ ignore = [
"D416",
"D417"
]
select = [
"F", # pyflakes
lint.select = [
"D", # pydocstyle
"E", # pycodestyle
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"D" # pydocstyle
"W" # pycodestyle warnings
]

[tool.ruff.lint.per-file-ignores]
"docs/conf.py" = [
lint.per-file-ignores."docs/conf.py" = [
"E501" # line too long
]

Expand Down
4 changes: 1 addition & 3 deletions src/earthkit/climate/utils/percentile.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ def custom_percentile(group: DataArray) -> DataArray:
expanded = ref_da.groupby(f"time.{time_component}").map(
lambda group: xr.full_like(
group,
ds_percentile[varname].sel(
{time_component: getattr(group.time.dt, time_component)[0].item()}
),
ds_percentile[varname].sel({time_component: getattr(group.time.dt, time_component)[0].item()}),
float,
)
)
Expand Down
8 changes: 2 additions & 6 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
@pytest.fixture
def dummy_precip_ds() -> xr.Dataset:
"""Simple constant precipitation dataset."""
time = xr.cftime_range(
start="2001-01-01", end="2001-01-10", freq="D", calendar="noleap"
).to_datetimeindex()
time = xr.cftime_range(start="2001-01-01", end="2001-01-10", freq="D", calendar="noleap").to_datetimeindex()
ds = xr.Dataset(
{"pr": ("time", [1.0] * len(time))},
coords={"time": time},
Expand Down Expand Up @@ -48,9 +46,7 @@ def dummy_temp_ds() -> xr.Dataset:
def daily_temperature_ds() -> xr.Dataset:
"""Synthetic daily temperature dataset for percentile and grouping tests."""
rng = np.random.default_rng(0)
time = xr.cftime_range(
start="2000-01-01", end="2001-12-31", freq="D", calendar="noleap"
).to_datetimeindex()
time = xr.cftime_range(start="2000-01-01", end="2001-12-31", freq="D", calendar="noleap").to_datetimeindex()
data = rng.normal(loc=10.0, scale=2.0, size=time.size)
ds = xr.Dataset({"tas": ("time", data)}, coords={"time": time})
return ds
Expand Down
5 changes: 1 addition & 4 deletions tests/unit/utils/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
import xarray as xr
from earthkit.data.wrappers.xarray import XArrayDatasetWrapper

from earthkit.climate.utils.conversions import (
to_earthkit_field,
to_xarray_dataset,
)
from earthkit.climate.utils.conversions import to_earthkit_field, to_xarray_dataset


@pytest.mark.parametrize(
Expand Down
12 changes: 3 additions & 9 deletions tools/xclim_wrappers_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,12 @@ def generate_module_content(category: str, indicators: List[Any]) -> str:

# Indent the docstring correctly
lines = docstring.split("\n")
indented_doc = (
lines[0] + "\n" + "\n".join([(" " + line if line.strip() else "") for line in lines[1:]])
)
indented_doc = lines[0] + "\n" + "\n".join([(" " + line if line.strip() else "") for line in lines[1:]])

code = FUNCTION_TEMPLATE.format(
func_name=func_name, xclim_func_name=xclim_func_name, docstring=indented_doc
)
code = FUNCTION_TEMPLATE.format(func_name=func_name, xclim_func_name=xclim_func_name, docstring=indented_doc)
functions_code.append(code)

return MODULE_TEMPLATE.format(
category_title=category.capitalize(), functions_code="".join(functions_code)
)
return MODULE_TEMPLATE.format(category_title=category.capitalize(), functions_code="".join(functions_code))


def main():
Expand Down
Loading