Upgrade to Python 3.12 #870
Draft
Jenkins - WCR / Tests / Declarative: Post Actions
failed
Aug 7, 2024 in 0s
failed: 22, passed: 202
Send us feedback
Details
climada_petals.hazard.emulator.test.test_geo.TestGeo.test_hazregion_centroids
AssertionError: 0 != 2
Stack trace
self = <climada_petals.hazard.emulator.test.test_geo.TestGeo testMethod=test_hazregion_centroids>
def test_hazregion_centroids(self):
"""Test HazRegion.centroids method"""
reg = geo.HazRegion(country="MLT")
cen = reg.centroids()
> self.assertEqual(cen.lat.size, 2)
E AssertionError: 0 != 2
../../../../petals_install_env/workspace/climada_petals/hazard/emulator/test/test_geo.py:74: AssertionError
climada_petals.hazard.test.test_flood.TestRiverFlood.test_flooded_area
AttributeError: 'Centroids' object has no attribute 'get_meta'
Stack trace
self = <climada_petals.hazard.test.test_flood.TestRiverFlood testMethod=test_flooded_area>
def test_flooded_area(self):
> testRFset = RiverFlood.from_nc(countries=['DEU', 'CHE'], dph_path=HAZ_DEMO_FLDDPH,
frc_path=HAZ_DEMO_FLDFRC, ISINatIDGrid=True)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_flood.py:210:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.river_flood.RiverFlood'>
dph_path = PosixPath('/var/lib/jenkins/climada/demo/data/flddph_2000_DEMO.nc')
frc_path = PosixPath('/var/lib/jenkins/climada/demo/data/fldfrc_2000_DEMO.nc')
origin = False, centroids = None, countries = ['DEU', 'CHE'], reg = None
shape = None, ISINatIDGrid = True, years = [2000]
@classmethod
def from_nc(cls, dph_path=None, frc_path=None, origin=False,
centroids=None, countries=None, reg=None, shape=None, ISINatIDGrid=False,
years=None):
"""Wrapper to fill hazard from nc_flood file
Parameters
----------
dph_path : str, optional
Flood file to read (depth)
frc_path : str, optional
Flood file to read (fraction)
origin : bool, optional
Historical or probabilistic event. Default: False
centroids : Centroids, optional
centroids to extract
countries : list of str, optional
If `reg` is None, use this selection of countries (ISO3). Default: None
reg : list of str, optional
Use region code to consider whole areas. If not None, countries and centroids
are ignored. Default: None
shape : str or Path, optional
If `reg` and `countries` are None, use the first geometry in this shape file to cut
out the area of interest. Default: None
ISINatIDGrid : bool, optional
Indicates whether ISIMIP_NatIDGrid is used. Default: False
years : list of int
Years that are considered. Default: None
Returns
-------
haz : RiverFlood instance
Raises
------
NameError
"""
if years is None:
years = [2000]
if dph_path is None:
raise NameError('No flood-depth-path set')
if frc_path is None:
raise NameError('No flood-fraction-path set')
if not Path(dph_path).exists():
raise NameError('Invalid flood-file path %s' % dph_path)
if not Path(frc_path).exists():
raise NameError('Invalid flood-file path %s' % frc_path)
with xr.open_dataset(dph_path) as flood_dph:
time = pd.to_datetime(flood_dph["time"].values)
event_index = np.where(np.isin(time.year, years))[0]
if len(event_index) == 0:
raise AttributeError(f'No events found for selected {years}')
bands = event_index + 1
if countries or reg:
# centroids as points
if ISINatIDGrid:
dest_centroids = RiverFlood._select_exact_area(countries, reg)[0]
> centroids_meta = dest_centroids.get_meta()
E AttributeError: 'Centroids' object has no attribute 'get_meta'
../../../../petals_install_env/workspace/climada_petals/hazard/river_flood.py:139: AttributeError
climada_petals.hazard.test.test_flood.TestRiverFlood.test_isimip_country_flood
AttributeError: 'Centroids' object has no attribute 'get_meta'
Stack trace
self = <climada_petals.hazard.test.test_flood.TestRiverFlood testMethod=test_isimip_country_flood>
def test_isimip_country_flood(self):
> rf = RiverFlood.from_nc(dph_path=HAZ_DEMO_FLDDPH, frc_path=HAZ_DEMO_FLDFRC,
countries=['DEU'], ISINatIDGrid=True)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_flood.py:93:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.river_flood.RiverFlood'>
dph_path = PosixPath('/var/lib/jenkins/climada/demo/data/flddph_2000_DEMO.nc')
frc_path = PosixPath('/var/lib/jenkins/climada/demo/data/fldfrc_2000_DEMO.nc')
origin = False, centroids = None, countries = ['DEU'], reg = None, shape = None
ISINatIDGrid = True, years = [2000]
@classmethod
def from_nc(cls, dph_path=None, frc_path=None, origin=False,
centroids=None, countries=None, reg=None, shape=None, ISINatIDGrid=False,
years=None):
"""Wrapper to fill hazard from nc_flood file
Parameters
----------
dph_path : str, optional
Flood file to read (depth)
frc_path : str, optional
Flood file to read (fraction)
origin : bool, optional
Historical or probabilistic event. Default: False
centroids : Centroids, optional
centroids to extract
countries : list of str, optional
If `reg` is None, use this selection of countries (ISO3). Default: None
reg : list of str, optional
Use region code to consider whole areas. If not None, countries and centroids
are ignored. Default: None
shape : str or Path, optional
If `reg` and `countries` are None, use the first geometry in this shape file to cut
out the area of interest. Default: None
ISINatIDGrid : bool, optional
Indicates whether ISIMIP_NatIDGrid is used. Default: False
years : list of int
Years that are considered. Default: None
Returns
-------
haz : RiverFlood instance
Raises
------
NameError
"""
if years is None:
years = [2000]
if dph_path is None:
raise NameError('No flood-depth-path set')
if frc_path is None:
raise NameError('No flood-fraction-path set')
if not Path(dph_path).exists():
raise NameError('Invalid flood-file path %s' % dph_path)
if not Path(frc_path).exists():
raise NameError('Invalid flood-file path %s' % frc_path)
with xr.open_dataset(dph_path) as flood_dph:
time = pd.to_datetime(flood_dph["time"].values)
event_index = np.where(np.isin(time.year, years))[0]
if len(event_index) == 0:
raise AttributeError(f'No events found for selected {years}')
bands = event_index + 1
if countries or reg:
# centroids as points
if ISINatIDGrid:
dest_centroids = RiverFlood._select_exact_area(countries, reg)[0]
> centroids_meta = dest_centroids.get_meta()
E AttributeError: 'Centroids' object has no attribute 'get_meta'
../../../../petals_install_env/workspace/climada_petals/hazard/river_flood.py:139: AttributeError
climada_petals.hazard.test.test_flood.TestRiverFlood.test_meta_centroids_flood
ValueError: zero-size array to reduction operation minimum which has no identity
Stack trace
self = <climada_petals.hazard.test.test_flood.TestRiverFlood testMethod=test_meta_centroids_flood>
def test_meta_centroids_flood(self):
min_lat, max_lat, min_lon, max_lon = 45.7, 47.8, 7.5, 10.5
cent = Centroids.from_pnt_bounds((min_lon, min_lat, max_lon, max_lat), res=0.05)
rf_rast = RiverFlood.from_nc(dph_path=HAZ_DEMO_FLDDPH, frc_path=HAZ_DEMO_FLDFRC,
centroids=cent)
self.assertEqual(rf_rast.centroids.shape, (43, 61))
> self.assertAlmostEqual(np.min(rf_rast.centroids.lat),
45.70000000000012, 4)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_flood.py:183:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../../miniforge3/envs/climada_env/lib/python3.9/site-packages/numpy/core/fromnumeric.py:2953: in min
return _wrapreduction(a, np.minimum, 'min', axis, None, out,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
obj = array([], dtype=float64), ufunc = <ufunc 'minimum'>, method = 'min'
axis = None, dtype = None, out = None
kwargs = {'initial': <no value>, 'keepdims': <no value>, 'where': <no value>}
passkwargs = {}
def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs):
passkwargs = {k: v for k, v in kwargs.items()
if v is not np._NoValue}
if type(obj) is not mu.ndarray:
try:
reduction = getattr(obj, method)
except AttributeError:
pass
else:
# This branch is needed for reductions like any which don't
# support a dtype.
if dtype is not None:
return reduction(axis=axis, dtype=dtype, out=out, **passkwargs)
else:
return reduction(axis=axis, out=out, **passkwargs)
> return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
E ValueError: zero-size array to reduction operation minimum which has no identity
../../../../../miniforge3/envs/climada_env/lib/python3.9/site-packages/numpy/core/fromnumeric.py:88: ValueError
climada_petals.hazard.test.test_landslide.TestLandslideModule.test_from_prob
AttributeError: type object 'Centroids' has no attribute 'from_meta'
Stack trace
self = <climada_petals.hazard.test.test_landslide.TestLandslideModule testMethod=test_from_prob>
def test_from_prob(self):
""" Test the function from_prob()"""
n_years=1000
> LS_prob = Landslide.from_prob(bbox=(8,45,11,46),
path_sourcefile=LS_PROB_FILE, n_years=n_years,
dist='binom')
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_landslide.py:84:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.landslide.Landslide'>
bbox = (8, 45, 11, 46)
path_sourcefile = PosixPath('/var/lib/jenkins/jobs/petals_install_env/workspace/climada_petals/hazard/test/data/test_ls_prob.tif')
corr_fact = 10000000.0, n_years = 1000, dist = 'binom'
@classmethod
def from_prob(cls, bbox, path_sourcefile, corr_fact=10e6, n_years=500,
dist='poisson'):
"""
Set probabilistic landslide hazard (fraction, intensity and
frequency) for a defined bounding box and time period from a raster.
The hazard data for which this function is explicitly written
is readily provided by UNEP & the Norwegian Geotechnical Institute
(NGI), and can be downloaded and unzipped from
https://preview.grid.unep.ch/index.php?preview=data&events=landslides&evcat=2&lang=eng
for precipitation-triggered landslide and from
https://preview.grid.unep.ch/index.php?preview=data&events=landslides&evcat=1&lang=eng
for earthquake-triggered landslides.
It works with any similar raster file.
Original data is given in expected annual probability and percentage
of pixel of occurrence of a potentially destructive landslide event
x 1000000 (so be sure to adjust this by setting the correction factor).
More details can be found in the landslide tutorial and under above-
mentioned links.
Events are sampled from annual occurrence probabilites via binomial or
poisson distribution. An event therefore includes all landslides
sampled to occur within a year for the given area.
intensity takes a binary value (occurrence or no occurrene of a LS);
frequency is set to 1 / n_years.
Impact functions, since they act on the intensity, should hence be in
the form of a step function,
defining impact for intensity 0 and (close to) 1.
Parameters
----------
bbox : tuple
(minx, miny, maxx, maxy) geographic extent of interest
path_sourcefile : str
path to UNEP/NGI ls hazard file (.tif)
corr_fact : float or int
factor by which to divide the values in the original probability
file, in case it is not scaled to [0,1]. Default is 1'000'000
n_years : int
sampling period
dist : str
distribution to sample from. 'poisson' (default) and 'binom'
Returns
-------
haz : climada.hazard.Landslide instance
probabilistic LS hazard
See also
--------
sample_events()
"""
haz = cls()
# raster with occurrence probs
meta, prob_matrix = \
u_coord.read_raster(path_sourcefile, geometry=[shapely.geometry.box(*bbox, ccw=True)])
> haz.centroids = Centroids.from_meta(meta)
E AttributeError: type object 'Centroids' has no attribute 'from_meta'
../../../../petals_install_env/workspace/climada_petals/hazard/landslide.py:304: AttributeError
climada_petals.hazard.test.test_landslide.TestLandslideModule.test_set_ls_prob
AttributeError: type object 'Centroids' has no attribute 'from_meta'
Stack trace
self = <climada_petals.hazard.test.test_landslide.TestLandslideModule testMethod=test_set_ls_prob>
def test_set_ls_prob(self):
""" Test deprecated function set_ls_prob()"""
LS_prob = Landslide()
n_years=1000
> LS_prob.set_ls_prob(bbox=(8,45,11,46),
path_sourcefile=LS_PROB_FILE, n_years=n_years,
dist='binom')
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_landslide.py:143:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../petals_install_env/workspace/climada_petals/hazard/landslide.py:328: in set_ls_prob
self.__dict__ = Landslide.from_prob(*args, **kwargs).__dict__
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.landslide.Landslide'>
bbox = (8, 45, 11, 46)
path_sourcefile = PosixPath('/var/lib/jenkins/jobs/petals_install_env/workspace/climada_petals/hazard/test/data/test_ls_prob.tif')
corr_fact = 10000000.0, n_years = 1000, dist = 'binom'
@classmethod
def from_prob(cls, bbox, path_sourcefile, corr_fact=10e6, n_years=500,
dist='poisson'):
"""
Set probabilistic landslide hazard (fraction, intensity and
frequency) for a defined bounding box and time period from a raster.
The hazard data for which this function is explicitly written
is readily provided by UNEP & the Norwegian Geotechnical Institute
(NGI), and can be downloaded and unzipped from
https://preview.grid.unep.ch/index.php?preview=data&events=landslides&evcat=2&lang=eng
for precipitation-triggered landslide and from
https://preview.grid.unep.ch/index.php?preview=data&events=landslides&evcat=1&lang=eng
for earthquake-triggered landslides.
It works with any similar raster file.
Original data is given in expected annual probability and percentage
of pixel of occurrence of a potentially destructive landslide event
x 1000000 (so be sure to adjust this by setting the correction factor).
More details can be found in the landslide tutorial and under above-
mentioned links.
Events are sampled from annual occurrence probabilites via binomial or
poisson distribution. An event therefore includes all landslides
sampled to occur within a year for the given area.
intensity takes a binary value (occurrence or no occurrene of a LS);
frequency is set to 1 / n_years.
Impact functions, since they act on the intensity, should hence be in
the form of a step function,
defining impact for intensity 0 and (close to) 1.
Parameters
----------
bbox : tuple
(minx, miny, maxx, maxy) geographic extent of interest
path_sourcefile : str
path to UNEP/NGI ls hazard file (.tif)
corr_fact : float or int
factor by which to divide the values in the original probability
file, in case it is not scaled to [0,1]. Default is 1'000'000
n_years : int
sampling period
dist : str
distribution to sample from. 'poisson' (default) and 'binom'
Returns
-------
haz : climada.hazard.Landslide instance
probabilistic LS hazard
See also
--------
sample_events()
"""
haz = cls()
# raster with occurrence probs
meta, prob_matrix = \
u_coord.read_raster(path_sourcefile, geometry=[shapely.geometry.box(*bbox, ccw=True)])
> haz.centroids = Centroids.from_meta(meta)
E AttributeError: type object 'Centroids' has no attribute 'from_meta'
../../../../petals_install_env/workspace/climada_petals/hazard/landslide.py:304: AttributeError
climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield.test_load_EU_all
AttributeError: 'Centroids' object has no attribute 'gdf'
Stack trace
self = <climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield testMethod=test_load_EU_all>
def test_load_EU_all(self):
"""Test defining crop potential hazard from complete demo file (Central Europe)"""
> haz = RelativeCropyield.from_isimip_netcdf(input_dir=INPUT_DIR, yearrange=(2001, 2005),
ag_model='lpjml', cl_model='ipsl-cm5a-lr', scenario='historical',
soc='2005soc', co2='co2', crop='whe', irr='noirr',
fn_str_var=FN_STR_DEMO)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_relative_cropyield.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.relative_cropyield.RelativeCropyield'>
input_dir = PosixPath('/var/lib/jenkins/climada/demo/data')
filename = 'lpjml_ipsl-cm5a-lr_ewembi_historical_2005soc_co2_yield-whe-noirr_annual_FR_DE_DEMO_1861_2005.nc'
bbox = (-180, -85, 180, 85), yearrange = (2001, 2005), ag_model = 'lpjml'
cl_model = 'ipsl-cm5a-lr', bias_corr = 'ewembi', scenario = 'historical'
soc = '2005soc', co2 = 'co2', crop = 'whe', irr = 'noirr'
fn_str_var = 'annual_FR_DE_DEMO'
@classmethod
def from_isimip_netcdf(cls, input_dir=None, filename=None, bbox=None,
yearrange=None, ag_model=None, cl_model=None, bias_corr=None,
scenario=None, soc=None, co2=None, crop=None,
irr=None, fn_str_var=None):
"""Wrapper to fill hazard from crop yield NetCDF file.
Build and tested for output from ISIMIP2 and ISIMIP3, but might also work
for other NetCDF containing gridded crop model output from other sources.
Parameters
----------
input_dir : Path or str
path to input data directory,
default: {CONFIG.exposures.crop_production.local_data}/Input/Exposure
filename : string
name of netcdf file in input_dir. If filename is given,
the other parameters specifying the model run are not required!
bbox : list of four floats
bounding box:
[lon min, lat min, lon max, lat max]
yearrange : int tuple
year range for hazard set, f.i. (1976, 2005)
ag_model : str
abbrev. agricultural model (only when input_dir is selected)
f.i. 'clm-crop', 'gepic','lpjml','pepic'
cl_model : str
abbrev. climate model (only when input_dir is selected)
f.i. ['gfdl-esm2m', 'hadgem2-es','ipsl-cm5a-lr','miroc5'
bias_corr : str
bias correction of climate forcing,
f.i. 'ewembi' (ISIMIP2b, default) or 'w5e5' (ISIMIP3b)
scenario : str
climate change scenario (only when input_dir is selected)
f.i. 'historical' or 'rcp60' or 'ISIMIP2a'
soc : str
socio-economic trajectory (only when input_dir is selected)
f.i. '2005soc' or 'histsoc'
co2 : str
CO2 forcing scenario (only when input_dir is selected)
f.i. 'co2' or '2005co2'
crop : str
crop type (only when input_dir is selected)
f.i. 'whe', 'mai', 'soy' or 'ric'
irr : str
irrigation type (only when input_dir is selected)
f.i 'noirr' or 'irr'
fn_str_var : str
FileName STRing depending on VARiable and
ISIMIP simuation round
Returns
-------
RelativeCropyield
Raises
------
NameError
"""
if not fn_str_var:
fn_str_var = FN_STR_VAR
if scenario is None:
scenario = 'historical'
if bias_corr is None:
bias_corr = 'ewembi'
if bbox is None:
bbox = BBOX
if input_dir is None:
input_dir = INPUT_DIR
input_dir = Path(input_dir)
if not Path(input_dir).is_dir():
raise NameError('Input directory %s does not exist' % input_dir)
# The filename is set or other variables (cl_model, scenario) are extracted of the
# specified filename
if filename is None:
yearchunk = YEARCHUNKS[scenario]
filename = '{}_{}_{}_{}_{}_{}_yield-{}-{}_{}_{}_{}.nc'.format(
ag_model, cl_model, bias_corr, scenario, soc, co2,
crop, irr, fn_str_var, yearchunk['startyear'], yearchunk['endyear'])
elif scenario == 'ISIMIP2a':
(_, _, _, _, _, _, _, crop, _, _, startyear, endyearnc) = filename.split('_')
endyear, _ = endyearnc.split('.')
yearchunk = dict()
yearchunk = {'yearrange': (int(startyear), int(endyear)),
'startyear': int(startyear), 'endyear': int(endyear)}
elif scenario == 'test_file':
yearchunk = dict()
yearchunk = {'yearrange': (1976, 2005), 'startyear': 1861,
'endyear': 2005, 'yearrange_mean': (1976, 2005)}
ag_model, cl_model, _, _, soc, co2, crop_prop, *_ = filename.split('_')
_, crop, irr = crop_prop.split('-')
else: # get yearchunk from filename, e.g., for rcp2.6 extended and ISIMIP3
(_, _, _, _, _, _, crop_irr, _, _, year1, year2) = filename.split('_')
yearchunk = {'yearrange': (int(year1), int(year2.split('.')[0])),
'startyear': int(year1),
'endyear': int(year2.split('.')[0])}
_, crop, irr = crop_irr.split('-')
# if no yearrange is given, load full range from input file:
if yearrange is None or len(yearrange) == 0:
yearrange = yearchunk['yearrange']
# define indexes of the netcdf-bands to be extracted, and the
# corresponding event names and dates
# corrected indexes due to the bands in input starting with the index=1
id_bands = np.arange(yearrange[0] - yearchunk['startyear'] + 1,
yearrange[1] - yearchunk['startyear'] + 2).tolist()
# hazard setup: set attributes
[lonmin, latmin, lonmax, latmax] = bbox
haz = cls.from_raster([str(Path(input_dir, filename))], band=id_bands,
geometry=list([shapely.geometry.box(lonmin, latmin, lonmax, latmax)]))
haz.intensity_def = INT_DEF
haz.intensity.data[np.isnan(haz.intensity.data)] = 0.0
haz.intensity.todense()
haz.crop = crop
haz.event_name = [str(n) for n in range(int(yearrange[0]), int(yearrange[-1] + 1))]
haz.frequency = np.ones(len(haz.event_name)) * (1 / len(haz.event_name))
haz.fraction = haz.intensity.copy()
haz.fraction.data.fill(1.0)
haz.units = 't / y / ha'
haz.date = np.array(dt.str_to_date(
[event_ + '-01-01' for event_ in haz.event_name]))
> haz.centroids.gdf['region_id'] = (
coord.coord_on_land(haz.centroids.lat, haz.centroids.lon)).astype(dtype=int)
E AttributeError: 'Centroids' object has no attribute 'gdf'
../../../../petals_install_env/workspace/climada_petals/hazard/relative_cropyield.py:249: AttributeError
climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield.test_set_percentile_to_int
AttributeError: 'Centroids' object has no attribute 'gdf'
Stack trace
self = <climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield testMethod=test_set_percentile_to_int>
def test_set_percentile_to_int(self):
"""Test setting intensity to percentile of the yield"""
> haz = RelativeCropyield.from_isimip_netcdf(input_dir=INPUT_DIR, yearrange=(2001, 2005), ag_model='lpjml',
cl_model='ipsl-cm5a-lr', scenario='historical', soc='2005soc',
co2='co2', crop='whe', irr='noirr', fn_str_var=FN_STR_DEMO)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_relative_cropyield.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.relative_cropyield.RelativeCropyield'>
input_dir = PosixPath('/var/lib/jenkins/climada/demo/data')
filename = 'lpjml_ipsl-cm5a-lr_ewembi_historical_2005soc_co2_yield-whe-noirr_annual_FR_DE_DEMO_1861_2005.nc'
bbox = (-180, -85, 180, 85), yearrange = (2001, 2005), ag_model = 'lpjml'
cl_model = 'ipsl-cm5a-lr', bias_corr = 'ewembi', scenario = 'historical'
soc = '2005soc', co2 = 'co2', crop = 'whe', irr = 'noirr'
fn_str_var = 'annual_FR_DE_DEMO'
@classmethod
def from_isimip_netcdf(cls, input_dir=None, filename=None, bbox=None,
yearrange=None, ag_model=None, cl_model=None, bias_corr=None,
scenario=None, soc=None, co2=None, crop=None,
irr=None, fn_str_var=None):
"""Wrapper to fill hazard from crop yield NetCDF file.
Build and tested for output from ISIMIP2 and ISIMIP3, but might also work
for other NetCDF containing gridded crop model output from other sources.
Parameters
----------
input_dir : Path or str
path to input data directory,
default: {CONFIG.exposures.crop_production.local_data}/Input/Exposure
filename : string
name of netcdf file in input_dir. If filename is given,
the other parameters specifying the model run are not required!
bbox : list of four floats
bounding box:
[lon min, lat min, lon max, lat max]
yearrange : int tuple
year range for hazard set, f.i. (1976, 2005)
ag_model : str
abbrev. agricultural model (only when input_dir is selected)
f.i. 'clm-crop', 'gepic','lpjml','pepic'
cl_model : str
abbrev. climate model (only when input_dir is selected)
f.i. ['gfdl-esm2m', 'hadgem2-es','ipsl-cm5a-lr','miroc5'
bias_corr : str
bias correction of climate forcing,
f.i. 'ewembi' (ISIMIP2b, default) or 'w5e5' (ISIMIP3b)
scenario : str
climate change scenario (only when input_dir is selected)
f.i. 'historical' or 'rcp60' or 'ISIMIP2a'
soc : str
socio-economic trajectory (only when input_dir is selected)
f.i. '2005soc' or 'histsoc'
co2 : str
CO2 forcing scenario (only when input_dir is selected)
f.i. 'co2' or '2005co2'
crop : str
crop type (only when input_dir is selected)
f.i. 'whe', 'mai', 'soy' or 'ric'
irr : str
irrigation type (only when input_dir is selected)
f.i 'noirr' or 'irr'
fn_str_var : str
FileName STRing depending on VARiable and
ISIMIP simuation round
Returns
-------
RelativeCropyield
Raises
------
NameError
"""
if not fn_str_var:
fn_str_var = FN_STR_VAR
if scenario is None:
scenario = 'historical'
if bias_corr is None:
bias_corr = 'ewembi'
if bbox is None:
bbox = BBOX
if input_dir is None:
input_dir = INPUT_DIR
input_dir = Path(input_dir)
if not Path(input_dir).is_dir():
raise NameError('Input directory %s does not exist' % input_dir)
# The filename is set or other variables (cl_model, scenario) are extracted of the
# specified filename
if filename is None:
yearchunk = YEARCHUNKS[scenario]
filename = '{}_{}_{}_{}_{}_{}_yield-{}-{}_{}_{}_{}.nc'.format(
ag_model, cl_model, bias_corr, scenario, soc, co2,
crop, irr, fn_str_var, yearchunk['startyear'], yearchunk['endyear'])
elif scenario == 'ISIMIP2a':
(_, _, _, _, _, _, _, crop, _, _, startyear, endyearnc) = filename.split('_')
endyear, _ = endyearnc.split('.')
yearchunk = dict()
yearchunk = {'yearrange': (int(startyear), int(endyear)),
'startyear': int(startyear), 'endyear': int(endyear)}
elif scenario == 'test_file':
yearchunk = dict()
yearchunk = {'yearrange': (1976, 2005), 'startyear': 1861,
'endyear': 2005, 'yearrange_mean': (1976, 2005)}
ag_model, cl_model, _, _, soc, co2, crop_prop, *_ = filename.split('_')
_, crop, irr = crop_prop.split('-')
else: # get yearchunk from filename, e.g., for rcp2.6 extended and ISIMIP3
(_, _, _, _, _, _, crop_irr, _, _, year1, year2) = filename.split('_')
yearchunk = {'yearrange': (int(year1), int(year2.split('.')[0])),
'startyear': int(year1),
'endyear': int(year2.split('.')[0])}
_, crop, irr = crop_irr.split('-')
# if no yearrange is given, load full range from input file:
if yearrange is None or len(yearrange) == 0:
yearrange = yearchunk['yearrange']
# define indexes of the netcdf-bands to be extracted, and the
# corresponding event names and dates
# corrected indexes due to the bands in input starting with the index=1
id_bands = np.arange(yearrange[0] - yearchunk['startyear'] + 1,
yearrange[1] - yearchunk['startyear'] + 2).tolist()
# hazard setup: set attributes
[lonmin, latmin, lonmax, latmax] = bbox
haz = cls.from_raster([str(Path(input_dir, filename))], band=id_bands,
geometry=list([shapely.geometry.box(lonmin, latmin, lonmax, latmax)]))
haz.intensity_def = INT_DEF
haz.intensity.data[np.isnan(haz.intensity.data)] = 0.0
haz.intensity.todense()
haz.crop = crop
haz.event_name = [str(n) for n in range(int(yearrange[0]), int(yearrange[-1] + 1))]
haz.frequency = np.ones(len(haz.event_name)) * (1 / len(haz.event_name))
haz.fraction = haz.intensity.copy()
haz.fraction.data.fill(1.0)
haz.units = 't / y / ha'
haz.date = np.array(dt.str_to_date(
[event_ + '-01-01' for event_ in haz.event_name]))
> haz.centroids.gdf['region_id'] = (
coord.coord_on_land(haz.centroids.lat, haz.centroids.lon)).astype(dtype=int)
E AttributeError: 'Centroids' object has no attribute 'gdf'
../../../../petals_install_env/workspace/climada_petals/hazard/relative_cropyield.py:249: AttributeError
climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield.test_set_rel_yield
AttributeError: 'Centroids' object has no attribute 'gdf'
Stack trace
self = <climada_petals.hazard.test.test_relative_cropyield.TestRelativeCropyield testMethod=test_set_rel_yield>
def test_set_rel_yield(self):
"""Test setting intensity to relativ yield"""
> haz = RelativeCropyield.from_isimip_netcdf(input_dir=INPUT_DIR, yearrange=(2001, 2005), ag_model='lpjml',
cl_model='ipsl-cm5a-lr', scenario='historical', soc='2005soc',
co2='co2', crop='whe', irr='noirr', fn_str_var=FN_STR_DEMO)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_relative_cropyield.py:52:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.relative_cropyield.RelativeCropyield'>
input_dir = PosixPath('/var/lib/jenkins/climada/demo/data')
filename = 'lpjml_ipsl-cm5a-lr_ewembi_historical_2005soc_co2_yield-whe-noirr_annual_FR_DE_DEMO_1861_2005.nc'
bbox = (-180, -85, 180, 85), yearrange = (2001, 2005), ag_model = 'lpjml'
cl_model = 'ipsl-cm5a-lr', bias_corr = 'ewembi', scenario = 'historical'
soc = '2005soc', co2 = 'co2', crop = 'whe', irr = 'noirr'
fn_str_var = 'annual_FR_DE_DEMO'
@classmethod
def from_isimip_netcdf(cls, input_dir=None, filename=None, bbox=None,
yearrange=None, ag_model=None, cl_model=None, bias_corr=None,
scenario=None, soc=None, co2=None, crop=None,
irr=None, fn_str_var=None):
"""Wrapper to fill hazard from crop yield NetCDF file.
Build and tested for output from ISIMIP2 and ISIMIP3, but might also work
for other NetCDF containing gridded crop model output from other sources.
Parameters
----------
input_dir : Path or str
path to input data directory,
default: {CONFIG.exposures.crop_production.local_data}/Input/Exposure
filename : string
name of netcdf file in input_dir. If filename is given,
the other parameters specifying the model run are not required!
bbox : list of four floats
bounding box:
[lon min, lat min, lon max, lat max]
yearrange : int tuple
year range for hazard set, f.i. (1976, 2005)
ag_model : str
abbrev. agricultural model (only when input_dir is selected)
f.i. 'clm-crop', 'gepic','lpjml','pepic'
cl_model : str
abbrev. climate model (only when input_dir is selected)
f.i. ['gfdl-esm2m', 'hadgem2-es','ipsl-cm5a-lr','miroc5'
bias_corr : str
bias correction of climate forcing,
f.i. 'ewembi' (ISIMIP2b, default) or 'w5e5' (ISIMIP3b)
scenario : str
climate change scenario (only when input_dir is selected)
f.i. 'historical' or 'rcp60' or 'ISIMIP2a'
soc : str
socio-economic trajectory (only when input_dir is selected)
f.i. '2005soc' or 'histsoc'
co2 : str
CO2 forcing scenario (only when input_dir is selected)
f.i. 'co2' or '2005co2'
crop : str
crop type (only when input_dir is selected)
f.i. 'whe', 'mai', 'soy' or 'ric'
irr : str
irrigation type (only when input_dir is selected)
f.i 'noirr' or 'irr'
fn_str_var : str
FileName STRing depending on VARiable and
ISIMIP simuation round
Returns
-------
RelativeCropyield
Raises
------
NameError
"""
if not fn_str_var:
fn_str_var = FN_STR_VAR
if scenario is None:
scenario = 'historical'
if bias_corr is None:
bias_corr = 'ewembi'
if bbox is None:
bbox = BBOX
if input_dir is None:
input_dir = INPUT_DIR
input_dir = Path(input_dir)
if not Path(input_dir).is_dir():
raise NameError('Input directory %s does not exist' % input_dir)
# The filename is set or other variables (cl_model, scenario) are extracted of the
# specified filename
if filename is None:
yearchunk = YEARCHUNKS[scenario]
filename = '{}_{}_{}_{}_{}_{}_yield-{}-{}_{}_{}_{}.nc'.format(
ag_model, cl_model, bias_corr, scenario, soc, co2,
crop, irr, fn_str_var, yearchunk['startyear'], yearchunk['endyear'])
elif scenario == 'ISIMIP2a':
(_, _, _, _, _, _, _, crop, _, _, startyear, endyearnc) = filename.split('_')
endyear, _ = endyearnc.split('.')
yearchunk = dict()
yearchunk = {'yearrange': (int(startyear), int(endyear)),
'startyear': int(startyear), 'endyear': int(endyear)}
elif scenario == 'test_file':
yearchunk = dict()
yearchunk = {'yearrange': (1976, 2005), 'startyear': 1861,
'endyear': 2005, 'yearrange_mean': (1976, 2005)}
ag_model, cl_model, _, _, soc, co2, crop_prop, *_ = filename.split('_')
_, crop, irr = crop_prop.split('-')
else: # get yearchunk from filename, e.g., for rcp2.6 extended and ISIMIP3
(_, _, _, _, _, _, crop_irr, _, _, year1, year2) = filename.split('_')
yearchunk = {'yearrange': (int(year1), int(year2.split('.')[0])),
'startyear': int(year1),
'endyear': int(year2.split('.')[0])}
_, crop, irr = crop_irr.split('-')
# if no yearrange is given, load full range from input file:
if yearrange is None or len(yearrange) == 0:
yearrange = yearchunk['yearrange']
# define indexes of the netcdf-bands to be extracted, and the
# corresponding event names and dates
# corrected indexes due to the bands in input starting with the index=1
id_bands = np.arange(yearrange[0] - yearchunk['startyear'] + 1,
yearrange[1] - yearchunk['startyear'] + 2).tolist()
# hazard setup: set attributes
[lonmin, latmin, lonmax, latmax] = bbox
haz = cls.from_raster([str(Path(input_dir, filename))], band=id_bands,
geometry=list([shapely.geometry.box(lonmin, latmin, lonmax, latmax)]))
haz.intensity_def = INT_DEF
haz.intensity.data[np.isnan(haz.intensity.data)] = 0.0
haz.intensity.todense()
haz.crop = crop
haz.event_name = [str(n) for n in range(int(yearrange[0]), int(yearrange[-1] + 1))]
haz.frequency = np.ones(len(haz.event_name)) * (1 / len(haz.event_name))
haz.fraction = haz.intensity.copy()
haz.fraction.data.fill(1.0)
haz.units = 't / y / ha'
haz.date = np.array(dt.str_to_date(
[event_ + '-01-01' for event_ in haz.event_name]))
> haz.centroids.gdf['region_id'] = (
coord.coord_on_land(haz.centroids.lat, haz.centroids.lon)).astype(dtype=int)
E AttributeError: 'Centroids' object has no attribute 'gdf'
../../../../petals_install_env/workspace/climada_petals/hazard/relative_cropyield.py:249: AttributeError
climada_petals.hazard.test.test_tc_rainfield.TestModel.test_rainfield_diff_time_steps
AttributeError: 'Centroids' object has no attribute 'get_dist_coast'
Stack trace
self = <climada_petals.hazard.test.test_tc_rainfield.TestModel testMethod=test_rainfield_diff_time_steps>
def test_rainfield_diff_time_steps(self):
"""Check that the results do not depend too much on the track's time step sizes."""
tc_track = TCTracks.from_processed_ibtracs_csv(TEST_TRACK)
> train_org = TCRain.from_tracks(tc_track)
../../../../petals_install_env/workspace/climada_petals/hazard/test/test_tc_rainfield.py:210:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'climada_petals.hazard.tc_rainfield.TCRain'>
tracks = <climada.hazard.tc_tracks.TCTracks object at 0x7f0e9eabfc10>
centroids = <climada.hazard.centroids.centr.Centroids object at 0x7f0e9eabf2b0>
pool = None, model = 'R-CLIPER', model_kwargs = None
ignore_distance_to_coast = False, store_rainrates = False, metric = 'equirect'
intensity_thres = 0.1, max_latitude = 61, max_dist_inland_km = 1000
max_dist_eye_km = 300, max_memory_gb = 8
@classmethod
def from_tracks(
cls,
tracks: TCTracks,
centroids: Centroids = None,
pool: Optional[pathos.pools.ProcessPool] = None,
model: str = 'R-CLIPER',
model_kwargs: Optional[dict] = None,
ignore_distance_to_coast: bool = False,
store_rainrates: bool = False,
metric: str = "equirect",
intensity_thres: float = DEF_INTENSITY_THRES,
max_latitude: float = 61,
max_dist_inland_km: float = 1000,
max_dist_eye_km: float = DEF_MAX_DIST_EYE_KM,
max_memory_gb: float = DEF_MAX_MEMORY_GB,
):
"""
Create new TCRain instance that contains rainfields from the specified tracks
This function sets the ``intensity`` attribute to contain, for each centroid,
the total amount of rain experienced over the whole period of each TC event in mm.
The amount of rain is set to 0 if it does not exceed the threshold ``intensity_thres``.
The ``category`` attribute is set to the value of the ``category``-attribute
of each of the given track data sets.
The ``basin`` attribute is set to the genesis basin for each event, which
is the first value of the ``basin``-variable in each of the given track data sets.
Optionally, the time-dependent rain rates can be stored using the ``store_rainrates``
function parameter (see below).
Currently, two models are supported to compute the rain rates: R-CLIPER and TCR. The
R-CLIPER model is documented in Tuleya et al. 2007. The TCR model was used by
Zhu et al. 2013 and Emanuel 2017 for the first time and is documented in detail in
Lu et al. 2018. This implementation of TCR includes improvements proposed in
Feldmann et al. 2019. TCR's accuracy is much higher than R-CLIPER's at the cost of
additional computational and data requirements.
When using the TCR model make sure that your TC track data includes the along-track
variables "t600" (temperature at 600 hPa) and "u850"/"v850" (wind speed at 850 hPa). Both
can be extracted from reanalysis or climate model outputs. For "t600", use the value at the
storm center. For "u850"/"v850", use the average over the 200-500 km annulus around the
storm center. If "u850"/"v850" is missing, this implementation sets the shear component of
the vertical velocity to 0. If "t600" is missing, the saturation specific humidity is set
to a universal estimate of 0.01 kg/kg. Both assumptions can have a large effect on the
results (see Lu et al. 2018).
Emanuel (2017): Assessing the present and future probability of Hurricane Harvey’s
rainfall. Proceedings of the National Academy of Sciences 114(48): 12681–12684.
https://doi.org/10.1073/pnas.1716222114
Lu et al. (2018): Assessing Hurricane Rainfall Mechanisms Using a Physics-Based Model:
Hurricanes Isabel (2003) and Irene (2011). Journal of the Atmospheric
Sciences 75(7): 2337–2358. https://doi.org/10.1175/JAS-D-17-0264.1
Feldmann et al. (2019): Estimation of Atlantic Tropical Cyclone Rainfall Frequency in the
United States. Journal of Applied Meteorology and Climatology 58(8): 1853–1866.
https://doi.org/10.1175/JAMC-D-19-0011.1
Tuleya et al. (2007): Evaluation of GFDL and Simple Statistical Model Rainfall Forecasts
for U.S. Landfalling Tropical Storms. Weather and Forecasting 22(1): 56–70.
https://doi.org/10.1175/WAF972.1
Zhu et al. (2013): Estimating tropical cyclone precipitation risk in Texas. Geophysical
Research Letters 40(23): 6225–6230. https://doi.org/10.1002/2013GL058284
Parameters
----------
tracks : climada.hazard.TCTracks
Tracks of storm events.
centroids : Centroids, optional
Centroids where to model TC. Default: centroids at 360 arc-seconds resolution within
tracks' bounds.
pool : pathos.pool, optional
Pool that will be used for parallel computation of rain fields. Default: None
model : str, optional
Parametric rain model to use: "R-CLIPER" (faster and requires less inputs, but
much less accurate, statistical approach, Tuleya et al. 2007), "TCR" (physics-based
approach, requires non-standard along-track variables, Zhu et al. 2013).
Default: "R-CLIPER".
model_kwargs: dict, optional
If given, forward these kwargs to the selected model. The implementation of the
R-CLIPER model currently does not allow modifications, so that ``model_kwargs`` is
ignored with ``model="R-CLIPER"``. While the TCR model can be configured in several ways,
it is usually safe to go with the default settings. Here is the complete list of
``model_kwargs`` and their meaning with ``model="TCR"`` (in alphabetical order):
c_drag_tif : Path or str, optional
Path to a GeoTIFF file containing gridded drag coefficients (bottom friction). If
not specified, an ERA5-based data set provided with CLIMADA is used. Default: None
e_precip : float, optional
Precipitation efficiency (unitless), the fraction of the vapor flux falling to the
surface as rainfall (Lu et al. 2018, eq. (14)). Note that we follow the MATLAB
reference implementation and use 0.5 as a default value instead of the 0.9 that was
proposed in Lu et al. 2018. Default: 0.5
elevation_tif : Path or str, optional
Path to a GeoTIFF file containing digital elevation model data (in m). If not
specified, an SRTM-based topography at 0.1 degree resolution provided with CLIMADA
is used. Default: None
matlab_ref_mode : bool, optional
This implementation is based on a (proprietary) reference implementation in MATLAB.
However, some (minor) changes have been applied in the CLIMADA implementation
compared to the reference:
* In the computation of horizontal wind speeds, we compute the Coriolis parameter
from latitude. The MATLAB code assumes a constant parameter value (5e-5).
* As a rescaling factor from surface to gradient winds, we use a factor from the
literature. The factor in MATLAB is very similar, but does not specify a
source.
* Instead of the "specific humidity", the (somewhat simpler) formula for the
"mixing ratio" is used in the MATLAB code. These quantities are almost the same
in practice.
* We use the approximation of the Clausius-Clapeyron equation used by the ECMWF
(Buck 1981) instead of the one used in the MATLAB code (Bolton 1980).
Since it might be useful to have a version that replicates the behavior of the
reference implementation, this parameter can be set to True to enforce the exact
behavior of the reference implementation. Default: False
max_w_foreground : float, optional
The maximum value (in m/s) at which to clip the vertical velocity w before
subtracting the background subsidence velocity w_rad. Default: 7.0
min_c_drag : float, optional
The drag coefficient is clipped to this minimum value (esp. over ocean).
Default: 0.001
q_950 : float, optional
If the track data does not include "t600" values, assume this constant value of
saturation specific humidity (in kg/kg) at 950 hPa. Default: 0.01
res_radial_m : float, optional
Resolution (in m) in radial direction. This is used for the computation of discrete
derivatives of the horizontal wind fields and derived quantities. Default: 2000.0
w_rad : float, optional
Background subsidence velocity (in m/s) under radiative cooling. Default: 0.005
wind_model : str, optional
Parametric wind field model to use, see the ``TropCyclone`` class. Default: "ER11".
Default: None
ignore_distance_to_coast : boolean, optional
If True, centroids far from coast are not ignored. Default: False.
store_rainrates : boolean, optional
If True, the Hazard object gets a list ``rainrates`` of sparse matrices. For each track,
the rain rates (in mm/h) at each centroid and track position are stored in a sparse
matrix of shape (npositions, ncentroids). Default: False.
metric : str, optional
Specify an approximation method to use for earth distances:
* "equirect": Distance according to sinusoidal projection. Fast, but inaccurate for
large distances and high latitudes.
* "geosphere": Exact spherical distance. Much more accurate at all distances, but slow.
Default: "equirect".
intensity_thres : float, optional
Rain amounts (in mm) below this threshold are stored as 0. Default: 0.1
max_latitude : float, optional
No rain calculation is done for centroids with latitude larger than this parameter.
Default: 61
max_dist_inland_km : float, optional
No rain calculation is done for centroids with a distance (in km) to the coast larger
than this parameter. Default: 1000
max_dist_eye_km : float, optional
No rain calculation is done for centroids with a distance (in km) to the
TC center ("eye") larger than this parameter. Default: 300
max_memory_gb : float, optional
To avoid memory issues, the computation is done for chunks of the track sequentially.
The chunk size is determined depending on the available memory (in GB). Note that this
limit applies to each thread separately if a ``pool`` is used. Default: 8
Returns
-------
TCRain
"""
num_tracks = tracks.size
if centroids is None:
centroids = Centroids.from_pnt_bounds(tracks.get_bounds(), res=0.1)
if ignore_distance_to_coast:
# Select centroids with lat <= max_latitude
[idx_centr_filter] = (np.abs(centroids.lat) <= max_latitude).nonzero()
else:
# Select centroids which are inside max_dist_inland_km and lat <= max_latitude
[idx_centr_filter] = (
> (centroids.get_dist_coast() <= max_dist_inland_km * 1000)
& (np.abs(centroids.lat) <= max_latitude)
).nonzero()
E AttributeError: 'Centroids' object has no attribute 'get_dist_coast'
../../../../petals_install_env/workspace/climada_petals/hazard/tc_rainfield.py:410: AttributeError
more test results are not shown here, view them on Jenkins
Loading