Thank you for your interest in contributing.
git clone https://github.com/northflow-technologies/climval
cd climval
pip install -e ".[dev]"pytest # all tests
pytest tests/ -v # verbose
pytest --cov=climval # with coverage- Ruff for linting:
ruff check climval/ - Mypy for types:
mypy climval/ - All public functions must have docstrings
- All new metrics must have at least one unit test with a known analytical value
- All new code must be covered ≥ 90%
- Subclass
BaseMetricinclimval/metrics/stats.py - Set
name,higher_is_better - Implement
compute(reference, candidate, weights=None) -> float - Register it in
METRIC_REGISTRY - Add a test in
tests/test_benchmark.pywith a known analytical value
class KGE(BaseMetric):
"""Kling-Gupta Efficiency."""
name = "kge"
higher_is_better = True
def compute(self, reference, candidate, weights=None):
r = np.corrcoef(reference, candidate)[0, 1]
alpha = np.std(candidate) / np.std(reference)
beta = np.mean(candidate) / np.mean(reference)
return float(1 - np.sqrt((r - 1)**2 + (alpha - 1)**2 + (beta - 1)**2))Add a new entry to _PRESETS in climval/core/loader.py:
"my-model": {
"model_type": ModelType.GCM,
"spatial_resolution": SpatialResolution.MEDIUM,
"temporal_resolution": TemporalResolution.MONTHLY,
"description": "My model description",
},- Tests pass (
pytest) - Linting passes (
ruff check .) - Type checks pass (
mypy climval/) - Docstrings added for new public API
- CHANGELOG.md updated
We follow Conventional Commits:
feat: add Kling-Gupta Efficiency metric
fix: correct weighted RMSE normalization
docs: add NetCDF loading example
test: add TSS unit test with known value