Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update xclim #414

Merged
merged 44 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ede3f1a
remove requests code
Zeitsperre Sep 30, 2024
3c211d7
WIP - first stab at modernizing finch
Zeitsperre Sep 30, 2024
1d5d12a
Merge branch 'master' into update-xclim
Zeitsperre Oct 29, 2024
36959a1
Avoid bugs of xclim 0.52
aulemahal Oct 29, 2024
42a9447
Merge branch 'update-xclim' of github.com:bird-house/finch into updat…
aulemahal Oct 29, 2024
b2e625a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
07a149d
Fix more Parameter is not dict - fix Humidex units
aulemahal Oct 29, 2024
0ec4329
Merge branch 'update-xclim' of github.com:bird-house/finch into updat…
aulemahal Oct 29, 2024
f3a6e8e
try to use xscen for spatial_avg
tlogan2000 Oct 29, 2024
6a79eaf
xscen for spatial_avg WIP
tlogan2000 Oct 30, 2024
ad12da7
xscen for spatial_avg WIP
tlogan2000 Oct 30, 2024
61e3222
Merge remote-tracking branch 'origin/update-xclim' into update-xclim
tlogan2000 Oct 30, 2024
57ea742
add xscen to requirements
tlogan2000 Oct 30, 2024
834dc14
tests for spatial averaging with xscen
tlogan2000 Oct 30, 2024
73f506f
small changes
tlogan2000 Oct 31, 2024
11245ad
test spatial avg no percentiles
tlogan2000 Oct 31, 2024
dce2d09
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2024
d211b62
black failure
tlogan2000 Oct 31, 2024
e83ee10
Merge remote-tracking branch 'origin/use_xscen_new' into use_xscen_new
tlogan2000 Oct 31, 2024
dcc340e
black failure
tlogan2000 Oct 31, 2024
00339cc
unpin xscen for now
tlogan2000 Oct 31, 2024
211fd6a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2024
90ec641
fix bbox, history, csv order, skip geomet processes
tlogan2000 Dec 5, 2024
5051539
fix bbox, history, csv order, skip geomet processes
tlogan2000 Dec 5, 2024
192291c
Merge branch 'use_xscen_new' of https://github.com/bird-house/finch i…
tlogan2000 Dec 5, 2024
3a6fec7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 5, 2024
a3da943
re mplement lost bbox fix
tlogan2000 Dec 6, 2024
e2c5314
Merge remote-tracking branch 'origin/use_xscen_new' into use_xscen_new
tlogan2000 Dec 6, 2024
1debaa2
Fix is_opendap - pin xesmf - use pytest for tmp paths
aulemahal Dec 9, 2024
ccd61aa
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 9, 2024
659c149
fix f-string pep8
aulemahal Dec 9, 2024
b716fb1
Merge branch 'use_xscen_new' of github.com:bird-house/finch into use_…
aulemahal Dec 9, 2024
338b37b
drop 3.9, add 3.12
aulemahal Dec 9, 2024
30ac9bb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 9, 2024
93358c6
Merge branch 'master' into update-xclim
Zeitsperre Dec 12, 2024
a0fd763
update changelog
tlogan2000 Dec 12, 2024
330bab0
Use xscen new (#427)
Zeitsperre Dec 12, 2024
a93c18b
Merge branch 'master' into update-xclim
Zeitsperre Dec 16, 2024
a55a3aa
Merge branch 'master' into update-xclim
Zeitsperre Dec 17, 2024
1705fb1
better formatting of YAML, synchronize dependencies
Zeitsperre Dec 17, 2024
143898b
update pandas version
Zeitsperre Dec 17, 2024
411a67b
update xarray version
Zeitsperre Dec 17, 2024
1d99a07
add setuptools
Zeitsperre Dec 17, 2024
8745a29
allow connection to PyPI, fix setuptools version, specify Python3.10+
Zeitsperre Dec 17, 2024
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: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
shell: bash -l {0}
strategy:
matrix:
python-version: [ "3.9", "3.10", "3.11" ] # "3.12"
python-version: [ "3.10", "3.11", "3.12"]
steps:
- name: Harden Runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repos:
rev: v3.17.0
hooks:
- id: pyupgrade
args: [ '--py39-plus' ]
args: [ '--py310-plus' ]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
Expand All @@ -30,7 +30,7 @@ repos:
rev: 24.10.0
hooks:
- id: black
args: [ '--target-version=py39' ]
args: [ '--target-version=py310' ]
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
Expand All @@ -46,10 +46,10 @@ repos:
rev: 1.8.7
hooks:
- id: nbqa-black
args: [ '--target-version=py39' ]
args: [ '--target-version=py310' ]
additional_dependencies: [ 'black==24.8.0' ]
- id: nbqa-pyupgrade
args: [ '--py39-plus' ]
args: [ '--py310-plus' ]
additional_dependencies: [ 'pyupgrade==3.17.0' ]
- id: nbqa-isort
args: [ '--settings-file=setup.cfg' ]
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ v0.13.0 (unreleased)
* Permissions have been set for all workflows.
* Pinned `cf-xarray`` below v0.9.3.
* Reformatted and renamed `CHANGES.rst` to `CHANGELOG.rst`.
* Dropped support for Python 3.8. The supported versions are now Python 3.9, 3.10, and 3.11.
* Dropped support for Python 3.8 and 3.9. The supported versions are now Python 3.10, 3.11 and 3.12.
* `black` has been updated to v2024.8.0, and coding conventions have been updated to Python3.9+.
* Several dependencies now are pinned to baseline versions, including `anyascii`, `dask`, `ipython`, `matplotlib`, `nbsphinx` `numpy`, and `sphinxcontrib-bibtex`.
* Added `xscen` dependency. Now used in spatial averaging of ensemble processes.

v0.12.1 (2024-06-25)
--------------------
Expand Down
4 changes: 2 additions & 2 deletions environment-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: finch
channels:
- conda-forge
dependencies:
- python >=3.8,<3.12
- anyascii >=0.3.2
- python >=3.10,<3.13
- anyascii >=0.3.0
- birdy >=0.8.1
- ipython >=8.0.0
- matplotlib-base >=3.5.0
Expand Down
18 changes: 9 additions & 9 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: finch
channels:
- conda-forge
dependencies:
- python >=3.9,<3.12
- python >=3.9,<3.13
- pip >=24.2.0
- anyascii >=0.3.0
- cftime
- cf_xarray >=0.6.1,<0.9.3
- cftime >=1.4.1
- cf_xarray >=0.9.3
- click >=8.0.0
- clisops >=0.11.0
- dask >=2023.5.1
Expand All @@ -15,16 +15,16 @@ dependencies:
- h5netcdf
- netcdf4 <=1.6.5
- numpy >=1.23.0
- pandas >=1.5.3,<2.2.0
- pandas >=2.2.0
- parse
- psutil
- python-slugify
- pywps >=4.5.1
- pyyaml
- requests>=2.32.2
- pyyaml >=6.0.1
- scipy >=1.9.0
- sentry-sdk
- siphon
- xarray >=2023.01.0,<2023.11.0
- xclim =0.43 # remember to match xclim version in requirements_docs.txt as well
- xesmf >=0.8.2
- xarray >=2023.11.0
- xclim =0.52.2 # remember to match xclim version in requirements_docs.txt as well
- xesmf >=0.8.2,!=0.8.8
- xscen
16 changes: 12 additions & 4 deletions finch/processes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# noqa: D104
import logging
from pathlib import Path

from pywps.configuration import get_config_value
from xclim.core.indicator import registry as xclim_registry
Expand Down Expand Up @@ -52,11 +51,20 @@ def filter_func(elem):

not_implemented = [
"DC",
"E_SAT",
"FWI",
"HURS",
"HURS_FROMDEWPOINT",
"HUSS",
"HUSS_FROMDEWPOINT",
"RH",
"RH_FROMDEWPOINT",
"E_SAT",
"HUSS",
"SPI",
"SPEI",
"WIND_POWER_POTENTIAL",
"WIND_PROFILE",
"WIND_SPEED_FROM_VECTOR",
"WIND_VECTOR_FROM_SPEED",
]


Expand Down Expand Up @@ -135,7 +143,7 @@ def get_processes():
SubsetPolygonProcess(),
AveragePolygonProcess(),
HourlyToDailyProcess(),
GeoseriesToNetcdfProcess(),
# GeoseriesToNetcdfProcess(),
]

return processes
82 changes: 64 additions & 18 deletions finch/processes/ensemble_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
from collections.abc import Iterable
from copy import deepcopy
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Optional, Union

import geopandas as gpd
import pandas as pd
import xarray as xr
from pandas.api.types import is_numeric_dtype
Expand All @@ -21,7 +23,9 @@
from xclim.core.calendar import days_since_to_doy, doy_to_days_since, percentile_doy
from xclim.core.indicator import Indicator
from xclim.indicators.atmos import tg
from xscen.aggregate import spatial_mean

from . import wpsio
from .subset import finch_subset_bbox, finch_subset_gridpoint, finch_subset_shape
from .utils import (
DatasetConfiguration,
Expand Down Expand Up @@ -71,9 +75,9 @@ class Dataset: # noqa: D101
model: str
scenario: str
frequency: str = "day"
realization: Optional[str] = None
date_start: Optional[str] = None
date_end: Optional[str] = None
realization: str | None = None
date_start: str | None = None
date_end: str | None = None

@classmethod
def from_filename(cls, filename, pattern): # noqa: D102
Expand All @@ -86,10 +90,10 @@ def from_filename(cls, filename, pattern): # noqa: D102
def file_is_required(
filename: str,
pattern: str,
model_lists: Optional[dict[str, list[str]]] = None,
model_lists: dict[str, list[str]] | None = None,
variables: list[str] = None,
scenario: str = None,
models: list[Union[str, tuple[str, int]]] = None,
models: list[str | tuple[str, int]] = None,
):
"""Parse metadata and filter datasets."""
file = Dataset.from_filename(filename, pattern)
Expand Down Expand Up @@ -177,9 +181,9 @@ def _make_resource_input(url: str, workdir: str, local: bool):
def get_datasets(
dsconf: DatasetConfiguration,
workdir: str,
variables: Optional[list[str]] = None,
scenario: Optional[str] = None,
models: Optional[list[str]] = None,
variables: list[str] | None = None,
scenario: str | None = None,
models: list[str] | None = None,
) -> list[PywpsInput]:
"""Parse a directory to find files and filters the list to return only the needed ones, as resource inputs.

Expand Down Expand Up @@ -215,7 +219,7 @@ def get_datasets(
return inputs


def _formatted_coordinate(value) -> Optional[str]:
def _formatted_coordinate(value) -> str | None:
"""Return the first float value.

The value can be a comma separated list of floats or a single float.
Expand Down Expand Up @@ -350,22 +354,44 @@ def make_file_groups(files_list: list[Path], variables: set) -> list[dict[str, P


def make_ensemble(
files: list[Path], percentiles: list[int], average_dims: Optional[tuple[str]] = None
files: list[Path],
percentiles: list[int],
spatavg: bool | None = False,
region: dict | None = None,
) -> None: # noqa: D103
ensemble = ensembles.create_ensemble(
files, realizations=[file.stem for file in files]
)
# make sure we have data starting in 1950
ensemble = ensemble.sel(time=(ensemble.time.dt.year >= 1950))

if ensemble.lon.size == 1 and ensemble.lat.size == 1 and spatavg:
ensemble.attrs["history"] = (
f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] "
f"spatial average flag is set to True but will be skipped as dataset contains a "
f"single point\n{ensemble.attrs.get('history', '')}"
)
spatavg = False

# If data is in day of year, percentiles won't make sense.
# Convert to "days since" (base will be the time coordinate)
for v in ensemble.data_vars:
if ensemble[v].attrs.get("is_dayofyear", 0) == 1:
ensemble[v] = doy_to_days_since(ensemble[v])

if average_dims is not None:
ensemble = ensemble.mean(dim=average_dims)
if spatavg:
# ensemble = ensemble.mean(dim=average_dims)
if region is None:
method = "cos-lat"
else:
method = "xesmf"
ensemble = spatial_mean(
ds=ensemble,
method=method,
spatial_subset=False,
region=region,
kwargs={"skipna": True},
)

if percentiles:
ensemble_percentiles = ensembles.ensemble_percentiles(
Expand Down Expand Up @@ -540,13 +566,28 @@ def ensemble_common_handler(
)

if single_input_or_none(request.inputs, "average"):
spatavg = True
if subset_function == finch_subset_gridpoint:
average_dims = ("region",)
region = None
elif subset_function == finch_subset_bbox:
lon0 = single_input_or_none(request.inputs, wpsio.lon0.identifier)
lat0 = single_input_or_none(request.inputs, wpsio.lat0.identifier)
lon1 = single_input_or_none(request.inputs, wpsio.lon1.identifier)
lat1 = single_input_or_none(request.inputs, wpsio.lat1.identifier)
bbox = dict(lat_bnds=[lat0, lat1], lon_bnds=[lon0, lon1])
region = dict(name="region", method="bbox", **bbox)
else:
average_dims = ("lat", "lon")
shp = gpd.read_file(
Path(request.inputs[wpsio.shape.identifier][0].file)
).to_crs("EPSG:4326")
shp["geometry"] = shp.make_valid()
region = dict(name="region", method="shape", shape=shp)
else:
average_dims = None
write_log(process, f"Will average over {average_dims}")
# average_dims = None
region = None
spatavg = False

write_log(process, f"Will average over {region}")

base_work_dir = Path(process.workdir)
ensembles = []
Expand Down Expand Up @@ -625,7 +666,12 @@ def ensemble_common_handler(
warnings.filterwarnings("default", category=FutureWarning)
warnings.filterwarnings("default", category=UserWarning)

ensemble = make_ensemble(indices_files, ensemble_percentiles, average_dims)
ensemble = make_ensemble(
files=indices_files,
percentiles=ensemble_percentiles,
spatavg=spatavg,
region=region,
)
ensemble.attrs["source_datasets"] = "\n".join(
[dsinp.url for dsinp in netcdf_inputs]
)
Expand All @@ -651,7 +697,7 @@ def ensemble_common_handler(
ensemble = ensemble.round(prec)
prec = 0
df = dataset_to_dataframe(ensemble)
if average_dims is None:
if spatavg is None:
dims = ["lat", "lon", "time"]
else:
dims = ["time"]
Expand Down
4 changes: 2 additions & 2 deletions finch/processes/modules/humidex.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ indicators:
default: "YS"
threshold:
default: "30"
units: ""
units: "1"

variables:
HXmax:
canonical_units: ""
canonical_units: "1"
cell_methods: "time: max"
description: Daily Maximum Humidex
6 changes: 3 additions & 3 deletions finch/processes/modules/streamflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ doc:
realm: land
indicators:
discharge_stats:
base: xclim.core.indicator.stats
base: stats
cf_attrs:
long_name: Daily flow statistics
description: "{freq} {op} of daily flow ({indexer})."
Expand All @@ -12,7 +12,7 @@ indicators:
input:
da: discharge
freq_analysis:
base: xclim.core.indicator.return_level
base: return_level
cf_attrs:
long_name: N-year return level discharge
description: "Streamflow frequency analysis for the {mode} {indexer} {window}-day flow estimated using the {dist} distribution."
Expand All @@ -21,7 +21,7 @@ indicators:
input:
da: discharge
discharge_distribution_fit:
base: xclim.core.indicator.fit
base: fit
cf_attrs:
var_name: params
input:
Expand Down
Loading
Loading