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
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
8 changes: 6 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ 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
- 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
45 changes: 19 additions & 26 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,36 @@ 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 = [
"black",
"ruff",
optional-dependencies.dev = [
"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 +56,9 @@ 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
preview = true
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