ewatercycle.base.forcing
Base classes for eWaterCycle forcings.
Configuring ESMValTool
To download data from ESFG via ESMValTool you will need a ~/.esmvaltool/config-user.yml file with something like:
search_esgf: when_missing
download_dir: ~/climate_data
rootpath:
CMIP6: ~/climate_data/CMIP6
drs:
CMIP6: ESGF
A config file can be generated with:
esmvaltool config get-config-user
See ESMValTool configuring docs for more information.
Module Contents
- ewatercycle.base.forcing.logger
- ewatercycle.base.forcing.FORCING_YAML = 'ewatercycle_forcing.yaml'
- ewatercycle.base.forcing.AnyForcing
- ewatercycle.base.forcing.Postprocessor: TypeAlias
- class ewatercycle.base.forcing.DefaultForcing
Bases:
pydantic.BaseModel
Container for forcing data.
- Parameters:
directory – Directory where forcing data files are stored.
start_time – Start time of forcing in UTC and ISO format string e.g. ‘YYYY-MM-DDTHH:MM:SSZ’.
end_time – End time of forcing in UTC and ISO format string e.g. ‘YYYY-MM-DDTHH:MM:SSZ’.
shape – Path to a shape file. Used for spatial selection. If relative then it is relative to the given directory.
filenames – Dictionary of the variables contained in this forcing object, as well as the file names. Default value is empty, for backwards compatibility.
- directory: Annotated[pathlib.Path, AfterValidator(_to_absolute_path)]
- shape: pathlib.Path | None
- classmethod generate(dataset: str | ewatercycle.esmvaltool.schema.Dataset | dict, start_time: str, end_time: str, shape: str | pathlib.Path, directory: str | None = None, variables: tuple[str, Ellipsis] = (), postprocessor: Postprocessor | None = None, **model_specific_options) AnyForcing
Generate forcings for a model.
The forcing is generated with help of ESMValTool.
- Parameters:
dataset – Dataset to get forcing data from. When string is given a predefined dataset is looked up in
ewatercycle.esmvaltool.datasets.DATASETS
. When dict given it is passed toewatercycle.esmvaltool.models.Dataset
constructor.start_time – Start time of forcing in UTC and ISO format string e.g. ‘YYYY-MM-DDTHH:MM:SSZ’.
end_time – nd time of forcing in UTC and ISO format string e.g. ‘YYYY-MM-DDTHH:MM:SSZ’.
shape – Path to a shape file. Used for spatial selection.
directory – Directory in which forcing should be written. If not given will create timestamped directory.
variables – Variables which need to be downloaded/preprocessed by ESMValTool.
postprocessor – A custom post-processor that can, e.g., derive additional variables based on the ESMValTool recipe output. Must return the names & filenames of the variables it derived.
- save()
Export forcing data for later use.
- classmethod load(directory: str | pathlib.Path)
Load previously generated or imported forcing data.
- Parameters:
directory – forcing data directory; must contain ewatercycle_forcing.yaml file
Returns: Forcing object
- to_xarray() xarray.Dataset
Return this Forcing object as an xarray Dataset.
- class ewatercycle.base.forcing.DistributedUserForcing
Bases:
DefaultForcing
Forcing object with user-specified downloaded variables and postprocessing.
Examples:
To generate forcing from ERA5 for the Rhine catchment for 2000-2001, retrieving the ‘pr’, ‘tas’ and ‘rsds’ variables, and applying the Makkink evaporation postprocessor.
from pathlib import Path from rich import print from ewatercycle.base.forcing import DistributedUserForcing cmip_dataset = { "dataset": "EC-Earth3", "project": "CMIP6", "grid": "gr", "exp": "historical", "ensemble": "r6i1p1f1", } shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") forcing = DistributedUserForcing.generate( dataset=cmip_dataset, start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', shape=str(shape.absolute()), variables=("pr", "tas"), ) print(forcing)
Gives something like:
DistributedUserForcing( start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', directory=PosixPath('/home/bart/esmvaltool_output/ewcrepvl1jeunb_20240305_131155/work/diagnostic/script'), shape=PosixPath('/home/bart/git/ewatercycle/src/ewatercycle/testing/data/Rhine/Rhine.shp'), filenames={ 'pr': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_pr_gr_2000-2001.nc', 'tas': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_tas_gr_2000-2001.nc', 'rsds': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_rsds_gr_2000-2001.nc', 'evspsblpot': 'Derived_Makkink_evspsblpot.nc' } )
- class ewatercycle.base.forcing.LumpedUserForcing
Bases:
DistributedUserForcing
Forcing object with user-specified downloaded variables and postprocessing.
Examples:
To generate lumped forcing from ERA5 for the Rhine catchment for 2000-2001, retrieving the ‘pr’, ‘tas’ and ‘rsds’ variables, and applying the Makkink evaporation postprocessor.
from pathlib import Path from rich import print from ewatercycle.base.forcing import LumpedUserForcing cmip_dataset = { "dataset": "EC-Earth3", "project": "CMIP6", "grid": "gr", "exp": "historical", "ensemble": "r6i1p1f1", } shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") forcing = LumpedUserForcing.generate( dataset=cmip_dataset, start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', shape=str(shape.absolute()), variables=("pr", "tas"), ) print(forcing)
Gives something like:
LumpedUserForcing( start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', directory=PosixPath('/home/bart/esmvaltool_output/ewcrepvl1jeunb_20240305_131155/work/diagnostic/script'), shape=PosixPath('/home/bart/git/ewatercycle/src/ewatercycle/testing/data/Rhine/Rhine.shp'), filenames={ 'pr': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_pr_gr_2000-2001.nc', 'tas': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_tas_gr_2000-2001.nc', 'rsds': 'CMIP6_EC-Earth3_day_historical_r6i1p1f1_rsds_gr_2000-2001.nc', 'evspsblpot': 'Derived_Makkink_evspsblpot.nc' } )
- class ewatercycle.base.forcing.GenericDistributedForcing
Bases:
_GenericForcing
,DistributedUserForcing
Generic forcing data for a distributed model.
Examples
To generate forcing from ERA5 for the Rhine catchment for 2000-2001:
from pathlib import Path from rich import print from ewatercycle.base.forcing import GenericDistributedForcing shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") forcing = GenericDistributedForcing.generate( dataset='ERA5', start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', shape=shape.absolute(), ) print(forcing)
Gives something like:
GenericDistributedForcing( model='generic_distributed', start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', directory=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/esmvaltool_output/tmp05upitxoewcrep_20230815_154640/work/diagnostic/script'), shape=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/src/ewatercycle/testing/data/Rhine/Rhine.shp'), filenames={ pr='OBS6_ERA5_reanaly_1_day_pr_2000-2001.nc', tas='OBS6_ERA5_reanaly_1_day_tas_2000-2001.nc', } )
To generate forcing from CMIP6 for the Rhine catchment for 2000-2001 (make sure ESMValTool is configured correctly):
from pathlib import Path from rich import print from ewatercycle.base.forcing import GenericDistributedForcing shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") cmip_dataset = { "dataset": "EC-Earth3", "project": "CMIP6", "grid": "gr", "exp": ["historical",], "ensemble": "r6i1p1f1", } forcing = GenericDistributedForcing.generate( dataset=cmip_dataset, start_time="2000-01-01T00:00:00Z", end_time="2001-01-01T00:00:00Z", shape=shape.absolute(), ) print(forcing)
Gives something like:
GenericDistributedForcing( start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', directory=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/esmvaltool_output/ewcrep0ibzlds__20230904_082748/work/diagnostic/script'), shape=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/src/ewatercycle/testing/data/Rhine/Rhine.shp'), filenames={ pr='CMIP6_EC-Earth3_day_historical_r6i1p1f1_pr_gr_2000-2001.nc', tas='CMIP6_EC-Earth3_day_historical_r6i1p1f1_tas_gr_2000-2001.nc', } )
- class ewatercycle.base.forcing.GenericLumpedForcing
Bases:
_GenericForcing
,LumpedUserForcing
Generic forcing data for a lumped model.
Example
To generate forcing from ERA5 for the Rhine catchment for 2000-2001:
from pathlib import Path from rich import print from ewatercycle.base.forcing import GenericLumpedForcing shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") forcing = GenericLumpedForcing.generate( dataset='ERA5', start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', shape=shape.absolute(), ) print(forcing)
Gives something like:
GenericLumpedForcing( model='generic_distributed', start_time='2000-01-01T00:00:00Z', end_time='2001-01-01T00:00:00Z', directory=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/esmvaltool_output/ewcrep90hmnvat_20230816_124951/work/diagnostic/script'), shape=PosixPath('/home/verhoes/git/eWaterCycle/ewatercycle/src/ewatercycle/testing/data/Rhine/Rhine.shp'), pr='OBS6_ERA5_reanaly_1_day_pr_2000-2001.nc', tas='OBS6_ERA5_reanaly_1_day_tas_2000-2001.nc', tasmin='OBS6_ERA5_reanaly_1_day_tasmin_2000-2001.nc', tasmax='OBS6_ERA5_reanaly_1_day_tasmax_2000-2001.nc' )
To generate forcing from CMIP6 for the Rhine catchment for 2000-2001 (make sure ESMValTool is configured correctly):
from pathlib import Path from rich import print from ewatercycle.base.forcing import GenericLumpedForcing shape = Path("./src/ewatercycle/testing/data/Rhine/Rhine.shp") cmip_dataset = { "dataset": "EC-Earth3", "project": "CMIP6", "grid": "gr", "exp": ["historical",], "ensemble": "r6i1p1f1", } forcing = GenericLumpedForcing.generate( dataset=cmip_dataset, start_time="2000-01-01T00:00:00Z", end_time="2001-01-01T00:00:00Z", shape=shape.absolute(), ) print(forcing)